Files
drop/server/api/v1/client/game/[id]/versions.get.ts
T
DecDuck dbe34684d8 Paginated admin library & upgrade manifests (#351)
* feat: new page layout + endpoint

* feat: non-parallel mass import

* feat: paginated admin library

* feat: lint and performance improvement

* feat: library filter util

* feat: link frontend features to backend

* fix: lint

* fix: small fixes

* feat: bump torrential

* fix: lint
2026-02-25 02:17:33 +11:00

131 lines
3.5 KiB
TypeScript

import { ArkErrors, type } from "arktype";
import type { Platform } from "~/prisma/client/enums";
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
import prisma from "~/server/internal/db/database";
import type { GameVersionSize } from "~/server/internal/gamesize";
import gameSizeManager from "~/server/internal/gamesize";
type VersionDownloadOption = {
gameId: string;
versionId: string;
displayName?: string | undefined;
versionPath?: string | undefined;
platform: Platform;
size: GameVersionSize;
requiredContent: Array<{
gameId: string;
versionId: string;
name: string;
iconObjectId: string;
shortDescription: string;
size: GameVersionSize;
}>;
};
const Query = type({
previous: "string?",
});
export default defineClientEventHandler(async (h3) => {
const id = getRouterParam(h3, "id")!;
if (!id)
throw createError({
statusCode: 400,
statusMessage: "No ID in router params",
});
const query = Query(getQuery(h3));
if (query instanceof ArkErrors)
throw createError({ statusCode: 400, message: query.summary });
const rawVersions = await prisma.gameVersion.findMany({
where: {
gameId: id,
},
orderBy: {
versionIndex: "desc", // Latest one first
},
select: {
versionId: true,
displayName: true,
versionPath: true,
gameId: true,
launches: {
select: {
platform: true,
emulator: {
select: {
gameVersion: {
select: {
game: {
select: {
mName: true,
mShortDescription: true,
mIconObjectId: true,
id: true,
},
},
versionId: true,
},
},
},
},
},
},
setups: true,
},
});
const versions: Array<VersionDownloadOption> = (
await Promise.all(
rawVersions.map(async (v) => {
const platformOptions: Map<
Platform,
VersionDownloadOption["requiredContent"]
> = new Map();
for (const launch of [...v.launches, ...v.setups]) {
if (!platformOptions.has(launch.platform))
platformOptions.set(launch.platform, []);
if ("emulator" in launch && launch.emulator) {
const old = platformOptions.get(launch.platform)!;
const gv = launch.emulator.gameVersion;
old.push({
gameId: gv.game.id,
versionId: gv.versionId,
name: gv.game.mName,
iconObjectId: gv.game.mIconObjectId,
shortDescription: gv.game.mShortDescription,
size: (await gameSizeManager.getVersionSize(gv.versionId))!,
});
}
}
const size = await gameSizeManager.getVersionSize(
v.versionId,
query.previous,
);
return platformOptions
.entries()
.map(
([platform, requiredContent]) =>
({
gameId: v.gameId,
versionId: v.versionId,
displayName: v.displayName || undefined,
versionPath: v.versionPath || undefined,
platform,
requiredContent,
size: size!,
}) satisfies VersionDownloadOption,
)
.toArray();
}),
)
).flat();
return versions;
});