Add function to fetch player information (#2010)

## Description:

This pull request introduces the fetchPlayerById() function together
with its associated schema components.

It represents one part of a series of split pull requests related to the
PlayerInfoModal (Player Profile). Subsequent pull requests will address
UI implementation and additional features.

(origin pr:https://github.com/openfrontio/OpenFrontIO/pull/1758)

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

aotumuri

---------

Co-authored-by: evanpelle <evanpelle@gmail.com>
This commit is contained in:
Aotumuri
2025-09-14 15:15:50 -07:00
committed by GitHub
co-authored by evanpelle
parent 835c8d97ce
commit a4127960b7
3 changed files with 81 additions and 2 deletions
+39 -1
View File
@@ -1,5 +1,7 @@
import { z } from "zod";
import { base64urlToUuid } from "./Base64";
import { BigIntStringSchema, PlayerStatsSchema } from "./StatsSchemas";
import { Difficulty, GameMapType, GameMode, GameType } from "./game/Game";
export const RefreshResponseSchema = z.object({
token: z.string(),
@@ -37,8 +39,8 @@ export const DiscordUserSchema = z.object({
username: z.string(),
global_name: z.string().nullable(),
discriminator: z.string(),
locale: z.string().optional(),
});
export type DiscordUser = z.infer<typeof DiscordUserSchema>;
export const UserMeResponseSchema = z.object({
user: z.object({
@@ -52,3 +54,39 @@ export const UserMeResponseSchema = z.object({
}),
});
export type UserMeResponse = z.infer<typeof UserMeResponseSchema>;
export const PlayerStatsLeafSchema = z.object({
wins: BigIntStringSchema,
losses: BigIntStringSchema,
total: BigIntStringSchema,
stats: PlayerStatsSchema,
});
export type PlayerStatsLeaf = z.infer<typeof PlayerStatsLeafSchema>;
export const PlayerStatsTreeSchema = z.partialRecord(
z.enum(GameType),
z.partialRecord(
z.enum(GameMode),
z.partialRecord(z.enum(Difficulty), PlayerStatsLeafSchema),
),
);
export type PlayerStatsTree = z.infer<typeof PlayerStatsTreeSchema>;
export const PlayerGameSchema = z.object({
gameId: z.string(),
start: z.iso.datetime(),
mode: z.enum(GameMode),
type: z.enum(GameType),
map: z.enum(GameMapType),
difficulty: z.enum(Difficulty),
clientId: z.string().optional(),
});
export type PlayerGame = z.infer<typeof PlayerGameSchema>;
export const PlayerProfileSchema = z.object({
createdAt: z.iso.datetime(),
user: DiscordUserSchema.optional(),
games: PlayerGameSchema.array(),
stats: PlayerStatsTreeSchema,
});
export type PlayerProfile = z.infer<typeof PlayerProfileSchema>;
+1 -1
View File
@@ -88,7 +88,7 @@ export const OTHER_INDEX_CAPTURE = 2; // Structures captured
export const OTHER_INDEX_LOST = 3; // Structures/warships destroyed/captured by others
export const OTHER_INDEX_UPGRADE = 4; // Structures upgraded
const BigIntStringSchema = z.preprocess((val) => {
export const BigIntStringSchema = z.preprocess((val) => {
if (typeof val === "string" && /^-?\d+$/.test(val)) return BigInt(val);
if (typeof val === "bigint") return val;
return val;