diff options
Diffstat (limited to 'packages/merchant-backoffice/src/hooks/backend.ts')
-rw-r--r-- | packages/merchant-backoffice/src/hooks/backend.ts | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/packages/merchant-backoffice/src/hooks/backend.ts b/packages/merchant-backoffice/src/hooks/backend.ts deleted file mode 100644 index 789cfc8..0000000 --- a/packages/merchant-backoffice/src/hooks/backend.ts +++ /dev/null @@ -1,319 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2021 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { useSWRConfig } from "swr"; -import axios, { AxiosError, AxiosResponse } from "axios"; -import { MerchantBackend } from "../declaration"; -import { useBackendContext } from "../context/backend"; -import { useEffect, useState } from "preact/hooks"; -import { DEFAULT_REQUEST_TIMEOUT } from "../utils/constants"; -import { axiosHandler, removeAxiosCancelToken } from "../utils/switchableAxios"; - -export function useMatchMutate(): ( - re: RegExp, - value?: unknown -) => Promise<any> { - const { cache, mutate } = useSWRConfig(); - - if (!(cache instanceof Map)) { - throw new Error( - "matchMutate requires the cache provider to be a Map instance" - ); - } - - return function matchRegexMutate(re: RegExp, value?: unknown) { - const allKeys = Array.from(cache.keys()); - // console.log(allKeys) - const keys = allKeys.filter((key) => re.test(key)); - // console.log(allKeys.length, keys.length) - const mutations = keys.map((key) => { - // console.log(key) - mutate(key, value, true); - }); - return Promise.all(mutations); - }; -} - -export type HttpResponse<T> = - | HttpResponseOk<T> - | HttpResponseLoading<T> - | HttpError; -export type HttpResponsePaginated<T> = - | HttpResponseOkPaginated<T> - | HttpResponseLoading<T> - | HttpError; - -export interface RequestInfo { - url: string; - hasToken: boolean; - params: unknown; - data: unknown; - status: number; -} - -interface HttpResponseLoading<T> { - ok?: false; - loading: true; - clientError?: false; - serverError?: false; - - data?: T; -} -export interface HttpResponseOk<T> { - ok: true; - loading?: false; - clientError?: false; - serverError?: false; - - data: T; - info?: RequestInfo; -} - -export type HttpResponseOkPaginated<T> = HttpResponseOk<T> & WithPagination; - -export interface WithPagination { - loadMore: () => void; - loadMorePrev: () => void; - isReachingEnd?: boolean; - isReachingStart?: boolean; -} - -export type HttpError = - | HttpResponseClientError - | HttpResponseServerError - | HttpResponseUnexpectedError; -export interface SwrError { - info: unknown; - status: number; - message: string; -} -export interface HttpResponseServerError { - ok?: false; - loading?: false; - clientError?: false; - serverError: true; - - error?: MerchantBackend.ErrorDetail; - status: number; - message: string; - info?: RequestInfo; -} -interface HttpResponseClientError { - ok?: false; - loading?: false; - clientError: true; - serverError?: false; - - info?: RequestInfo; - isUnauthorized: boolean; - isNotfound: boolean; - status: number; - error?: MerchantBackend.ErrorDetail; - message: string; -} - -interface HttpResponseUnexpectedError { - ok?: false; - loading?: false; - clientError?: false; - serverError?: false; - - info?: RequestInfo; - status?: number; - error: unknown; - message: string; -} - -type Methods = "get" | "post" | "patch" | "delete" | "put"; - -interface RequestOptions { - method?: Methods; - token?: string; - data?: unknown; - params?: unknown; -} - -function buildRequestOk<T>( - res: AxiosResponse<T>, - url: string, - hasToken: boolean -): HttpResponseOk<T> { - return { - ok: true, - data: res.data, - info: { - params: res.config.params, - data: res.config.data, - url, - hasToken, - status: res.status, - }, - }; -} - -// function buildResponse<T>(data?: T, error?: MerchantBackend.ErrorDetail, isValidating?: boolean): HttpResponse<T> { -// if (isValidating) return {loading: true} -// if (error) return buildRequestFailed() -// } - -function buildRequestFailed( - ex: AxiosError<MerchantBackend.ErrorDetail>, - url: string, - hasToken: boolean -): - | HttpResponseClientError - | HttpResponseServerError - | HttpResponseUnexpectedError { - const status = ex.response?.status; - - const info: RequestInfo = { - data: ex.request?.data, - params: ex.request?.params, - url, - hasToken, - status: status || 0, - }; - - if (status && status >= 400 && status < 500) { - const error: HttpResponseClientError = { - clientError: true, - isNotfound: status === 404, - isUnauthorized: status === 401, - status, - info, - message: ex.response?.data?.hint || ex.message, - error: ex.response?.data, - }; - return error; - } - if (status && status >= 500 && status < 600) { - const error: HttpResponseServerError = { - serverError: true, - status, - info, - message: - `${ex.response?.data?.hint} (code ${ex.response?.data?.code})` || - ex.message, - error: ex.response?.data, - }; - return error; - } - - const error: HttpResponseUnexpectedError = { - info, - status, - error: ex, - message: ex.message, - }; - - return error; -} - -const CancelToken = axios.CancelToken; -let source = CancelToken.source(); - -export function cancelPendingRequest(): void { - source.cancel("canceled by the user"); - source = CancelToken.source(); -} - -export function isAxiosError<T>( - error: AxiosError | any -): error is AxiosError<T> { - return error && error.isAxiosError; -} - -export async function request<T>( - url: string, - options: RequestOptions = {} -): Promise<HttpResponseOk<T>> { - const headers = options.token - ? { Authorization: `Bearer ${options.token}` } - : undefined; - - try { - const res = await axiosHandler({ - url, - responseType: "json", - headers, - cancelToken: !removeAxiosCancelToken ? source.token : undefined, - method: options.method || "get", - data: options.data, - params: options.params, - timeout: DEFAULT_REQUEST_TIMEOUT * 1000, - }); - return buildRequestOk<T>(res, url, !!options.token); - } catch (e) { - if (isAxiosError<MerchantBackend.ErrorDetail>(e)) { - const error = buildRequestFailed(e, url, !!options.token); - throw error; - } - throw e; - } -} - -export function multiFetcher<T>( - urls: string[], - token: string, - backend: string -): Promise<HttpResponseOk<T>[]> { - return Promise.all(urls.map((url) => fetcher<T>(url, token, backend))); -} - -export function fetcher<T>( - url: string, - token: string, - backend: string -): Promise<HttpResponseOk<T>> { - return request<T>(`${backend}${url}`, { token }); -} - -export function useBackendInstancesTestForAdmin(): HttpResponse<MerchantBackend.Instances.InstancesResponse> { - const { url, token } = useBackendContext(); - - type Type = MerchantBackend.Instances.InstancesResponse; - - const [result, setResult] = useState<HttpResponse<Type>>({ loading: true }); - - useEffect(() => { - request<Type>(`${url}/management/instances`, { token }) - .then((data) => setResult(data)) - .catch((error) => setResult(error)); - }, [url, token]); - - return result; -} - -export function useBackendConfig(): HttpResponse<MerchantBackend.VersionResponse> { - const { url, token } = useBackendContext(); - - type Type = MerchantBackend.VersionResponse; - - const [result, setResult] = useState<HttpResponse<Type>>({ loading: true }); - - useEffect(() => { - request<Type>(`${url}/config`, { token }) - .then((data) => setResult(data)) - .catch((error) => setResult(error)); - }, [url, token]); - - return result; -} |