UNPKG

@surgbc/egw-writings-shared

Version:

Shared utilities, types, and database schema for EGW Writings MCP servers

173 lines (172 loc) 5.54 kB
import axios from 'axios'; export class EGWApiClient { client; authManager; baseUrl; constructor(authManager, baseUrl = 'https://a.egwwritings.org') { this.authManager = authManager; this.baseUrl = baseUrl; this.client = axios.create({ baseURL: baseUrl, timeout: 30000, headers: { 'User-Agent': 'EGW-Research-Tool/1.0.0', 'Content-Type': 'application/json' } }); // Add request interceptor to include auth token this.client.interceptors.request.use(async (config) => { try { const token = await this.authManager.getValidToken(); config.headers.Authorization = `Bearer ${token}`; } catch (error) { console.warn('No valid auth token available:', error); } return config; }); // Add response interceptor for error handling this.client.interceptors.response.use((response) => response, (error) => { if (error.response?.status === 401) { console.error('Authentication failed. Please re-authenticate.'); } return Promise.reject(error); }); } /** * Add delay between requests to be respectful */ async delay(ms = 1000) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Get available languages */ async getLanguages() { const response = await this.client.get('/content/languages'); await this.delay(); return response.data; } /** * Get folders for a language */ async getFolders(languageCode) { const response = await this.client.get(`/content/languages/${languageCode}/folders`); await this.delay(); return response.data; } /** * Get books in a folder */ async getBooksByFolder(folderId) { const response = await this.client.get(`/content/books/by_folder/${folderId}`); await this.delay(); return response.data; } /** * Get book information */ async getBook(bookId) { const response = await this.client.get(`/content/books/${bookId}`); await this.delay(); return response.data; } /** * Get book table of contents */ async getBookToc(bookId) { const response = await this.client.get(`/content/books/${bookId}/toc`); await this.delay(); return response.data; } /** * Get chapter content */ async getChapter(bookId, chapterId) { const response = await this.client.get(`/content/books/${bookId}/chapter/${chapterId}`); await this.delay(); return response.data; } /** * Get specific paragraph */ async getParagraph(bookId, paragraphId) { const response = await this.client.get(`/content/books/${bookId}/content/${paragraphId}`); await this.delay(); return response.data; } /** * Search content (using Android app parameters) */ async search(query, options) { const params = new URLSearchParams({ query: query, ...(options?.lang && { lang: options.lang.join(',') }), ...(options?.folder && { folder: options.folder.join(',') }), ...(options?.pubnr && { pubnr: options.pubnr.join(',') }), ...(options?.limit && { limit: options.limit.toString() }), ...(options?.offset && { offset: options.offset.toString() }), ...(options?.highlight && { highlight: options.highlight }), ...(options?.trans && { trans: options.trans }) }); const response = await this.client.get(`/search?${params.toString()}`); await this.delay(); return response.data; } /** * Get search suggestions (using Android app parameters) */ async getSearchSuggestions(query) { const response = await this.client.get(`/search/suggestions?query=${encodeURIComponent(query)}`); await this.delay(); return response.data; } /** * Download book as ZIP */ async downloadBook(bookId) { const response = await this.client.get(`/content/books/${bookId}/download`, { responseType: 'arraybuffer' }); await this.delay(2000); // Longer delay for downloads return Buffer.from(response.data); } /** * Get user information */ async getUserInfo() { const response = await this.client.get('/user/info/'); await this.delay(); return response.data; } /** * Test API connectivity and authentication */ async testConnection() { try { await this.getUserInfo(); return true; } catch (error) { console.error('API connection test failed:', error); return false; } } /** * Get API status and basic info */ async getApiStatus() { try { // Try a simple endpoint that might not require auth const response = await this.client.get('/content/mirrors'); return { status: 'connected', data: response.data }; } catch (error) { return { status: 'error', error: error }; } } } // Create default API client export const createApiClient = (authManager) => { return new EGWApiClient(authManager); };