mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-09 20:12:10 +10:00
* feat: small library tweaks + company page * feat: new store view * fix: ci merge error * feat: add genres to store page * feat: sorting * feat: lock game/version imports while their tasks are running * feat: feature games * feat: tag based filtering * fix: make tags alphabetical * refactor: move a bunch of i18n to common * feat: add localizations for everything * fix: title description on panel * fix: feature carousel text * fix: i18n footer strings * feat: add tag page * fix: develop merge * feat: offline games support (don't error out if provider throws) * feat: tag management * feat: show library next to game import + small fixes * feat: most of the company and tag managers * feat: company text field editing * fix: small fixes + tsgo experiemental * feat: upload icon and banner * feat: store infinite scrolling and bulk import mode * fix: lint * fix: add drop-base to prettier ignore
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import type {
|
|
ExtractedRouteMethod,
|
|
NitroFetchOptions,
|
|
NitroFetchRequest,
|
|
TypedInternalResponse,
|
|
} from "nitropack/types";
|
|
import type { FetchError } from "ofetch";
|
|
|
|
interface DropFetch<
|
|
DefaultT = unknown,
|
|
DefaultR extends NitroFetchRequest = NitroFetchRequest,
|
|
> {
|
|
<
|
|
T = DefaultT,
|
|
R extends NitroFetchRequest = DefaultR,
|
|
O extends NitroFetchOptions<R> = NitroFetchOptions<R>,
|
|
>(
|
|
request: R,
|
|
opts?: O & { failTitle?: string },
|
|
): Promise<
|
|
// sometimes there is an error, other times there isn't
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
TypedInternalResponse<
|
|
R,
|
|
T,
|
|
NitroFetchOptions<R> extends O ? "get" : ExtractedRouteMethod<R, O>
|
|
>
|
|
>;
|
|
}
|
|
|
|
export const $dropFetch: DropFetch = async (rawRequest, opts) => {
|
|
const requestParts = rawRequest.toString().split("/");
|
|
requestParts.forEach((part, index) => {
|
|
if (!part.startsWith(":")) {
|
|
return;
|
|
}
|
|
const partName = part.slice(1);
|
|
const replacement = opts?.params?.[partName] as string | undefined;
|
|
if (!replacement) {
|
|
return;
|
|
}
|
|
requestParts[index] = replacement;
|
|
|
|
delete opts?.params?.[partName];
|
|
});
|
|
const request = requestParts.join("/");
|
|
|
|
if (!getCurrentInstance()?.proxy) {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore Excessive stack depth comparing types
|
|
return await $fetch(request, opts);
|
|
}
|
|
|
|
const id = request.toString();
|
|
|
|
const state = useState(id);
|
|
if (state.value) {
|
|
// Deep copy
|
|
const object = JSON.parse(JSON.stringify(state.value));
|
|
// Never use again on client
|
|
if (import.meta.client) state.value = undefined;
|
|
return object;
|
|
}
|
|
|
|
const headers = useRequestHeaders(["cookie", "authorization"]);
|
|
try {
|
|
const data = await $fetch(request, {
|
|
...opts,
|
|
headers: { ...opts?.headers, ...headers },
|
|
});
|
|
if (import.meta.server) state.value = data;
|
|
return data;
|
|
} catch (e) {
|
|
if (import.meta.client && opts?.failTitle) {
|
|
createModal(
|
|
ModalType.Notification,
|
|
{
|
|
title: opts.failTitle,
|
|
description:
|
|
(e as FetchError)?.statusMessage ?? (e as string).toString(),
|
|
buttonText: $t("common.close"),
|
|
},
|
|
(_, c) => c(),
|
|
);
|
|
}
|
|
throw e;
|
|
}
|
|
};
|