- move shared parsing/grouping helpers into serverUtils and update imports - add xcxApi singleton in serverUtils - add Redis-backed uid score store and /api/user/nowScores endpoint - preload uid scores in event loader and tags in profile loader - allow grouping prediction to switch sort mode between current/yearly score - update tags component to consume loader-provided tags - remove unused zustand game store - add redis test scaffold and scoreboard component scaffold
92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import { serve } from "bun";
|
|
import { getMatchInfo, listEvent } from "./utils/utils";
|
|
import index from "./index.html";
|
|
import { xcxApi } from "./utils/server";
|
|
import { getUidScore } from "./services/uidScoreStore";
|
|
|
|
if (!process.env.KAIQIUCC_TOKEN) {
|
|
console.error('env KAIQIUCC_TOKEN not found');
|
|
process.exit(1);
|
|
}
|
|
|
|
|
|
const server = serve({
|
|
port: process.env.PORT || 3000,
|
|
routes: {
|
|
// Serve index.html for all unmatched routes.
|
|
"/*": index,
|
|
"/api/events/:clubid": {
|
|
async GET(req) {
|
|
const data = await listEvent(req.params.clubid);
|
|
return Response.json(data);
|
|
}
|
|
},
|
|
"/api/match/:matchId": {
|
|
async GET(req) {
|
|
const data = await getMatchInfo(req.params.matchId);
|
|
return Response.json(data);
|
|
}
|
|
},
|
|
"/api/match/:matchId/:itemId": {
|
|
async GET(req) {
|
|
const { matchId, itemId } = req.params;
|
|
const data = await xcxApi.getMemberDetail(matchId, itemId);
|
|
return Response.json(data);
|
|
}
|
|
},
|
|
"/api/user/find": {
|
|
async GET(req) {
|
|
const searchParams = new URL(req.url).searchParams;
|
|
const key = searchParams.get('key') ?? '';
|
|
const page = Number(searchParams.get('page'));
|
|
const users = await xcxApi.findUser(key, page);
|
|
return Response.json(users);
|
|
}
|
|
},
|
|
"/api/user/nowScores": {
|
|
async GET(req) {
|
|
const searchParams = new URL(req.url).searchParams;
|
|
const uids = searchParams.get('uids')?.split(',') ?? [];
|
|
const uidScore = await getUidScore(uids);
|
|
return Response.json(uidScore);
|
|
}
|
|
},
|
|
"/api/user/:uid": {
|
|
async GET(req) {
|
|
const uid = req.params.uid;
|
|
if (uid === '0') return Response.json(null);
|
|
const profile = await xcxApi.getAdvProfile(uid);
|
|
return Response.json(profile);
|
|
},
|
|
},
|
|
"/api/user/:uid/games": {
|
|
async GET(req) {
|
|
const uid = req.params.uid;
|
|
if (uid === '0') return Response.json([]);
|
|
const search = new URL(req.url).searchParams;
|
|
const page = Number(search.get('page')) ?? 0;
|
|
const resp = await xcxApi.getGameList(uid, page);
|
|
return Response.json(resp);
|
|
},
|
|
},
|
|
"/api/user/:uid/tags": {
|
|
async GET(req) {
|
|
const uid = req.params.uid;
|
|
if (uid == '0') return Response.json([]);
|
|
const profile = await xcxApi.getPlayerTags(uid);
|
|
return Response.json(profile);
|
|
},
|
|
}
|
|
},
|
|
|
|
development: process.env.NODE_ENV !== "production" && {
|
|
// Enable browser hot reloading in development
|
|
hmr: true,
|
|
|
|
// Echo console logs from the browser to the server
|
|
console: true,
|
|
},
|
|
});
|
|
|
|
console.log(`🚀 Server running at ${server.url}`);
|