117 lines
4.2 KiB
TypeScript
117 lines
4.2 KiB
TypeScript
import type { RequestHandler } from '@sveltejs/kit';
|
|
import { getSession } from '../../../../lib/server/sessionStore';
|
|
import { PLEB_BEATLEADER_ID, DEFAULT_ADMIN_RANK_FALLBACK } from '../../../../lib/utils/plebsaber-utils';
|
|
|
|
const PLAYER_ENDPOINT = 'https://api.beatleader.com/player/';
|
|
|
|
type BeatLeaderIdentity = { id: string; name: string | null };
|
|
type BeatLeaderPlayer = {
|
|
id: string;
|
|
name: string | null;
|
|
avatar: string | null;
|
|
country: string | null;
|
|
role: string | null;
|
|
rank: number | null;
|
|
countryRank: number | null;
|
|
techPp: number | null;
|
|
accPp: number | null;
|
|
passPp: number | null;
|
|
pp: number | null;
|
|
mapperId: number | null;
|
|
level: number | null;
|
|
banned: boolean;
|
|
profileSettings: { showAllRatings: boolean } | null;
|
|
};
|
|
|
|
type ResponsePayload = {
|
|
identity: BeatLeaderIdentity;
|
|
player: BeatLeaderPlayer | null;
|
|
rawPlayer: Record<string, unknown> | null;
|
|
adminBaseline: {
|
|
rank: number | null;
|
|
fallback: number;
|
|
};
|
|
};
|
|
|
|
export const GET: RequestHandler = async ({ cookies, fetch }) => {
|
|
const session = getSession(cookies);
|
|
if (!session) {
|
|
return new Response(
|
|
JSON.stringify({ error: 'Unauthorized', login: '/auth/beatleader/login' }),
|
|
{ status: 401, headers: { 'content-type': 'application/json' } }
|
|
);
|
|
}
|
|
|
|
const identity: BeatLeaderIdentity = {
|
|
id: session.beatleaderId,
|
|
name: session.name
|
|
};
|
|
|
|
let player: BeatLeaderPlayer | null = null;
|
|
let rawPlayer: Record<string, unknown> | null = null;
|
|
|
|
let adminRank: number | null = null;
|
|
|
|
try {
|
|
const res = await fetch(`${PLAYER_ENDPOINT}${encodeURIComponent(session.beatleaderId)}?stats=true`);
|
|
if (res.ok) {
|
|
rawPlayer = (await res.json()) as Record<string, unknown>;
|
|
player = {
|
|
id: typeof rawPlayer.id === 'string' ? (rawPlayer.id as string) : session.beatleaderId,
|
|
name: typeof rawPlayer.name === 'string' ? (rawPlayer.name as string) : session.name,
|
|
avatar: typeof rawPlayer.avatar === 'string' ? (rawPlayer.avatar as string) : session.avatar,
|
|
country: typeof rawPlayer.country === 'string' ? (rawPlayer.country as string) : null,
|
|
role: typeof rawPlayer.role === 'string' ? (rawPlayer.role as string) : null,
|
|
rank: typeof rawPlayer.rank === 'number' ? (rawPlayer.rank as number) : null,
|
|
countryRank: typeof rawPlayer.countryRank === 'number' ? (rawPlayer.countryRank as number) : null,
|
|
techPp: typeof rawPlayer.techPp === 'number' ? (rawPlayer.techPp as number) : null,
|
|
accPp: typeof rawPlayer.accPp === 'number' ? (rawPlayer.accPp as number) : null,
|
|
passPp: typeof rawPlayer.passPp === 'number' ? (rawPlayer.passPp as number) : null,
|
|
pp: typeof rawPlayer.pp === 'number' ? (rawPlayer.pp as number) : null,
|
|
mapperId: typeof rawPlayer.mapperId === 'number' ? (rawPlayer.mapperId as number) : null,
|
|
level: typeof rawPlayer.level === 'number' ? (rawPlayer.level as number) : null,
|
|
banned: Boolean(rawPlayer.banned),
|
|
profileSettings: typeof rawPlayer.profileSettings === 'object' && rawPlayer.profileSettings !== null
|
|
? {
|
|
showAllRatings: Boolean((rawPlayer.profileSettings as Record<string, unknown>).showAllRatings)
|
|
}
|
|
: null
|
|
};
|
|
if (session.beatleaderId === PLEB_BEATLEADER_ID) {
|
|
adminRank = typeof rawPlayer.rank === 'number' ? (rawPlayer.rank as number) : adminRank;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to refresh BeatLeader public profile', err);
|
|
}
|
|
|
|
if (adminRank === null) {
|
|
try {
|
|
const res = await fetch(`${PLAYER_ENDPOINT}${encodeURIComponent(PLEB_BEATLEADER_ID)}?stats=true`);
|
|
if (res.ok) {
|
|
const admin = (await res.json()) as Record<string, unknown>;
|
|
const rankValue = admin?.rank;
|
|
if (typeof rankValue === 'number') {
|
|
adminRank = rankValue;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to refresh BeatLeader admin profile', err);
|
|
}
|
|
}
|
|
|
|
const payload: ResponsePayload = {
|
|
identity,
|
|
player,
|
|
rawPlayer,
|
|
adminBaseline: {
|
|
rank: adminRank,
|
|
fallback: DEFAULT_ADMIN_RANK_FALLBACK
|
|
}
|
|
};
|
|
return new Response(JSON.stringify(payload), {
|
|
headers: { 'content-type': 'application/json' }
|
|
});
|
|
};
|
|
|