diff --git a/package.json b/package.json index 29d0301..d4b7ea2 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-screen-wake-lock": "^3.0.2", - "styled-components": "^6.0.7" + "styled-components": "^6.0.7", + "zod": "^3.22.4" }, "devDependencies": { "@emotion/react": "^11.11.1", diff --git a/src/Providers/GlobalSettingsProvider.tsx b/src/Providers/GlobalSettingsProvider.tsx index b17ed6e..eaace51 100644 --- a/src/Providers/GlobalSettingsProvider.tsx +++ b/src/Providers/GlobalSettingsProvider.tsx @@ -5,7 +5,13 @@ import { GlobalSettingsContextType, } from '../Contexts/GlobalSettingsContext'; import { useAnalytics } from '../Hooks/useAnalytics'; -import { InitialGameSettings, Orientation, Settings } from '../Types/Settings'; +import { + GameFormat, + InitialGameSettings, + InitialGameSettingsSchema, + Orientation, + Settings, +} from '../Types/Settings'; export const GlobalSettingsProvider = ({ children, @@ -33,7 +39,7 @@ export const GlobalSettingsProvider = ({ startingLifeTotal: 40, useCommanderDamage: true, orientation: Orientation.Landscape, - gameFormat: 'commander', + gameFormat: GameFormat.Commander, }; setInitialSettings({ ...defaultSettings, ...initialGameSettings }); }; @@ -45,9 +51,18 @@ export const GlobalSettingsProvider = ({ ); useEffect(() => { + //parse existing game settings with zod schema + const parsedInitialGameSettings = + InitialGameSettingsSchema.safeParse(initialGameSettings); + + if (!parsedInitialGameSettings.success) { + localStorage.setItem('initialGameSettings', ''); + return; + } + localStorage.setItem( 'initialGameSettings', - JSON.stringify(initialGameSettings) + JSON.stringify(parsedInitialGameSettings.data) ); }, [initialGameSettings]); diff --git a/src/Types/Settings.ts b/src/Types/Settings.ts index cc1c8e5..8e5499b 100644 --- a/src/Types/Settings.ts +++ b/src/Types/Settings.ts @@ -1,9 +1,17 @@ +import { z } from 'zod'; + export enum Orientation { OppositeLandscape = 'opposite-landscape', Landscape = 'landscape', Portrait = 'portrait', } +export enum GameFormat { + Commander = 'commander', + Standard = 'standard', + TwoHeadedGiant = 'two-headed-giant', +} + export type Settings = { keepAwake: boolean; showStartingPlayer: boolean; @@ -18,4 +26,10 @@ export type InitialGameSettings = { orientation: Orientation; }; -type GameFormat = 'commander' | 'standard' | 'two-headed-giant'; +export const InitialGameSettingsSchema = z.object({ + startingLifeTotal: z.number().min(1).max(200).default(20), + useCommanderDamage: z.boolean().default(false), + gameFormat: z.nativeEnum(GameFormat).optional(), + numberOfPlayers: z.number().min(1).max(6).default(2), + orientation: z.nativeEnum(Orientation).default(Orientation.Landscape), +}); diff --git a/yarn.lock b/yarn.lock index f58e4cb..afa13a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6988,3 +6988,8 @@ zip-stream@^4.1.0: archiver-utils "^3.0.4" compress-commons "^4.1.2" readable-stream "^3.6.0" + +zod@^3.22.4: + version "3.22.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" + integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==