2020-11-12 10:07:09 +01:00
|
|
|
/**
|
|
|
|
* API cache for cached request responses.
|
|
|
|
*/
|
2021-01-25 13:10:13 +01:00
|
|
|
import { notificationStore } from "../store/notification"
|
2020-11-12 10:07:09 +01:00
|
|
|
let cache = {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for API errors.
|
|
|
|
*/
|
2020-11-11 13:25:50 +01:00
|
|
|
const handleError = error => {
|
|
|
|
return { error }
|
|
|
|
}
|
|
|
|
|
2020-11-12 10:07:09 +01:00
|
|
|
/**
|
|
|
|
* Performs an API call to the server.
|
|
|
|
* App ID header is always correctly set.
|
|
|
|
*/
|
2020-11-12 13:24:45 +01:00
|
|
|
const makeApiCall = async ({ method, url, body, json = true }) => {
|
2020-11-11 13:25:50 +01:00
|
|
|
try {
|
2020-11-12 13:24:45 +01:00
|
|
|
const requestBody = json ? JSON.stringify(body) : body
|
2021-02-01 10:11:48 +01:00
|
|
|
const inBuilder = window["##BUDIBASE_IN_BUILDER##"]
|
|
|
|
const headers = {
|
2020-11-19 21:04:30 +01:00
|
|
|
Accept: "application/json",
|
2021-01-07 15:53:56 +01:00
|
|
|
"x-budibase-app-id": window["##BUDIBASE_APP_ID##"],
|
2021-02-01 10:11:48 +01:00
|
|
|
...(json && { "Content-Type": "application/json" }),
|
|
|
|
...(!inBuilder && { "x-budibase-type": "client" }),
|
2020-11-19 21:04:30 +01:00
|
|
|
}
|
2020-11-12 10:07:09 +01:00
|
|
|
const response = await fetch(url, {
|
|
|
|
method,
|
2020-11-19 21:04:30 +01:00
|
|
|
headers,
|
2020-11-12 13:24:45 +01:00
|
|
|
body: requestBody,
|
2020-11-11 13:25:50 +01:00
|
|
|
credentials: "same-origin",
|
|
|
|
})
|
|
|
|
switch (response.status) {
|
|
|
|
case 200:
|
|
|
|
return response.json()
|
|
|
|
case 404:
|
2021-01-25 13:10:13 +01:00
|
|
|
notificationStore.danger("Not found")
|
2020-11-11 13:25:50 +01:00
|
|
|
return handleError(`${url}: Not Found`)
|
|
|
|
case 400:
|
|
|
|
return handleError(`${url}: Bad Request`)
|
|
|
|
case 403:
|
2021-01-25 13:10:13 +01:00
|
|
|
notificationStore.danger("Forbidden")
|
2020-11-11 13:25:50 +01:00
|
|
|
return handleError(`${url}: Forbidden`)
|
|
|
|
default:
|
|
|
|
if (response.status >= 200 && response.status < 400) {
|
|
|
|
return response.json()
|
|
|
|
}
|
|
|
|
return handleError(`${url} - ${response.statusText}`)
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
return handleError(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-12 10:07:09 +01:00
|
|
|
/**
|
|
|
|
* Performs an API call to the server and caches the response.
|
|
|
|
* Future invocation for this URL will return the cached result instead of
|
|
|
|
* hitting the server again.
|
|
|
|
*/
|
|
|
|
const makeCachedApiCall = async params => {
|
|
|
|
const identifier = params.url
|
|
|
|
if (!identifier) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
if (!cache[identifier]) {
|
|
|
|
cache[identifier] = makeApiCall(params)
|
|
|
|
cache[identifier] = await cache[identifier]
|
|
|
|
}
|
|
|
|
return await cache[identifier]
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs an API call function for a particular HTTP method.
|
|
|
|
*/
|
2020-11-12 13:24:45 +01:00
|
|
|
const requestApiCall = method => async params => {
|
|
|
|
const { url, cache = false } = params
|
2021-01-11 11:01:02 +01:00
|
|
|
const fixedUrl = `/${url}`.replace("//", "/")
|
2021-01-26 10:40:04 +01:00
|
|
|
const enrichedParams = { ...params, method, url: fixedUrl }
|
2020-11-12 13:24:45 +01:00
|
|
|
return await (cache ? makeCachedApiCall : makeApiCall)(enrichedParams)
|
2020-11-12 10:07:09 +01:00
|
|
|
}
|
|
|
|
|
2020-11-11 13:25:50 +01:00
|
|
|
export default {
|
2020-11-12 10:07:09 +01:00
|
|
|
post: requestApiCall("POST"),
|
|
|
|
get: requestApiCall("GET"),
|
|
|
|
patch: requestApiCall("PATCH"),
|
|
|
|
del: requestApiCall("DELETE"),
|
2020-11-11 13:25:50 +01:00
|
|
|
error: handleError,
|
|
|
|
}
|