import { apiBaseURL } from "./config" import * as sentry from "./sentry" import * as SSR from "../api/hooks/lib/ssr.js" import config from "../api/hooks/config" // [MIT License](LICENSE.md) © [Jason Miller](https://jasonformat.com/) const _f = function (url, options): Promise { if (typeof XMLHttpRequest === "undefined") { return Promise.resolve(null) } options = options || {} return new Promise((resolve, reject) => { const request = new XMLHttpRequest() const keys = [] const all = [] const headers = {} const response = (): Response => ({ ok: ((request.status / 100) | 0) == 2, // 200-299 statusText: request.statusText, status: request.status, url: request.responseURL, text: () => Promise.resolve(request.responseText), json: () => Promise.resolve(request.responseText).then(JSON.parse), blob: () => Promise.resolve(new Blob([request.response])), clone: response, headers: { // @ts-ignore keys: () => keys, // @ts-ignore entries: () => all, get: (n) => headers[n.toLowerCase()], has: (n) => n.toLowerCase() in headers, }, }) request.open(options.method || "get", url, true) request.onload = () => { request .getAllResponseHeaders() // @ts-ignore .replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, (m, key, value) => { keys.push((key = key.toLowerCase())) all.push([key, value]) headers[key] = headers[key] ? `${headers[key]},${value}` : value }) resolve(response()) } request.onerror = reject request.withCredentials = options.credentials == "include" for (const i in options.headers) { request.setRequestHeader(i, options.headers[i]) } request.send(options.body || null) }) } const _fetch = typeof fetch === "undefined" ? (typeof window === "undefined" ? _f : window.fetch || _f) : fetch export const api = async ( endpoint: string, options?: { method?: string filter?: any sort?: string limit?: number offset?: number projection?: string headers?: { [key: string]: string } params?: APIParams body?: any noToken?: boolean signal?: AbortSignal _groupBy?: string showErrors?: boolean } ): Promise<{ data: T; count: number }> => { if (typeof window === "undefined") { // ssr // @ts-ignore return context.ssrFetch(endpoint, options) } // try ssr cache const key = SSR.obj2str({ endpoint, options }) // @ts-ignore if (window.__SSR_CACHE__) { // @ts-ignore const ssrVal = window.__SSR_CACHE__[key] console.log("SSR:", key, ssrVal) if (ssrVal) { return ssrVal } } let method = "GET" if (options?.method) method = options.method.toUpperCase() let query = "&count=1" if (options?.filter) query += "&filter=" + encodeURIComponent(JSON.stringify(options.filter)) if (options?.sort) query += "&sort=" + options.sort + "&sort=_id" if (options?.limit) query += "&limit=" + options.limit if (options?.offset) query += "&offset=" + options.offset if (options?.projection) query += "&projection=" + options.projection if (options?._groupBy) query += "&_groupBy=" + options._groupBy if (options?.params) { Object.keys(options.params).forEach((p) => { query += "&" + p + "=" + encodeURIComponent(options.params[p]) }) } let headers: any = { "Content-Type": "application/json", } // send jwt if (!options?.noToken) { // try { // headers["Authorization"] = // "Bearer " + (await getLogin()).tokenString // } catch (e) { } } if (options?.headers) headers = { ...headers, ...options.headers } let url = apiBaseURL + endpoint + (query ? (endpoint.includes("?") ? query : "?" + query) : "") const span = sentry.currentTransaction()?.startChild({ op: "fetch", description: method + " " + url, data: Object.assign({}, options, { url }), }) const trace_id = span?.toTraceparent() if (trace_id) { headers["sentry-trace"] = trace_id } try { const response = await _fetch(url, { method, mode: "cors", headers, body: options?.body ? JSON.stringify(options.body) : null, signal: options?.signal, }) span?.finish() // @ts-ignore let data = (await response?.json()) || null if (response?.status < 200 || response?.status >= 400) throw { response, data } // @ts-ignore return { data, count: response?.headers?.get("x-results-count") || 0 } } catch (e) { if (options?.showErrors && !(e instanceof DOMException)) { // newNotification({ // class: "error", // html: "Es ist ein Fehler aufgetreten! Bitte laden Sie die Seite neu und versuchen es später nocheinmal.", // timeout: 6000, // }) } throw e } } export const sendEmail = async (type: string = "contactForm", data: any, noToken?: boolean) => { await api("email?type=" + type, { method: "post", body: data, noToken, showErrors: true, headers: { token: config.publicToken, }, }) } export const getContent = async (locale: string, filter?: APIParams, params?: APIParams): Promise => { const c = await api("content", { // limit: 1, params: { sort: "priority", ...params, }, filter: { locale, ...filter }, sort: "-priority", }) if (c?.data?.length) { return c.data } return null } export const getGeneralInformation = async (): Promise => { try { let response = await api("general", { method: "get", offset: 0, limit: 1, filter: { public: true, }, }) return response.data } catch (e) { return null } } export const getArticles = async (): Promise => { try { let response = await api("articles", { method: "get", offset: 0, filter: { active: true, }, }) return response.data } catch (e) { return null } } export const getNavigations = async (l: Locale): Promise => { try { let response = await api("navigation", { method: "get", offset: 0, filter: { // locale: l.key, }, }) return response.data } catch (e) { return null } } export const getGalleries = async (galIds: number[], params?: APIParams): Promise => { try { let response = await api("galleries", { method: "get", offset: 0, params: { sort: "title", ...params, }, filter: { _id: { $in: galIds }, }, }) return response.data } catch (e) { return null } }