189 lines
5.1 KiB
TypeScript
189 lines
5.1 KiB
TypeScript
import type { Config, Provider, Transformer } from '@/types';
|
|
|
|
// API Client Class for handling requests with baseUrl and apikey authentication
|
|
class ApiClient {
|
|
private baseUrl: string;
|
|
private apiKey: string;
|
|
|
|
constructor(baseUrl: string = '/api', apiKey: string = '') {
|
|
this.baseUrl = baseUrl;
|
|
// Load API key from localStorage if available
|
|
this.apiKey = apiKey || localStorage.getItem('apiKey') || '';
|
|
}
|
|
|
|
// Update base URL
|
|
setBaseUrl(url: string) {
|
|
this.baseUrl = url;
|
|
}
|
|
|
|
// Update API key
|
|
setApiKey(apiKey: string) {
|
|
this.apiKey = apiKey;
|
|
// Save API key to localStorage
|
|
if (apiKey) {
|
|
localStorage.setItem('apiKey', apiKey);
|
|
} else {
|
|
localStorage.removeItem('apiKey');
|
|
}
|
|
}
|
|
|
|
// Create headers with API key authentication
|
|
private createHeaders(contentType: string = 'application/json'): HeadersInit {
|
|
const headers: Record<string, string> = {
|
|
'X-API-Key': this.apiKey,
|
|
'Accept': 'application/json',
|
|
};
|
|
|
|
if (contentType) {
|
|
headers['Content-Type'] = contentType;
|
|
}
|
|
|
|
return headers;
|
|
}
|
|
|
|
// Generic fetch wrapper with base URL and authentication
|
|
private async apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
|
const url = `${this.baseUrl}${endpoint}`;
|
|
|
|
const config: RequestInit = {
|
|
...options,
|
|
headers: {
|
|
...this.createHeaders(),
|
|
...options.headers,
|
|
},
|
|
};
|
|
|
|
try {
|
|
const response = await fetch(url, config);
|
|
|
|
// Handle 401 Unauthorized responses
|
|
if (response.status === 401) {
|
|
// Remove API key when it's invalid
|
|
localStorage.removeItem('apiKey');
|
|
// Redirect to login page if not already there
|
|
// For memory router, we need to use the router instance
|
|
// We'll dispatch a custom event that the app can listen to
|
|
window.dispatchEvent(new CustomEvent('unauthorized'));
|
|
// Return a promise that never resolves to prevent further execution
|
|
return new Promise(() => {}) as Promise<T>;
|
|
}
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
}
|
|
|
|
if (response.status === 204) {
|
|
return {} as T;
|
|
}
|
|
|
|
const text = await response.text();
|
|
return text ? JSON.parse(text) : ({} as T);
|
|
|
|
} catch (error) {
|
|
console.error('API request error:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// GET request
|
|
async get<T>(endpoint: string): Promise<T> {
|
|
return this.apiFetch<T>(endpoint, {
|
|
method: 'GET',
|
|
});
|
|
}
|
|
|
|
// POST request
|
|
async post<T>(endpoint: string, data: unknown): Promise<T> {
|
|
return this.apiFetch<T>(endpoint, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
}
|
|
|
|
// PUT request
|
|
async put<T>(endpoint: string, data: unknown): Promise<T> {
|
|
return this.apiFetch<T>(endpoint, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
});
|
|
}
|
|
|
|
// DELETE request
|
|
async delete<T>(endpoint: string): Promise<T> {
|
|
return this.apiFetch<T>(endpoint, {
|
|
method: 'DELETE',
|
|
});
|
|
}
|
|
|
|
// API methods for configuration
|
|
// Get current configuration
|
|
async getConfig(): Promise<Config> {
|
|
return this.get<Config>('/config');
|
|
}
|
|
|
|
// Update entire configuration
|
|
async updateConfig(config: Config): Promise<Config> {
|
|
return this.post<Config>('/config', config);
|
|
}
|
|
|
|
// Get providers
|
|
async getProviders(): Promise<Provider[]> {
|
|
return this.get<Provider[]>('/api/providers');
|
|
}
|
|
|
|
// Add a new provider
|
|
async addProvider(provider: Provider): Promise<Provider> {
|
|
return this.post<Provider>('/api/providers', provider);
|
|
}
|
|
|
|
// Update a provider
|
|
async updateProvider(index: number, provider: Provider): Promise<Provider> {
|
|
return this.post<Provider>(`/api/providers/${index}`, provider);
|
|
}
|
|
|
|
// Delete a provider
|
|
async deleteProvider(index: number): Promise<void> {
|
|
return this.delete<void>(`/api/providers/${index}`);
|
|
}
|
|
|
|
// Get transformers
|
|
async getTransformers(): Promise<Transformer[]> {
|
|
return this.get<Transformer[]>('/api/transformers');
|
|
}
|
|
|
|
// Add a new transformer
|
|
async addTransformer(transformer: Transformer): Promise<Transformer> {
|
|
return this.post<Transformer>('/api/transformers', transformer);
|
|
}
|
|
|
|
// Update a transformer
|
|
async updateTransformer(index: number, transformer: Transformer): Promise<Transformer> {
|
|
return this.post<Transformer>(`/api/transformers/${index}`, transformer);
|
|
}
|
|
|
|
// Delete a transformer
|
|
async deleteTransformer(index: number): Promise<void> {
|
|
return this.delete<void>(`/api/transformers/${index}`);
|
|
}
|
|
|
|
// Get configuration (new endpoint)
|
|
async getConfigNew(): Promise<Config> {
|
|
return this.get<Config>('/config');
|
|
}
|
|
|
|
// Save configuration (new endpoint)
|
|
async saveConfig(config: Config): Promise<unknown> {
|
|
return this.post<Config>('/config', config);
|
|
}
|
|
|
|
// Restart service
|
|
async restartService(): Promise<unknown> {
|
|
return this.post<void>('/restart', {});
|
|
}
|
|
}
|
|
|
|
// Create a default instance of the API client
|
|
export const api = new ApiClient();
|
|
|
|
// Export the class for creating custom instances
|
|
export default ApiClient; |