index.ts

  1import myzod, { Infer } from 'myzod';
  2import { DeepReadonly } from 'ts-essentials';
  3
  4// See protocol.go.
  5
  6// Messages sent from client to server.
  7
  8export type WordPack = Infer<typeof WordPack>;
  9const WordPack = myzod.object({
 10    name: myzod.string(),
 11    words: myzod.array(myzod.string()),
 12});
 13
 14export type PartialClientNote = Infer<typeof PartialClientNote>;
 15export type PartialClientNoteSender = (r: PartialClientNote) => void;
 16const PartialClientNote = myzod.union([
 17    myzod.object({
 18        method: myzod.literal('newGame'),
 19        params: myzod.object({}),
 20    }),
 21    myzod.object({
 22        method: myzod.literal('endTurn'),
 23        params: myzod.object({}),
 24    }),
 25    myzod.object({
 26        method: myzod.literal('randomizeTeams'),
 27        params: myzod.object({}),
 28    }),
 29    myzod.object({
 30        method: myzod.literal('reveal'),
 31        params: myzod.object({ row: myzod.number(), col: myzod.number() }),
 32    }),
 33    myzod.object({
 34        method: myzod.literal('changeTeam'),
 35        params: myzod.object({ team: myzod.number() }),
 36    }),
 37    myzod.object({
 38        method: myzod.literal('changeNickname'),
 39        params: myzod.object({ nickname: myzod.string() }),
 40    }),
 41    myzod.object({
 42        method: myzod.literal('changeRole'),
 43        params: myzod.object({ spymaster: myzod.boolean() }),
 44    }),
 45    myzod.object({
 46        method: myzod.literal('changePack'),
 47        params: myzod.object({ num: myzod.number(), enable: myzod.boolean() }),
 48    }),
 49    myzod.object({
 50        method: myzod.literal('changeTurnMode'),
 51        params: myzod.object({ timed: myzod.boolean() }),
 52    }),
 53    myzod.object({
 54        method: myzod.literal('changeTurnTime'),
 55        params: myzod.object({ seconds: myzod.number() }),
 56    }),
 57    myzod.object({
 58        method: myzod.literal('addPacks'),
 59        params: myzod.object({
 60            packs: myzod.array(WordPack),
 61        }),
 62    }),
 63    myzod.object({
 64        method: myzod.literal('removePack'),
 65        params: myzod.object({ num: myzod.number() }),
 66    }),
 67    myzod.object({
 68        method: myzod.literal('changeHideBomb'),
 69        params: myzod.object({ hideBomb: myzod.boolean() }),
 70    }),
 71]);
 72
 73export type ClientNote = Infer<typeof ClientNote>;
 74export const ClientNote = myzod
 75    .object({
 76        version: myzod.number(),
 77    })
 78    .and(PartialClientNote);
 79
 80// Messages sent from server to client.
 81
 82export type RoomResponse = DeepReadonly<Infer<typeof RoomResponse>>;
 83export const RoomResponse = myzod.object({
 84    id: myzod.string().optional().nullable(),
 85    error: myzod.string().optional().nullable(),
 86});
 87
 88export type TimeResponse = DeepReadonly<Infer<typeof TimeResponse>>;
 89export const TimeResponse = myzod.object({
 90    time: myzod.date(),
 91});
 92
 93export type StateTile = DeepReadonly<Infer<typeof StateTile>>;
 94const StateTile = myzod.object({
 95    word: myzod.string(),
 96    revealed: myzod.boolean(),
 97    view: myzod
 98        .object({
 99            team: myzod.number(),
100            neutral: myzod.boolean(),
101            bomb: myzod.boolean(),
102        })
103        .optional()
104        .nullable(),
105});
106
107export type StateBoard = DeepReadonly<Infer<typeof StateBoard>>;
108const StateBoard = myzod.array(myzod.array(StateTile));
109
110export type StatePlayer = DeepReadonly<Infer<typeof StatePlayer>>;
111const StatePlayer = myzod.object({
112    playerID: myzod.string(),
113    nickname: myzod.string(),
114    spymaster: myzod.boolean(),
115});
116
117export type StateTeams = DeepReadonly<Infer<typeof StateTeams>>;
118const StateTeams = myzod.array(myzod.array(StatePlayer));
119
120export type StateTimer = DeepReadonly<Infer<typeof StateTimer>>;
121const StateTimer = myzod.object({
122    turnTime: myzod.number(),
123    turnEnd: myzod.date(),
124});
125
126export type State = DeepReadonly<Infer<typeof State>>;
127export const State = myzod.object({
128    version: myzod.number(),
129    teams: StateTeams,
130    turn: myzod.number(),
131    winner: myzod.number().optional().nullable(),
132    board: StateBoard,
133    wordsLeft: myzod.array(myzod.number()),
134    lists: myzod.array(
135        myzod.object({
136            name: myzod.string(),
137            count: myzod.number(),
138            custom: myzod.boolean(),
139            enabled: myzod.boolean(),
140        })
141    ),
142    timer: StateTimer.optional().nullable(),
143    hideBomb: myzod.boolean(),
144});
145
146export type ServerNote = DeepReadonly<Infer<typeof ServerNote>>;
147export const ServerNote = myzod.union([
148    myzod.object({
149        method: myzod.literal('state'),
150        params: State,
151    }),
152]);