discriminatedUnion (#1130)

## Description:

Convert `z.union()` to `z.discriminatedUnion()` and remove the redundant
`type` enum from `BaseIntentSchema`.

## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

---------

Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
Scott Anderson
2025-06-11 16:46:59 -04:00
committed by GitHub
parent 4cd3c2f984
commit bbf6329933
+7 -23
View File
@@ -131,7 +131,7 @@ export const GameConfigSchema = z.object({
infiniteTroops: z.boolean(),
instantBuild: z.boolean(),
maxPlayers: z.number().optional(),
disabledUnits: z.array(z.nativeEnum(UnitType)).optional(),
disabledUnits: z.nativeEnum(UnitType).array().optional(),
playerTeams: z.union([z.number().optional(), z.literal(Duos)]),
});
@@ -170,22 +170,6 @@ export const AllPlayersStatsSchema = z.record(ID, PlayerStatsSchema);
// Zod schemas
const BaseIntentSchema = z.object({
type: z.enum([
"attack",
"cancel_attack",
"spawn",
"mark_disconnected",
"boat",
"cancel_boat",
"name",
"targetPlayer",
"emoji",
"troop_ratio",
"build_unit",
"upgrade_structure",
"embargo",
"move_warship",
]),
clientID: ID,
});
@@ -311,7 +295,7 @@ export const MarkDisconnectedIntentSchema = BaseIntentSchema.extend({
isDisconnected: z.boolean(),
});
const IntentSchema = z.union([
const IntentSchema = z.discriminatedUnion("type", [
AttackIntentSchema,
CancelAttackIntentSchema,
SpawnIntentSchema,
@@ -335,7 +319,7 @@ const IntentSchema = z.union([
export const TurnSchema = z.object({
turnNumber: z.number(),
intents: z.array(IntentSchema),
intents: IntentSchema.array(),
// The hash of the game state at the end of the turn.
hash: z.number().nullable().optional(),
});
@@ -369,13 +353,13 @@ export const PlayerSchema = z.object({
export const GameStartInfoSchema = z.object({
gameID: ID,
config: GameConfigSchema,
players: z.array(PlayerSchema),
players: PlayerSchema.array(),
});
export const ServerStartGameMessageSchema = ServerBaseMessageSchema.extend({
type: z.literal("start"),
// Turns the client missed if they are late to the game.
turns: z.array(TurnSchema),
turns: TurnSchema.array(),
gameStartInfo: GameStartInfoSchema,
});
@@ -460,7 +444,7 @@ export const PlayerRecordSchema = PlayerSchema.extend({
export type PlayerRecord = z.infer<typeof PlayerRecordSchema>;
export const GameEndInfoSchema = GameStartInfoSchema.extend({
players: z.array(PlayerRecordSchema),
players: PlayerRecordSchema.array(),
start: z.number(),
end: z.number(),
duration: z.number().nonnegative(),
@@ -479,6 +463,6 @@ export const AnalyticsRecordSchema = z.object({
export type AnalyticsRecord = z.infer<typeof AnalyticsRecordSchema>;
export const GameRecordSchema = AnalyticsRecordSchema.extend({
turns: z.array(TurnSchema),
turns: TurnSchema.array(),
});
export type GameRecord = z.infer<typeof GameRecordSchema>;