2020-11-18 07:39:44 -05:00
|
|
|
// fetch wrapper to make simple JSON requests:
|
|
|
|
// - send the CSRF token in the request
|
|
|
|
// - set the JSON content-type in the request headers
|
|
|
|
// - throw errors on non-ok response
|
|
|
|
// - parse JSON response body, unless response is empty
|
2021-01-05 05:57:18 -05:00
|
|
|
const OError = require('@overleaf/o-error')
|
2020-11-18 07:39:44 -05:00
|
|
|
|
|
|
|
export function getJSON(path, options) {
|
|
|
|
return fetchJSON(path, { ...options, method: 'GET' })
|
|
|
|
}
|
|
|
|
|
|
|
|
export function postJSON(path, options) {
|
|
|
|
return fetchJSON(path, { ...options, method: 'POST' })
|
|
|
|
}
|
|
|
|
|
|
|
|
export function deleteJSON(path, options) {
|
|
|
|
return fetchJSON(path, { ...options, method: 'DELETE' })
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function fetchJSON(
|
|
|
|
path,
|
|
|
|
{ body = {}, headers = {}, method = 'GET', ...otherOptions }
|
|
|
|
) {
|
|
|
|
const options = {
|
|
|
|
...otherOptions,
|
|
|
|
headers: {
|
|
|
|
...headers,
|
|
|
|
'Content-Type': 'application/json',
|
2021-01-05 05:57:18 -05:00
|
|
|
'X-Csrf-Token': window.csrfToken,
|
|
|
|
Accept: 'application/json'
|
2020-11-18 07:39:44 -05:00
|
|
|
},
|
|
|
|
method
|
|
|
|
}
|
|
|
|
|
|
|
|
if (method !== 'GET' && method !== 'HEAD') {
|
|
|
|
options.body = JSON.stringify(body)
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetch(path, options)
|
2021-01-05 05:57:18 -05:00
|
|
|
.then(parseResponseBody)
|
|
|
|
.then(({ responseBody, response }) => {
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new OError(response.statusText, {
|
|
|
|
statusCode: response.status,
|
|
|
|
responseBody,
|
|
|
|
response
|
|
|
|
})
|
|
|
|
}
|
2020-11-18 07:39:44 -05:00
|
|
|
|
2021-01-05 05:57:18 -05:00
|
|
|
return responseBody
|
2020-11-18 07:39:44 -05:00
|
|
|
})
|
2021-01-05 05:57:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function parseResponseBody(response) {
|
|
|
|
const contentType = response.headers.get('Content-Type')
|
|
|
|
if (/application\/json/.test(contentType)) {
|
|
|
|
return response.json().then(json => {
|
|
|
|
return { responseBody: json, response }
|
2020-11-18 07:39:44 -05:00
|
|
|
})
|
2021-01-05 05:57:18 -05:00
|
|
|
} else if (
|
|
|
|
/text\/plain/.test(contentType) ||
|
|
|
|
/text\/html/.test(contentType)
|
|
|
|
) {
|
|
|
|
return response.text().then(text => {
|
|
|
|
return { responseBody: { message: text }, response }
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
// response body ignored as content-type is either not set (e.g. 204
|
|
|
|
// responses) or unsupported
|
|
|
|
return Promise.resolve({ responseBody: {}, response })
|
|
|
|
}
|
2020-11-18 07:39:44 -05:00
|
|
|
}
|