322 lines
8.8 KiB
TypeScript
322 lines
8.8 KiB
TypeScript
/*
|
|
This file is part of GNU Taler
|
|
(C) 2021-2023 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 { MerchantBackend } from "../declaration.js";
|
|
import { useBackendContext } from "../context/backend.js";
|
|
import { useCallback, useEffect, useState } from "preact/hooks";
|
|
import { useInstanceContext } from "../context/instance.js";
|
|
import {
|
|
HttpResponse,
|
|
HttpResponseOk,
|
|
RequestOptions,
|
|
} from "@gnu-taler/web-util/lib/index.browser";
|
|
import { useApiContext } from "@gnu-taler/web-util/lib/index.browser";
|
|
|
|
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());
|
|
const keys = allKeys.filter((key) => re.test(key));
|
|
const mutations = keys.map((key) => {
|
|
return mutate(key, value, true);
|
|
});
|
|
return Promise.all(mutations);
|
|
};
|
|
}
|
|
|
|
export function useBackendInstancesTestForAdmin(): HttpResponse<
|
|
MerchantBackend.Instances.InstancesResponse,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { request } = useBackendBaseRequest();
|
|
|
|
type Type = MerchantBackend.Instances.InstancesResponse;
|
|
|
|
const [result, setResult] = useState<
|
|
HttpResponse<Type, MerchantBackend.ErrorDetail>
|
|
>({ loading: true });
|
|
|
|
useEffect(() => {
|
|
request<Type>(`/management/instances`)
|
|
.then((data) => setResult(data))
|
|
.catch((error) => setResult(error));
|
|
}, [request]);
|
|
|
|
return result;
|
|
}
|
|
|
|
export function useBackendConfig(): HttpResponse<
|
|
MerchantBackend.VersionResponse,
|
|
MerchantBackend.ErrorDetail
|
|
> {
|
|
const { request } = useBackendBaseRequest();
|
|
|
|
type Type = MerchantBackend.VersionResponse;
|
|
|
|
const [result, setResult] = useState<
|
|
HttpResponse<Type, MerchantBackend.ErrorDetail>
|
|
>({ loading: true });
|
|
|
|
useEffect(() => {
|
|
request<Type>(`/config`)
|
|
.then((data) => setResult(data))
|
|
.catch((error) => setResult(error));
|
|
}, [request]);
|
|
|
|
return result;
|
|
}
|
|
|
|
interface useBackendInstanceRequestType {
|
|
request: <T>(
|
|
endpoint: string,
|
|
options?: RequestOptions,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
fetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
|
|
reserveDetailFetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
|
|
tipsDetailFetcher: <T>(endpoint: string) => Promise<HttpResponseOk<T>>;
|
|
multiFetcher: <T>(url: string[]) => Promise<HttpResponseOk<T>[]>;
|
|
orderFetcher: <T>(
|
|
endpoint: string,
|
|
paid?: YesOrNo,
|
|
refunded?: YesOrNo,
|
|
wired?: YesOrNo,
|
|
searchDate?: Date,
|
|
delta?: number,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
transferFetcher: <T>(
|
|
endpoint: string,
|
|
payto_uri?: string,
|
|
verified?: string,
|
|
position?: string,
|
|
delta?: number,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
templateFetcher: <T>(
|
|
endpoint: string,
|
|
position?: string,
|
|
delta?: number,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
webhookFetcher: <T>(
|
|
endpoint: string,
|
|
position?: string,
|
|
delta?: number,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
}
|
|
interface useBackendBaseRequestType {
|
|
request: <T>(
|
|
endpoint: string,
|
|
options?: RequestOptions,
|
|
) => Promise<HttpResponseOk<T>>;
|
|
}
|
|
|
|
type YesOrNo = "yes" | "no";
|
|
|
|
/**
|
|
*
|
|
* @param root the request is intended to the base URL and no the instance URL
|
|
* @returns request handler to
|
|
*/
|
|
export function useBackendBaseRequest(): useBackendBaseRequestType {
|
|
const { url: backend, token } = useBackendContext();
|
|
const { request: requestHandler } = useApiContext();
|
|
|
|
const request = useCallback(
|
|
function requestImpl<T>(
|
|
endpoint: string,
|
|
options: RequestOptions = {},
|
|
): Promise<HttpResponseOk<T>> {
|
|
return requestHandler<T>(backend, endpoint, { token, ...options });
|
|
},
|
|
[backend, token],
|
|
);
|
|
|
|
return { request };
|
|
}
|
|
|
|
export function useBackendInstanceRequest(): useBackendInstanceRequestType {
|
|
const { url: rootBackendUrl, token: rootToken } = useBackendContext();
|
|
const { token: instanceToken, id, admin } = useInstanceContext();
|
|
const { request: requestHandler } = useApiContext();
|
|
|
|
const { baseUrl, token } = !admin
|
|
? { baseUrl: rootBackendUrl, token: rootToken }
|
|
: { baseUrl: `${rootBackendUrl}/instances/${id}`, token: instanceToken };
|
|
|
|
const request = useCallback(
|
|
function requestImpl<T>(
|
|
endpoint: string,
|
|
options: RequestOptions = {},
|
|
): Promise<HttpResponseOk<T>> {
|
|
return requestHandler<T>(baseUrl, endpoint, { token, ...options });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const multiFetcher = useCallback(
|
|
function multiFetcherImpl<T>(
|
|
endpoints: string[],
|
|
): Promise<HttpResponseOk<T>[]> {
|
|
return Promise.all(
|
|
endpoints.map((endpoint) =>
|
|
requestHandler<T>(baseUrl, endpoint, { token }),
|
|
),
|
|
);
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const fetcher = useCallback(
|
|
function fetcherImpl<T>(endpoint: string): Promise<HttpResponseOk<T>> {
|
|
return requestHandler<T>(baseUrl, endpoint, { token });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const orderFetcher = useCallback(
|
|
function orderFetcherImpl<T>(
|
|
endpoint: string,
|
|
paid?: YesOrNo,
|
|
refunded?: YesOrNo,
|
|
wired?: YesOrNo,
|
|
searchDate?: Date,
|
|
delta?: number,
|
|
): Promise<HttpResponseOk<T>> {
|
|
const date_ms =
|
|
delta && delta < 0 && searchDate
|
|
? searchDate.getTime() + 1
|
|
: searchDate?.getTime();
|
|
const params: any = {};
|
|
if (paid !== undefined) params.paid = paid;
|
|
if (delta !== undefined) params.delta = delta;
|
|
if (refunded !== undefined) params.refunded = refunded;
|
|
if (wired !== undefined) params.wired = wired;
|
|
if (date_ms !== undefined) params.date_ms = date_ms;
|
|
return requestHandler<T>(baseUrl, endpoint, { params, token });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const reserveDetailFetcher = useCallback(
|
|
function reserveDetailFetcherImpl<T>(
|
|
endpoint: string,
|
|
): Promise<HttpResponseOk<T>> {
|
|
return requestHandler<T>(baseUrl, endpoint, {
|
|
params: {
|
|
tips: "yes",
|
|
},
|
|
token,
|
|
});
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const tipsDetailFetcher = useCallback(
|
|
function tipsDetailFetcherImpl<T>(
|
|
endpoint: string,
|
|
): Promise<HttpResponseOk<T>> {
|
|
return requestHandler<T>(baseUrl, endpoint, {
|
|
params: {
|
|
pickups: "yes",
|
|
},
|
|
token,
|
|
});
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const transferFetcher = useCallback(
|
|
function transferFetcherImpl<T>(
|
|
endpoint: string,
|
|
payto_uri?: string,
|
|
verified?: string,
|
|
position?: string,
|
|
delta?: number,
|
|
): Promise<HttpResponseOk<T>> {
|
|
const params: any = {};
|
|
if (payto_uri !== undefined) params.payto_uri = payto_uri;
|
|
if (verified !== undefined) params.verified = verified;
|
|
if (delta !== undefined) {
|
|
params.limit = delta;
|
|
}
|
|
if (position !== undefined) params.offset = position;
|
|
|
|
return requestHandler<T>(baseUrl, endpoint, { params, token });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const templateFetcher = useCallback(
|
|
function templateFetcherImpl<T>(
|
|
endpoint: string,
|
|
position?: string,
|
|
delta?: number,
|
|
): Promise<HttpResponseOk<T>> {
|
|
const params: any = {};
|
|
if (delta !== undefined) {
|
|
params.limit = delta;
|
|
}
|
|
if (position !== undefined) params.offset = position;
|
|
|
|
return requestHandler<T>(baseUrl, endpoint, { params, token });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
const webhookFetcher = useCallback(
|
|
function webhookFetcherImpl<T>(
|
|
endpoint: string,
|
|
position?: string,
|
|
delta?: number,
|
|
): Promise<HttpResponseOk<T>> {
|
|
const params: any = {};
|
|
if (delta !== undefined) {
|
|
params.limit = delta;
|
|
}
|
|
if (position !== undefined) params.offset = position;
|
|
|
|
return requestHandler<T>(baseUrl, endpoint, { params, token });
|
|
},
|
|
[baseUrl, token],
|
|
);
|
|
|
|
return {
|
|
request,
|
|
fetcher,
|
|
multiFetcher,
|
|
orderFetcher,
|
|
reserveDetailFetcher,
|
|
tipsDetailFetcher,
|
|
transferFetcher,
|
|
templateFetcher,
|
|
webhookFetcher,
|
|
};
|
|
}
|