import axios, { AxiosError, AxiosInstance, ResponseType } from "axios"; import { App, Plugin } from "vue"; import { advent22Store } from "./store"; export class Advent22 { private axios: AxiosInstance; public constructor() { this.axios = axios.create({ timeout: 10000, }); } private get api_baseurl(): string { // in production mode, return "//host/api" if (process.env.NODE_ENV === "production") { return `//${window.location.host}/api`; } else if (process.env.NODE_ENV !== "development") { // not in prouction or development mode console.warn("Unexpected NODE_ENV value"); } // in development mode, return "//hostname:8000/api" return `//${window.location.hostname}:8000/api`; } public name_door(day: number): string { return `Türchen ${day}`; } public format_user_error([reason, endpoint]: [unknown, string]): string { let msg = "Unbekannter Fehler, bitte wiederholen! Besteht das Problem länger, bitte Admin benachrichtigen!"; let code = "U"; const result = () => `${msg} (Fehlercode: ${code}/${endpoint})`; if (!(reason instanceof AxiosError)) return result(); switch (reason.code) { case "ECONNABORTED": // API unerreichbar msg = "API antwortet nicht, bitte später wiederholen! Besteht das Problem länger, bitte Admin benachrichtigen!"; code = "D"; break; case "ERR_NETWORK": // Netzwerk nicht verbunden msg = "Sieht aus, als sei deine Netzwerkverbindung gestört."; code = "N"; break; default: if (reason.response === undefined) return result(); switch (reason.response.status) { case 401: // UNAUTHORIZED msg = "Netter Versuch :)"; code = "A"; break; case 422: // UNPROCESSABLE ENTITY msg = "Funktion ist kaputt, bitte Admin benachrichtigen!"; code = "I"; break; default: // HTTP code = `H${reason.response.status}`; break; } break; } return result(); } public alert_user_error(param: [unknown, string]): void { alert(this.format_user_error(param)); } public api_url(): string; public api_url(endpoint: string): string; public api_url(endpoint?: string): string { if (endpoint === undefined) { return this.api_baseurl; } while (endpoint.startsWith("/")) { endpoint = endpoint.substring(1); } return `${this.api_baseurl}/${endpoint}`; } private _api_get(endpoint: string): Promise; private _api_get(endpoint: string, responseType: ResponseType): Promise; private _api_get( endpoint: string, responseType: ResponseType = "json", ): Promise { const req_config = { auth: advent22Store().axios_creds, responseType: responseType, }; return new Promise((resolve, reject) => { this.axios .get(this.api_url(endpoint), req_config) .then((response) => resolve(response.data)) .catch((reason) => { console.error(`Failed to query ${endpoint}: ${reason}`); reject([reason, endpoint]); }); }); } public api_get(endpoint: string): Promise { return this._api_get(endpoint); } public api_get_blob(endpoint: string): Promise { return new Promise((resolve, reject) => { this._api_get(endpoint, "blob") .then((data: Blob) => { const reader = new FileReader(); reader.readAsDataURL(data); reader.onloadend = () => { if (typeof reader.result === "string") { resolve(reader.result); } else { reject(["failed data url", endpoint]); } }; }) .catch(reject); }); } public api_put(endpoint: string, data: unknown): Promise { const req_config = { auth: advent22Store().axios_creds, }; return new Promise((resolve, reject) => { this.axios .put(this.api_url(endpoint), data, req_config) .then(() => resolve()) .catch((reason) => { console.error(`Failed to query ${endpoint}: ${reason}`); reject([reason, endpoint]); }); }); } } export const ADVENT22 = new Advent22(); export const Advent22Plugin: Plugin = { install(app: App) { app.config.globalProperties.$advent22 = ADVENT22; }, };