2020-11-12 10:07:09 +01:00
|
|
|
/**
|
|
|
|
* API cache for cached request responses.
|
|
|
|
*/
|
|
|
|
let cache = {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes a fully formatted URL based on the SDK configuration.
|
|
|
|
*/
|
|
|
|
const makeFullURL = path => {
|
2021-01-05 19:47:51 +01:00
|
|
|
const isProxy = window.location.pathname.startsWith("/app/")
|
|
|
|
return `${isProxy ? "/app/" : "/"}${path}`.replace("//", "/")
|
2020-11-11 13:25:50 +01:00
|
|
|
}
|
|
|
|
|
2020-11-12 10:07:09 +01:00
|
|
|
/**
|
|
|
|
* 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
|
2020-11-19 21:04:30 +01:00
|
|
|
let headers = {
|
|
|
|
Accept: "application/json",
|
|
|
|
"Content-Type": "application/json",
|
2021-01-07 15:53:56 +01:00
|
|
|
"x-budibase-app-id": window["##BUDIBASE_APP_ID##"],
|
2020-11-19 21:04:30 +01:00
|
|
|
}
|
|
|
|
if (!window["##BUDIBASE_IN_BUILDER##"]) {
|
|
|
|
headers["x-budibase-type"] = "client"
|
|
|
|
}
|
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:
|
|
|
|
return handleError(`${url}: Not Found`)
|
|
|
|
case 400:
|
|
|
|
return handleError(`${url}: Bad Request`)
|
|
|
|
case 403:
|
|
|
|
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
|
2020-11-12 10:07:09 +01:00
|
|
|
const fullURL = makeFullURL(url)
|
2020-11-12 13:24:45 +01:00
|
|
|
const enrichedParams = { ...params, method, url: fullURL }
|
|
|
|
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,
|
|
|
|
}
|