import { VirtFusionApiError } from './errors.js'; import { QueryParams } from './types.js'; export class VirtFusionClient { private readonly baseUrl: string; private readonly token: string; constructor(baseUrl: string, token: string) { this.baseUrl = baseUrl.replace(/\/+$/, ''); this.token = token; } private buildUrl(path: string, query?: QueryParams): string { const url = new URL(`${this.baseUrl}${path}`); if (query) { for (const [key, value] of Object.entries(query)) { if (value !== undefined) { url.searchParams.set(key, String(value)); } } } return url.toString(); } private async request(method: string, path: string, body?: unknown, query?: QueryParams): Promise { const url = this.buildUrl(path, query); const headers: Record = { Authorization: `Bearer ${this.token}`, Accept: 'application/json', }; if (body !== undefined) { headers['Content-Type'] = 'application/json'; } const response = await fetch(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined, }); if (response.status === 204) { return { success: true }; } let responseBody: unknown; const text = await response.text(); try { responseBody = JSON.parse(text); } catch { responseBody = text; } if (!response.ok) { throw new VirtFusionApiError(response.status, response.statusText, responseBody); } return responseBody; } async get(path: string, query?: QueryParams): Promise { return this.request('GET', path, undefined, query); } async post(path: string, body?: unknown, query?: QueryParams): Promise { return this.request('POST', path, body, query); } async put(path: string, body?: unknown, query?: QueryParams): Promise { return this.request('PUT', path, body, query); } async delete(path: string, body?: unknown, query?: QueryParams): Promise { return this.request('DELETE', path, body, query); } }