| import apiClient from './apiClient.js'; | |
| const ENDPOINTS = [ | |
| { label: 'Health', method: 'GET', path: '/api/health', description: 'Core service health check' }, | |
| { label: 'Market Stats', method: 'GET', path: '/api/market/stats', description: 'Global market metrics' }, | |
| { label: 'Top Coins', method: 'GET', path: '/api/coins/top', description: 'Top market cap coins', params: 'limit=10' }, | |
| { label: 'Latest News', method: 'GET', path: '/api/news/latest', description: 'Latest curated news', params: 'limit=20' }, | |
| { label: 'Chart History', method: 'GET', path: '/api/charts/price/BTC', description: 'Historical price data', params: 'timeframe=7d' }, | |
| { label: 'Chart AI Analysis', method: 'POST', path: '/api/charts/analyze', description: 'AI chart insights', body: '{"symbol":"BTC","timeframe":"7d"}' }, | |
| { label: 'Sentiment Analysis', method: 'POST', path: '/api/sentiment/analyze', description: 'Run sentiment models', body: '{"text":"Bitcoin rally","mode":"auto"}' }, | |
| { label: 'News Summarize', method: 'POST', path: '/api/news/summarize', description: 'Summarize a headline', body: '{"title":"Headline","body":"Full article"}' }, | |
| ]; | |
| class ApiExplorerView { | |
| constructor(section) { | |
| this.section = section; | |
| this.endpointSelect = section?.querySelector('[data-api-endpoint]'); | |
| this.methodSelect = section?.querySelector('[data-api-method]'); | |
| this.paramsInput = section?.querySelector('[data-api-params]'); | |
| this.bodyInput = section?.querySelector('[data-api-body]'); | |
| this.sendButton = section?.querySelector('[data-api-send]'); | |
| this.responseNode = section?.querySelector('[data-api-response]'); | |
| this.metaNode = section?.querySelector('[data-api-meta]'); | |
| } | |
| init() { | |
| if (!this.section) return; | |
| this.populateEndpoints(); | |
| this.bindEvents(); | |
| this.applyPreset(ENDPOINTS[0]); | |
| } | |
| populateEndpoints() { | |
| if (!this.endpointSelect) return; | |
| this.endpointSelect.innerHTML = ENDPOINTS.map((endpoint, index) => `<option value="${index}">${endpoint.label}</option>`).join(''); | |
| } | |
| bindEvents() { | |
| this.endpointSelect?.addEventListener('change', () => { | |
| const index = Number(this.endpointSelect.value); | |
| this.applyPreset(ENDPOINTS[index]); | |
| }); | |
| this.sendButton?.addEventListener('click', () => this.sendRequest()); | |
| } | |
| applyPreset(preset) { | |
| if (!preset) return; | |
| if (this.methodSelect) { | |
| this.methodSelect.value = preset.method; | |
| } | |
| if (this.paramsInput) { | |
| this.paramsInput.value = preset.params || ''; | |
| } | |
| if (this.bodyInput) { | |
| this.bodyInput.value = preset.body || ''; | |
| } | |
| this.section.querySelector('[data-api-description]').textContent = preset.description; | |
| this.section.querySelector('[data-api-path]').textContent = preset.path; | |
| } | |
| async sendRequest() { | |
| const index = Number(this.endpointSelect?.value || 0); | |
| const preset = ENDPOINTS[index]; | |
| const method = this.methodSelect?.value || preset.method; | |
| let endpoint = preset.path; | |
| const params = (this.paramsInput?.value || '').trim(); | |
| if (params) { | |
| endpoint += endpoint.includes('?') ? `&${params}` : `?${params}`; | |
| } | |
| let body = this.bodyInput?.value.trim(); | |
| if (!body) body = undefined; | |
| let parsedBody; | |
| if (body && method !== 'GET') { | |
| try { | |
| parsedBody = JSON.parse(body); | |
| } catch (error) { | |
| this.renderError('Invalid JSON body'); | |
| return; | |
| } | |
| } | |
| this.renderMeta('pending'); | |
| this.renderResponse('Fetching...'); | |
| const started = performance.now(); | |
| const result = await apiClient.request(method, endpoint, { cache: false, body: parsedBody }); | |
| const duration = Math.round(performance.now() - started); | |
| if (!result.ok) { | |
| this.renderError(result.error || 'Request failed', duration); | |
| return; | |
| } | |
| this.renderMeta('ok', duration, method, endpoint); | |
| this.renderResponse(result.data); | |
| } | |
| renderResponse(data) { | |
| if (!this.responseNode) return; | |
| if (typeof data === 'string') { | |
| this.responseNode.textContent = data; | |
| return; | |
| } | |
| this.responseNode.textContent = JSON.stringify(data, null, 2); | |
| } | |
| renderMeta(status, duration = 0, method = '', path = '') { | |
| if (!this.metaNode) return; | |
| if (status === 'pending') { | |
| this.metaNode.textContent = 'Sending request...'; | |
| return; | |
| } | |
| this.metaNode.textContent = `${method} ${path} • ${duration}ms`; | |
| } | |
| renderError(message, duration = 0) { | |
| this.renderMeta('error', duration); | |
| this.renderResponse({ error: message }); | |
| } | |
| } | |
| export default ApiExplorerView; | |