2017-09-19 13:32:04 -07:00
|
|
|
import fetch from 'fetch';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Describes the attributes on the fetch configuration object
|
|
|
|
*/
|
|
|
|
interface FetchConfig {
|
|
|
|
url: string;
|
2017-10-18 17:38:51 -07:00
|
|
|
headers?: { [key: string]: string } | Headers;
|
|
|
|
data?: object;
|
2017-09-19 13:32:04 -07:00
|
|
|
}
|
|
|
|
|
2017-10-18 17:38:51 -07:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {FetchConfig} config
|
|
|
|
*/
|
|
|
|
const baseFetchHeaders = (headers: FetchConfig['headers']) => ({
|
|
|
|
headers: {
|
|
|
|
Accept: 'application/json',
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
...headers
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @template T
|
|
|
|
* @param {string} url
|
|
|
|
* @param {object} fetchConfig
|
|
|
|
* @returns {Promise<T>}
|
|
|
|
*/
|
|
|
|
const json = <T>(url: string, fetchConfig: object): Promise<T> =>
|
|
|
|
fetch(url, fetchConfig).then<T>(response => response.json());
|
|
|
|
|
2017-09-19 13:32:04 -07:00
|
|
|
/**
|
|
|
|
* Conveniently gets a JSON response using the fetch api
|
|
|
|
* @param {FetchConfig} config
|
|
|
|
* @return {Promise<T>}
|
|
|
|
*/
|
|
|
|
const getJSON = <T>(config: FetchConfig): Promise<T> => {
|
2017-10-18 17:38:51 -07:00
|
|
|
const fetchConfig = { ...baseFetchHeaders(config.headers), method: 'GET' };
|
|
|
|
|
|
|
|
return json<T>(config.url, fetchConfig);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @template T
|
|
|
|
* @param {FetchConfig} config
|
|
|
|
* @returns {Promise<T>}
|
|
|
|
*/
|
|
|
|
const postJSON = <T>(config: FetchConfig): Promise<T> => {
|
|
|
|
const fetchConfig = Object.assign(
|
|
|
|
config.data && { body: JSON.stringify(config.data) },
|
|
|
|
baseFetchHeaders(config.headers),
|
|
|
|
{ method: 'POST' }
|
|
|
|
);
|
|
|
|
|
|
|
|
return json<T>(config.url, fetchConfig);
|
|
|
|
};
|
|
|
|
|
|
|
|
const deleteJSON = <T>(config: FetchConfig): Promise<T> => {
|
|
|
|
const fetchConfig = Object.assign(
|
|
|
|
config.data && { body: JSON.stringify(config.data) },
|
|
|
|
baseFetchHeaders(config.headers),
|
|
|
|
{ method: 'DELETE' }
|
|
|
|
);
|
|
|
|
|
|
|
|
return json<T>(config.url, fetchConfig);
|
|
|
|
};
|
|
|
|
|
|
|
|
const putJSON = <T>(config: FetchConfig): Promise<T> => {
|
|
|
|
const fetchConfig = Object.assign(
|
|
|
|
config.data && { body: JSON.stringify(config.data) },
|
|
|
|
baseFetchHeaders(config.headers),
|
|
|
|
{ method: 'PUT' }
|
|
|
|
);
|
2017-09-19 13:32:04 -07:00
|
|
|
|
2017-10-18 17:38:51 -07:00
|
|
|
return json<T>(config.url, fetchConfig);
|
2017-09-19 13:32:04 -07:00
|
|
|
};
|
|
|
|
|
2017-09-20 14:25:27 -07:00
|
|
|
/**
|
|
|
|
* Requests the headers from a resource endpoint
|
|
|
|
* @param {FetchConfig} config
|
2017-09-20 16:10:52 -07:00
|
|
|
* @return {Promise<Headers>>}
|
2017-09-20 14:25:27 -07:00
|
|
|
*/
|
2017-09-20 16:10:52 -07:00
|
|
|
const getHeaders = async (config: FetchConfig): Promise<Headers> => {
|
2017-09-20 14:25:27 -07:00
|
|
|
const fetchConfig = {
|
2017-10-18 17:38:51 -07:00
|
|
|
...baseFetchHeaders(config.headers),
|
|
|
|
method: 'HEAD'
|
2017-09-20 14:25:27 -07:00
|
|
|
};
|
|
|
|
const { ok, headers, statusText } = await fetch(config.url, fetchConfig);
|
|
|
|
|
|
|
|
if (ok) {
|
2017-09-20 16:10:52 -07:00
|
|
|
return headers;
|
2017-09-20 14:25:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error(statusText);
|
|
|
|
};
|
|
|
|
|
2017-10-18 17:38:51 -07:00
|
|
|
export { getJSON, postJSON, deleteJSON, putJSON, getHeaders };
|