UNPKG

@tdb/util

Version:
110 lines (95 loc) 2.3 kB
import { Subject } from 'rxjs'; import { share } from 'rxjs/operators'; import { IS_BROWSER } from '../../constants'; import { IHttpHeaders, IHttpResponse, HttpMethod, IHttpEvent } from './types'; import { time } from '../time'; import { id as idUtil } from '../id'; export * from './types'; if (IS_BROWSER) { require('whatwg-fetch'); } const _events$ = new Subject<IHttpEvent>(); export const events$ = _events$.pipe(share()); const DEFAULT_HEADERS = { Accept: 'application/json', 'Content-Type': 'application/json', }; export async function request<T>( method: HttpMethod, url: string, data?: any, headers?: IHttpHeaders, ): Promise<IHttpResponse<T>> { // Setup initial conditions. const timer = time.timer(); const payload = { method, headers: new Headers({ ...DEFAULT_HEADERS, ...(headers || {}) }), }; if (data) { (payload as any).body = JSON.stringify(data); } // Fire pre-event. const event: IHttpEvent = { id: idUtil.shortid(), stage: 'START', method, url, data, headers: payload.headers, }; _events$.next(event); // Make the request. let ok = true; let status = 200; let statusText = 'OK'; let json: any; let res: Response | undefined; try { res = await fetch(url, payload); ok = res.ok; status = res.status; statusText = res.statusText; } catch (err) { ok = false; status = 521; statusText = 'CONNECTION_REFUSED'; } // Parse the response JSON. try { json = res ? await res.json() : undefined; } catch (error) { // Ignore. } // Prepare the response. const response: IHttpResponse<T> = { ok, status, statusText, elapsed: timer.elapsed(), data: json as T, }; // Finish up. _events$.next({ ...event, stage: 'COMPLETE', response, }); return response; } /** * Curry's a set of HTTP methods with the given HTTP headers. */ export function headers(headers: IHttpHeaders) { return { get: <T>(url: string) => { return request<T>('GET', url, undefined, headers); }, post: <T>(url: string, data: any) => { return request<T>('POST', url, data, headers); }, }; } const DEFAULT_METHODS = headers({}); export const get = DEFAULT_METHODS.get; export const post = DEFAULT_METHODS.post;