// Mock API Client for communicating with the mock server // This replaces the original API client to use port 3002 class MockApiClient { constructor() { // Use port 3002 for mock server const currentHost = window.location.hostname; this.baseUrl = `http://${currentHost}:3002`; console.log('Mock 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() { return this.request('/api/cluster/members', { method: 'GET' }); } async getClusterMembersFromNode(ip) { return this.request(`/api/cluster/members`, { method: 'GET', query: { ip: ip } }); } async getDiscoveryInfo() { return this.request('/api/discovery/nodes', { method: 'GET' }); } async selectRandomPrimaryNode() { return this.request('/api/discovery/random-primary', { method: 'POST', body: { timestamp: new Date().toISOString() } }); } async getNodeStatus(ip) { return this.request('/api/node/status', { method: 'GET', query: { ip: ip } }); } async getTasksStatus(ip) { return this.request('/api/tasks/status', { method: 'GET', query: ip ? { ip } : undefined }); } async getEndpoints(ip) { return this.request('/api/node/endpoints', { method: 'GET', query: ip ? { ip } : undefined }); } async callEndpoint({ ip, method, uri, params }) { return this.request('/api/proxy-call', { method: 'POST', body: { ip, method, uri, params } }); } async uploadFirmware(file, nodeIp) { const formData = new FormData(); formData.append('file', file); const data = await this.request(`/api/node/update`, { method: 'POST', query: { ip: nodeIp }, body: formData, isForm: true, headers: {}, }); // Some endpoints may return HTTP 200 with success=false on logical failure if (data && data.success === false) { const message = data.message || 'Firmware upload failed'; throw new Error(message); } return data; } async getMonitoringResources(ip) { return this.request('/api/proxy-call', { method: 'POST', body: { ip: ip, method: 'GET', uri: '/api/monitoring/resources', params: [] } }); } } // Override the global API client window.apiClient = new MockApiClient(); // Add debugging console.log('Mock API Client loaded and initialized'); console.log('API Client base URL:', window.apiClient.baseUrl); // Test API call window.apiClient.getDiscoveryInfo().then(data => { console.log('Mock API test successful:', data); }).catch(error => { console.error('Mock API test failed:', error); });