Files
spore-ui/src/client/index.js
2025-08-28 11:17:37 +02:00

249 lines
6.7 KiB
JavaScript

/**
* SPORE API Client
* Generated from api/openapi.yaml
*/
class SporeApiClient {
constructor(baseUrl) {
if (!baseUrl) {
throw new Error('baseUrl is required for SporeApiClient');
}
this.baseUrl = baseUrl;
this.defaultHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
}
/**
* Make an HTTP request
* @param {string} method - HTTP method
* @param {string} path - API path
* @param {Object} options - Request options
* @returns {Promise<Object>} Response data
*/
async request(method, path, options = {}) {
const url = `${this.baseUrl}${path}`;
const config = {
method,
headers: { ...this.defaultHeaders, ...options.headers },
...options
};
try {
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Handle empty responses
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
} catch (error) {
throw new Error(`Request failed: ${error.message}`);
}
}
/**
* Get comprehensive task status
* @returns {Promise<Object>} Task status response
*/
async getTaskStatus() {
return this.request('GET', '/api/tasks/status');
}
/**
* Control individual task operations
* @param {string} task - Name of the task to control
* @param {string} action - Action to perform (enable, disable, start, stop, status)
* @returns {Promise<Object>} Task control response
*/
async controlTask(task, action) {
const formData = new URLSearchParams();
formData.append('task', task);
formData.append('action', action);
return this.request('POST', '/api/tasks/control', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData.toString()
});
}
/**
* Get system status and API information
* @returns {Promise<Object>} System status response
*/
async getSystemStatus() {
return this.request('GET', '/api/node/status');
}
/**
* Get node capabilities
* @returns {Promise<Object>} Capabilities response
*/
async getCapabilities() {
return this.request('GET', '/api/capabilities');
}
/**
* Get cluster discovery information
* @returns {Promise<Object>} Cluster discovery response
*/
async getClusterDiscovery() {
return this.request('GET', '/api/cluster/members');
}
/**
* Get cluster status
* @returns {Promise<Object>} Cluster status response
*/
async getClusterStatus() {
return this.request('GET', '/api/cluster/members');
}
/**
* Get OTA update status
* @returns {Promise<Object>} OTA update status response
*/
async getOtaStatus() {
return this.request('GET', '/api/ota/status');
}
/**
* Get system health metrics
* @returns {Promise<Object>} Health metrics response
*/
async getHealthMetrics() {
return this.request('GET', '/api/health/metrics');
}
/**
* Get system logs
* @param {Object} options - Query options
* @returns {Promise<Object>} System logs response
*/
async getSystemLogs(options = {}) {
const queryParams = new URLSearchParams();
if (options.level) queryParams.append('level', options.level);
if (options.limit) queryParams.append('limit', options.limit);
if (options.offset) queryParams.append('offset', options.offset);
const queryString = queryParams.toString();
const path = queryString ? `/api/system/logs?${queryString}` : '/api/system/logs';
return this.request('GET', path);
}
/**
* Get network configuration
* @returns {Promise<Object>} Network configuration response
*/
async getNetworkConfig() {
return this.request('GET', '/api/network/config');
}
/**
* Update network configuration
* @param {Object} config - Network configuration
* @returns {Promise<Object>} Update response
*/
async updateNetworkConfig(config) {
return this.request('POST', '/api/network/config', {
body: JSON.stringify(config)
});
}
/**
* Get WiFi networks
* @returns {Promise<Object>} WiFi networks response
*/
async getWifiNetworks() {
return this.request('GET', '/api/network/wifi/scan');
}
/**
* Connect to WiFi network
* @param {string} ssid - Network SSID
* @param {string} password - Network password
* @returns {Promise<Object>} Connection response
*/
async connectWifi(ssid, password) {
return this.request('POST', '/api/network/wifi/connect', {
body: JSON.stringify({ ssid, password })
});
}
/**
* Get device information
* @returns {Promise<Object>} Device info response
*/
async getDeviceInfo() {
return this.request('GET', '/api/device/info');
}
/**
* Restart the device
* @returns {Promise<Object>} Restart response
*/
async restartDevice() {
return this.request('POST', '/api/device/restart');
}
/**
* Factory reset the device
* @returns {Promise<Object>} Factory reset response
*/
async factoryReset() {
return this.request('POST', '/api/device/factory-reset');
}
/**
* Update firmware on the device
* @param {Buffer|Uint8Array} firmwareData - Firmware binary data
* @param {string} filename - Name of the firmware file
* @returns {Promise<Object>} Update response
*/
async updateFirmware(firmwareData, filename) {
// Create multipart form data manually for Node.js compatibility
const boundary = '----WebKitFormBoundary' + Math.random().toString(16).substr(2, 8);
let body = '';
// Add the firmware file part
body += `--${boundary}\r\n`;
body += `Content-Disposition: form-data; name="firmware"; filename="${filename}"\r\n`;
body += 'Content-Type: application/octet-stream\r\n\r\n';
// Convert the body to Buffer and append the firmware data
const headerBuffer = Buffer.from(body, 'utf8');
const endBuffer = Buffer.from(`\r\n--${boundary}--\r\n`, 'utf8');
// Combine all parts
const finalBody = Buffer.concat([headerBuffer, firmwareData, endBuffer]);
// Send the multipart form data to the SPORE device
return this.request('POST', '/api/node/update', {
body: finalBody,
headers: {
'Content-Type': `multipart/form-data; boundary=${boundary}`
}
});
}
}
// Export the client class
module.exports = SporeApiClient;
// Also export for ES modules if available
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = SporeApiClient;
}
}