chore: restructure public files
This commit is contained in:
144
public/scripts/api-client.js
Normal file
144
public/scripts/api-client.js
Normal file
@@ -0,0 +1,144 @@
|
||||
// API Client for communicating with the backend
|
||||
|
||||
class ApiClient {
|
||||
constructor() {
|
||||
// Auto-detect server URL based on current location
|
||||
const currentHost = window.location.hostname;
|
||||
const currentPort = window.location.port;
|
||||
|
||||
// If accessing from localhost, use localhost:3001
|
||||
// If accessing from another device, use the same hostname but port 3001
|
||||
if (currentHost === 'localhost' || currentHost === '127.0.0.1') {
|
||||
this.baseUrl = 'http://localhost:3001';
|
||||
} else {
|
||||
// Use the same hostname but port 3001
|
||||
this.baseUrl = `http://${currentHost}:3001`;
|
||||
}
|
||||
|
||||
console.log('API Client initialized with base URL:', this.baseUrl);
|
||||
}
|
||||
|
||||
async request(path, { method = 'GET', headers = {}, body = undefined, query = undefined, isForm = false } = {}) {
|
||||
const url = new URL(`${this.baseUrl}${path}`);
|
||||
if (query && typeof query === 'object') {
|
||||
Object.entries(query).forEach(([k, v]) => {
|
||||
if (v !== undefined && v !== null) url.searchParams.set(k, String(v));
|
||||
});
|
||||
}
|
||||
const finalHeaders = { 'Accept': 'application/json', ...headers };
|
||||
const options = { method, headers: finalHeaders };
|
||||
if (body !== undefined) {
|
||||
if (isForm) {
|
||||
options.body = body;
|
||||
} else {
|
||||
options.headers['Content-Type'] = options.headers['Content-Type'] || 'application/json';
|
||||
options.body = typeof body === 'string' ? body : JSON.stringify(body);
|
||||
}
|
||||
}
|
||||
const response = await fetch(url.toString(), options);
|
||||
let data;
|
||||
const text = await response.text();
|
||||
try {
|
||||
data = text ? JSON.parse(text) : null;
|
||||
} catch (_) {
|
||||
data = text; // Non-JSON payload
|
||||
}
|
||||
if (!response.ok) {
|
||||
const message = (data && data.message) || `HTTP ${response.status}: ${response.statusText}`;
|
||||
throw new Error(message);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async getClusterMembers() {
|
||||
try {
|
||||
return await this.request('/api/cluster/members', { method: 'GET' });
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getClusterMembersFromNode(ip) {
|
||||
try {
|
||||
return await this.request(`/api/cluster/members`, {
|
||||
method: 'GET',
|
||||
query: { ip: ip }
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getDiscoveryInfo() {
|
||||
try {
|
||||
return await this.request('/api/discovery/nodes', { method: 'GET' });
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async selectRandomPrimaryNode() {
|
||||
try {
|
||||
return await this.request('/api/discovery/random-primary', {
|
||||
method: 'POST',
|
||||
body: { timestamp: new Date().toISOString() }
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getNodeStatus(ip) {
|
||||
try {
|
||||
return await this.request(`/api/node/status/${encodeURIComponent(ip)}`, { method: 'GET' });
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getTasksStatus(ip) {
|
||||
try {
|
||||
return await this.request('/api/tasks/status', { method: 'GET', query: ip ? { ip } : undefined });
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getCapabilities(ip) {
|
||||
try {
|
||||
return await this.request('/api/capabilities', { method: 'GET', query: ip ? { ip } : undefined });
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async callCapability({ ip, method, uri, params }) {
|
||||
try {
|
||||
return await this.request('/api/proxy-call', {
|
||||
method: 'POST',
|
||||
body: { ip, method, uri, params }
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async uploadFirmware(file, nodeIp) {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return await this.request(`/api/node/update`, {
|
||||
method: 'POST',
|
||||
query: { ip: nodeIp },
|
||||
body: formData,
|
||||
isForm: true,
|
||||
headers: {},
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Upload failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global API client instance
|
||||
window.apiClient = new ApiClient();
|
||||
Reference in New Issue
Block a user