A social knowledge tool for researchers built on ATProto
at main 53 lines 1.3 kB view raw
1import { ApiError, ApiErrorResponse } from '../errors'; 2 3export abstract class BaseClient { 4 constructor(protected baseUrl: string) {} 5 6 protected async request<T>( 7 method: string, 8 endpoint: string, 9 data?: any, 10 ): Promise<T> { 11 const url = `${this.baseUrl}${endpoint}`; 12 13 const headers: Record<string, string> = { 14 'Content-Type': 'application/json', 15 }; 16 17 const config: RequestInit = { 18 method, 19 headers, 20 credentials: 'include', // Include cookies automatically (works for both client and server) 21 }; 22 23 if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH')) { 24 config.body = JSON.stringify(data); 25 } 26 27 const response = await fetch(url, config); 28 return this.handleResponse<T>(response); 29 } 30 31 private async handleResponse<T>(response: Response): Promise<T> { 32 if (!response.ok) { 33 let errorData: ApiErrorResponse; 34 35 try { 36 errorData = await response.json(); 37 } catch { 38 errorData = { 39 message: response.statusText || 'Unknown error', 40 }; 41 } 42 43 throw new ApiError( 44 errorData.message, 45 response.status, 46 errorData.code, 47 errorData.details, 48 ); 49 } 50 51 return response.json(); 52 } 53}