1 |
|
2 | 'use strict';
|
3 |
|
4 | export type HttpRequestOptions = {
|
5 | body?: ?(Array<any> | Object | string);
|
6 | url: string;
|
7 | method: 'POST' | 'GET';
|
8 | };
|
9 |
|
10 |
|
11 |
|
12 | let _fetch: (input: string | Request, init?: RequestOptions) => Promise<Response> =
|
13 | typeof window === `undefined`
|
14 | ? () => Promise.reject()
|
15 | : window.fetch;
|
16 |
|
17 | export function setFetch(fetch: any) {
|
18 | _fetch = fetch;
|
19 | }
|
20 |
|
21 | function 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 |
|
32 | function wrapBody(body: any): ?string {
|
33 | if (typeof body === `string`) {
|
34 | return body;
|
35 | } else {
|
36 | return JSON.stringify(body);
|
37 | }
|
38 | }
|
39 |
|
40 | function parseResult(text: string): mixed {
|
41 | try {
|
42 | return JSON.parse(text);
|
43 | } catch (e) {
|
44 | return text;
|
45 | }
|
46 | }
|
47 |
|
48 | export 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 | }
|