From 79e567c9d1655902465ea6574a883abdd411fd24 Mon Sep 17 00:00:00 2001 From: MattIPv4 Date: Tue, 10 Dec 2024 01:48:22 +0000 Subject: [PATCH] Add Zod schema for Ambassador --- src/ambassadors/core.ts | 93 ++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/src/ambassadors/core.ts b/src/ambassadors/core.ts index a4133d4..ccad01b 100644 --- a/src/ambassadors/core.ts +++ b/src/ambassadors/core.ts @@ -1,40 +1,61 @@ -import type { IUCNStatus } from "../iucn"; -import type { EnclosureKey } from "../enclosures"; -import type { PartialDateString, Nullable } from "../types"; -import type { Class } from "./classification"; -import lifespans, { type Lifespan } from "./lifespans"; +import { z } from "zod"; -export type Ambassadors = typeof ambassadors; +import { isIUCNStatus } from "../iucn"; +import { isEnclosureKey } from "../enclosures"; +import { isPartialDateString } from "../types"; +import { isClass } from "./classification"; +import lifespans, { lifespanSchema } from "./lifespans"; -export type AmbassadorKey = keyof Ambassadors; +export const ambassadorSchema = z.object({ + name: z.string(), + alternate: z.array(z.string()).readonly(), + commands: z.array(z.string()).readonly(), + class: z.string().refine(isClass).nullable(), + species: z.string(), + scientific: z.string(), + sex: z.enum(["Male", "Female"]).nullable(), + birth: z.string().refine(isPartialDateString).nullable(), + arrival: z.string().refine(isPartialDateString).nullable(), + retired: z.string().refine(isPartialDateString).nullable(), + iucn: z.object({ + id: z.number().nullable(), + status: z.string().refine(isIUCNStatus), + }), + enclosure: z.string().refine(isEnclosureKey), + story: z.string(), + mission: z.string(), + native: z.object({ + text: z.string(), + source: z.string(), + }), + lifespan: lifespanSchema, + clips: z + .array( + z.object({ + id: z.string(), + caption: z.string(), + }), + ) + .readonly(), + homepage: z + .object({ + title: z.string(), + description: z.string(), + }) + .nullable(), + plush: z + .union([ + z.object({ + link: z.string(), + }), + z.object({ + soon: z.string(), + }), + ]) + .nullable(), +}); -export type Ambassador = { - name: string; - alternate: Readonly; - commands: Readonly; - class: Class; - species: string; - scientific: string; - sex: Nullable<"Male" | "Female">; - birth: Nullable; - arrival: Nullable; - retired: Nullable; - iucn: { - id: Nullable; - status: IUCNStatus; - }; - enclosure: EnclosureKey; - story: string; - mission: string; - native: { - text: string; - source: string; - }; - lifespan: Lifespan; - clips: Readonly<{ id: string; caption: string }[]>; - homepage: Nullable<{ title: string; description: string }>; - plush: Nullable<{ link: string } | { soon: string }>; -}; +export type Ambassador = z.infer; const ambassadors = { // Active ambassadors @@ -1271,6 +1292,10 @@ const ambassadors = { }, } as const satisfies Record; +export type Ambassadors = typeof ambassadors; + +export type AmbassadorKey = keyof Ambassadors; + const ambassadorKeys = Object.keys(ambassadors) as AmbassadorKey[]; export const isAmbassadorKey = (str: string): str is AmbassadorKey =>