-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcreateFetch.js
76 lines (68 loc) · 2.1 KB
/
createFetch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* React Starter Kit (https://www.reactstarterkit.com/)
*
* Copyright © 2014-present Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/
/* @flow */
import type { graphql as graphqType, GraphQLSchema } from 'graphql';
type Fetch = (url: string, options: ?any) => Promise<any>;
type Options = {
baseUrl: string,
cookie?: string,
schema?: GraphQLSchema,
graphql?: graphqType,
};
/**
* Creates a wrapper function around the HTML5 Fetch API that provides
* default arguments to fetch(...) and is intended to reduce the amount
* of boilerplate code in the application.
* https://developer.mozilla.org/docs/Web/API/Fetch_API/Using_Fetch
*/
function createFetch(
fetch: Fetch,
{ baseUrl, cookie, schema, graphql }: Options,
) {
// NOTE: Tweak the default options to suite your application needs
const defaults = {
method: 'POST', // handy with GraphQL backends
mode: baseUrl ? 'cors' : 'same-origin',
credentials: baseUrl ? 'include' : 'same-origin',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(cookie ? { Cookie: cookie } : null),
},
};
return async (url: string, options: any) => {
const isGraphQL = url.startsWith('/graphql');
if (schema && graphql && isGraphQL) {
// We're SSR, so route the graphql internal to avoid latency
const query = JSON.parse(options.body);
const result = await graphql(
schema,
query.query,
{ request: {} }, // fill in request vars needed by graphql
null,
query.variables,
);
return Promise.resolve({
status: result.errors ? 400 : 200,
json: () => Promise.resolve(result),
});
}
return isGraphQL || url.startsWith('/api')
? fetch(`${baseUrl}${url}`, {
...defaults,
...options,
headers: {
...defaults.headers,
...(options && options.headers),
},
})
: fetch(url, options);
};
}
export default createFetch;