import { z } from 'zod'; const colorSchema = z.union([z.literal('w'), z.literal('b')]); const squareSchema = z.string().regex(/^[a-h][1-8]$/); const promotionSchema = z.union([z.literal('q'), z.literal('r'), z.literal('b'), z.literal('n')]); const gameIdSchema = z.string().regex(/^[a-z0-9]{8}$/); const tokenSchema = z.string().regex(/^[a-z0-9]{24}$/); export const helloSchema = z.object({ type: z.literal('hello'), gameId: gameIdSchema, token: tokenSchema.optional(), joinAs: z.union([colorSchema, z.literal('auto')]).optional(), }); export const commitSchema = z.object({ type: z.literal('commit'), from: squareSchema, to: squareSchema.optional(), promotion: promotionSchema.optional(), }); export const resignSchema = z.object({ type: z.literal('resign') }); export const offerDrawSchema = z.object({ type: z.literal('offer-draw') }); export const respondDrawSchema = z.object({ type: z.literal('respond-draw'), accept: z.boolean(), }); export const pongSchema = z.object({ type: z.literal('pong') }); export const clientMessageSchema = z.discriminatedUnion('type', [ helloSchema, commitSchema, resignSchema, offerDrawSchema, respondDrawSchema, pongSchema, ]); export const createGameSchema = z.object({ mode: z.union([z.literal('blind'), z.literal('vanilla')]), side: z.union([colorSchema, z.literal('random')]), highlightingEnabled: z.boolean(), vsAi: z.object({ brain: z.union([z.literal('casual'), z.literal('recon')]), }).optional(), });