UNPKG

1.54 kBJavaScriptView Raw
1/* @flow */
2'use strict';
3
4export type HttpRequestOptions = {
5 body?: ?(Array<any> | Object | string);
6 url: string;
7 method: 'POST' | 'GET';
8};
9
10// slight hack to make Flow happy, but to allow Node to set its own fetch
11// Request, RequestOptions and Response are built-in types of Flow for fetch API
12let _fetch: (input: string | Request, init?: RequestOptions) => Promise<Response> =
13 typeof window === `undefined`
14 ? () => Promise.reject()
15 : window.fetch;
16
17export function setFetch(fetch: any) {
18 _fetch = fetch;
19}
20
21function contentType(body: any): string {
22 if (typeof body === `string`) {
23 if (body === ``) {
24 return `text/plain`;
25 }
26 return `application/octet-stream`;
27 } else {
28 return `application/json`;
29 }
30}
31
32function wrapBody(body: any): ?string {
33 if (typeof body === `string`) {
34 return body;
35 } else {
36 return JSON.stringify(body);
37 }
38}
39
40function parseResult(text: string): mixed {
41 try {
42 return JSON.parse(text);
43 } catch (e) {
44 return text;
45 }
46}
47
48export async function request(options: HttpRequestOptions): Promise<mixed> {
49 const res = await _fetch(options.url, {
50 method: options.method,
51 headers: {
52 'Content-Type': contentType(options.body || ``),
53 },
54 body: wrapBody(options.body),
55 });
56 const resText = await res.text();
57 if (res.ok) {
58 return parseResult(resText);
59 } else {
60 const resJson = parseResult(resText);
61 if (resJson.error) {
62 throw new Error(resJson.error);
63 } else {
64 throw new Error(resText);
65 }
66 }
67}