UNPKG

@starsched/sdk

Version:

ABA clinic control and management service API SDK

154 lines (153 loc) 5.23 kB
export class HttpClient { baseURL; requestInterceptors; responseInterceptors; constructor(options) { this.baseURL = options?.baseURL; this.requestInterceptors = options?.requestInterceptors ?? []; this.responseInterceptors = options?.responseInterceptors ?? []; } mountHeaders(headers) { return new Headers({ Accept: 'application/json', 'Content-Type': 'application/json', ...headers }); } async extractBodyJsonFromResponse(response) { const responseContentType = response.headers.get('Content-Type'); const isJsonResponse = responseContentType?.includes('application/json') ?? false; let body = null; if (isJsonResponse) { body = await response.json(); } return body; } async initRequest(request) { const config = { method: request.method, url: request.url, queryParams: request.queryParams, headers: this.mountHeaders(request.headers), mode: 'cors', signal: request.abortSignal }; if (!request.body) { config.headers.delete('Content-Type'); } const requestContentType = config.headers.get('Content-Type'); const isJsonBody = requestContentType?.startsWith('application/json') ?? false; if (request.body && isJsonBody) { config.body = JSON.stringify(request.body); } return this.request(config); } isHttpResponse(maybeHttpResponse) { return (typeof maybeHttpResponse === 'object' && maybeHttpResponse !== null && 'ok' in maybeHttpResponse && 'statusCode' in maybeHttpResponse); } async request(config) { let configCopy = config; const url = new URL(configCopy.url, this.baseURL); const queryParamsEntires = Object.entries(configCopy.queryParams ?? {}); for (const [name, value] of queryParamsEntires) { url.searchParams.append(name, String(value)); } try { /** Intercepta a requisição antes de ela ser executada */ for (const interceptor of this.requestInterceptors) { configCopy = await interceptor(configCopy); } const response = await fetch(url, configCopy); const responseBody = await this.extractBodyJsonFromResponse(response); let httpResponse = { ok: response.ok, statusCode: response.status, headers: response.headers, body: responseBody }; /** Intercepta a resposta antes de devolver */ for (const interceptor of this.responseInterceptors) { httpResponse = (await interceptor(configCopy, httpResponse)); } return httpResponse; } catch (error) { if (this.isHttpResponse(error)) { return error; } if (error instanceof Error) { if (error.name === 'ConnectionRefused') { // TODO: Atribuir uma mensagem diferente } if (error.name === 'Timeout') { // TODO: Implementar timeout e atribuir uma mensagem diferente } } return { ok: false, headers: {}, statusCode: 0, body: { code: 'internal', message: 'We are unable to process your request right now, please try again later.' } }; } } get(url, options) { const request = { method: 'GET', url, headers: options?.headers, queryParams: options?.queryParams, abortSignal: options?.abortSignal }; return this.initRequest(request); } post(url, body, options) { const request = { method: 'POST', url, headers: options?.headers, queryParams: options?.queryParams, body, abortSignal: options?.abortSignal }; return this.initRequest(request); } put(url, body, options) { const request = { method: 'PUT', url, headers: options?.headers, queryParams: options?.queryParams, body, abortSignal: options?.abortSignal }; return this.initRequest(request); } patch(url, body, options) { const request = { method: 'PATCH', url, headers: options?.headers, queryParams: options?.queryParams, body, abortSignal: options?.abortSignal }; return this.initRequest(request); } delete(url, options) { const request = { method: 'DELETE', url, headers: options?.headers, queryParams: options?.queryParams, abortSignal: options?.abortSignal }; return this.initRequest(request); } }