UNPKG

apis.do

Version:

Unified API Gateway for all domains and services in the .do ecosystem

112 lines (88 loc) 3.19 kB
import { ErrorResponse, ListResponse, QueryParams } from './types' export interface ClientOptions { baseUrl?: string apiKey?: string headers?: Record<string, string> } export class ApiClient { private baseUrl: string private headers: Record<string, string> constructor(options: ClientOptions = {}) { this.baseUrl = options.baseUrl || 'https://apis.do' this.headers = { 'Content-Type': 'application/json', ...options.headers, } if (options.apiKey) { this.headers['Authorization'] = `Bearer ${options.apiKey}` } } private async request<T>(method: string, path: string, data?: any, params?: QueryParams): Promise<T> { const url = new URL(path, this.baseUrl) // Add query parameters if (params) { Object.entries(params).forEach(([key, value]) => { if (value !== undefined) { if (key === 'where' && typeof value === 'object') { url.searchParams.append(key, JSON.stringify(value)) } else { // Let URLSearchParams handle the encoding naturally url.searchParams.append(key, String(value)) } } }) } const options: RequestInit = { method, headers: this.headers, } if (data) { options.body = JSON.stringify(data) } const response = await fetch(url.toString(), options) const responseData = await response.json() if (!response.ok) { throw new Error((responseData as ErrorResponse).errors?.[0]?.message || `API request failed with status ${response.status}`) } return responseData as T } async get<T>(path: string, params?: QueryParams): Promise<T> { return this.request<T>('GET', path, undefined, params) } async post<T>(path: string, data: any): Promise<T> { return this.request<T>('POST', path, data) } async put<T>(path: string, data: any): Promise<T> { return this.request<T>('PUT', path, data) } async patch<T>(path: string, data: any): Promise<T> { return this.request<T>('PATCH', path, data) } async delete<T>(path: string): Promise<T> { return this.request<T>('DELETE', path) } async list<T>(collection: string, params?: QueryParams): Promise<ListResponse<T>> { return this.get<ListResponse<T>>(`/api/${collection}`, params) } async getById<T>(collection: string, id: string): Promise<T> { return this.get<T>(`/api/${collection}/${id}`) } async create<T>(collection: string, data: Partial<T>): Promise<T> { return this.post<T>(`/api/${collection}`, data) } async update<T>(collection: string, id: string, data: Partial<T>): Promise<T> { return this.patch<T>(`/api/${collection}/${id}`, data) } async replace<T>(collection: string, id: string, data: T): Promise<T> { return this.put<T>(`/api/${collection}/${id}`, data) } async remove<T>(collection: string, id: string): Promise<T> { return this.delete<T>(`/api/${collection}/${id}`) } async search<T>(collection: string, query: string, params?: QueryParams): Promise<ListResponse<T>> { return this.get<ListResponse<T>>(`/api/${collection}/search`, { ...params, q: query, }) } }