stock-bot/apps/web-app/src/features/exchanges/services/exchangeApi.ts
2025-06-18 14:01:45 -04:00

135 lines
No EOL
3.8 KiB
TypeScript

import {
ApiResponse,
Exchange,
ExchangeDetails,
ExchangeStats,
ProviderMapping,
ProviderExchange,
CreateExchangeRequest,
UpdateExchangeRequest,
CreateProviderMappingRequest,
UpdateProviderMappingRequest,
} from '../types';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:4000/api';
class ExchangeApiService {
private async request<T>(
endpoint: string,
options?: RequestInit
): Promise<ApiResponse<T>> {
const url = `${API_BASE_URL}${endpoint}`;
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (!data.success) {
throw new Error(data.error || 'API request failed');
}
return data;
}
// Exchanges
async getExchanges(): Promise<Exchange[]> {
const response = await this.request<Exchange[]>('/exchanges');
return response.data || [];
}
async getExchangeById(id: string): Promise<ExchangeDetails | null> {
const response = await this.request<ExchangeDetails>(`/exchanges/${id}`);
return response.data || null;
}
async createExchange(data: CreateExchangeRequest): Promise<Exchange> {
const response = await this.request<Exchange>('/exchanges', {
method: 'POST',
body: JSON.stringify(data),
});
if (!response.data) {
throw new Error('No exchange data returned');
}
return response.data;
}
async updateExchange(id: string, data: UpdateExchangeRequest): Promise<Exchange> {
const response = await this.request<Exchange>(`/exchanges/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
});
if (!response.data) {
throw new Error('No exchange data returned');
}
return response.data;
}
// Provider Mappings
async getProviderMappings(provider?: string): Promise<ProviderMapping[]> {
const endpoint = provider
? `/exchanges/provider-mappings/${provider}`
: '/exchanges/provider-mappings/all';
const response = await this.request<ProviderMapping[]>(endpoint);
return response.data || [];
}
async createProviderMapping(data: CreateProviderMappingRequest): Promise<ProviderMapping> {
const response = await this.request<ProviderMapping>('/exchanges/provider-mappings', {
method: 'POST',
body: JSON.stringify(data),
});
if (!response.data) {
throw new Error('No provider mapping data returned');
}
return response.data;
}
async updateProviderMapping(
id: string,
data: UpdateProviderMappingRequest
): Promise<ProviderMapping> {
const response = await this.request<ProviderMapping>(`/exchanges/provider-mappings/${id}`, {
method: 'PATCH',
body: JSON.stringify(data),
});
if (!response.data) {
throw new Error('No provider mapping data returned');
}
return response.data;
}
// Providers and Utilities
async getProviders(): Promise<string[]> {
const response = await this.request<string[]>('/exchanges/providers/list');
return response.data || [];
}
async getUnmappedProviderExchanges(provider: string): Promise<ProviderExchange[]> {
const response = await this.request<ProviderExchange[]>(
`/exchanges/provider-exchanges/unmapped/${provider}`
);
return response.data || [];
}
async getExchangeStats(): Promise<ExchangeStats> {
const response = await this.request<ExchangeStats>('/exchanges/stats/summary');
if (!response.data) {
throw new Error('No exchange stats data returned');
}
return response.data;
}
}
// Export singleton instance
export const exchangeApi = new ExchangeApiService();