cineclub-site/front/composables/api.ts

100 lines
2.5 KiB
TypeScript

import { useLoadingStore } from "~/stores/loadingStore"
type MyHeaders = Record<string, string>
const makeLoadingKey = (path: string) => {
// camel-case the path : auth/login -> authLogin
if (path.endsWith("/")) {
path = path.slice(0, -1)
}
if (path.startsWith("/")) {
path = path.slice(1)
}
let words = path.split("/")
words = words.filter((word) => !/^\d+$/.test(word))
for (const [ix, word] of Object.entries(words.slice(1))) {
words[parseInt(ix) + 1] = word[0].toUpperCase() + word.slice(1)
}
return words.join("")
}
const getCsrfCookie = () => {
let cookie: string | undefined
if (process.server) {
cookie = useRequestHeaders(["cookie"])["cookie"]
} else {
cookie = document.cookie
}
if (!cookie) {
return null
}
const csrfRow = cookie.split("; ").find((row) => row.startsWith("csrftoken="))
if (!csrfRow) {
return null
}
return csrfRow.split("=")[1]
}
const getHeaders = (includeCsrf = false): MyHeaders => {
// @ts-expect-error TODO handle null values here
const headers: MyHeaders = useRequestHeaders(["cookie"])
if (includeCsrf) {
const csfrToken = getCsrfCookie()
if (csfrToken) {
headers["X-CSRFTOKEN"] = csfrToken
}
}
return headers
}
let host
// local
if (process.env.NODE_ENV !== "production") {
host = "http://localhost:8000"
} else {
// production server
if (process.server) {
// server-side rendering
host = "http://localhost:8064"
} else {
host = "https://cineclub.ens.fr" //use env params ?
}
}
const baseUrl = `${host}/api/`
export async function apiRequest<Type>(
method: string,
path: string,
payload: Record<never, never> | undefined,
params = {}
) {
const loadingStore = useLoadingStore()
const key = makeLoadingKey(path)
loadingStore.markLoading(key)
const response = await useAsyncData<Type>(key, () =>
$fetch<Type>(baseUrl + path, {
method: method,
body: payload,
credentials: "include",
headers: getHeaders(method != "GET"),
params: params,
})
)
if (response.error.value) loadingStore.markError(key)
else loadingStore.markDone(key)
return response
}
export async function apiGet<Type>(path: string, params = {}) {
return apiRequest<Type>("GET", path, undefined, params)
}
export async function apiPost<Type>(path: string, payload = {}, params = {}) {
return apiRequest<Type>("POST", path, payload, params)
}
export async function apiPatch<Type>(path: string, payload = {}, params = {}) {
return apiRequest<Type>("PATCH", path, payload, params)
}