import { z } from "zod" import { CampaignPageEnum } from "../../../types/campaignPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { accordionRefsSchema, accordionSchema, } from "../schemas/blocks/accordion" import { carouselCardsRefsSchema, carouselCardsSchema, } from "../schemas/blocks/carouselCards" import { essentialsBlockSchema } from "../schemas/blocks/essentials" import { campaignPageHotelListingSchema } from "../schemas/blocks/hotelListing" import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { linkConnectionRefs, linkConnectionSchema, } from "../schemas/linkConnection" import { systemSchema } from "../schemas/system" const campaignPageEssentials = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.Essentials), }) .merge(essentialsBlockSchema) const campaignPageCarouselCards = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.CarouselCards), }) .merge(carouselCardsSchema) export const campaignPageAccordion = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.Accordion), }) .merge(accordionSchema) export const campaignPageHotelListing = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.HotelListing), }) .merge(campaignPageHotelListingSchema) export const blocksSchema = z.discriminatedUnion("__typename", [ campaignPageEssentials, campaignPageCarouselCards, campaignPageAccordion, campaignPageHotelListing, ]) export const heroSchema = z.object({ image: tempImageVaultAssetSchema, heading: z.string(), theme: z.enum(["Peach", "Burgundy"]).default("Peach"), benefits: z .array(z.string()) .nullish() .transform((data) => data || []), rate_text: z .object({ bold_text: z.string().nullish(), text: z.string().nullish(), }) .nullish(), button: z .intersection(z.object({ cta: z.string() }), linkConnectionSchema) .transform((data) => { if (!data.link) { return null } return { cta: data.cta, url: data.link?.url || "", } }), }) export const includedHotelsSchema = z .object({ list_1Connection: z.object({ edges: z.array( z.object({ node: z.object({ hotel_page_id: z.string(), }), }) ), }), list_2Connection: z.object({ edges: z.array( z.object({ node: z.object({ hotel_page_id: z.string(), }), }) ), }), }) .transform((data) => { const list1HotelIds = data.list_1Connection.edges .map((edge) => edge.node.hotel_page_id) .filter(Boolean) const list2HotelIds = data.list_2Connection.edges .map((edge) => edge.node.hotel_page_id) .filter(Boolean) return [...new Set([...list1HotelIds, ...list2HotelIds])] }) export const campaignPageSchema = z .object({ campaign_page: z.object({ title: z.string(), hero: heroSchema, heading: z.string(), subheading: z.string().nullish(), included_hotels: includedHotelsSchema, preamble: z.object({ is_two_columns: z.boolean().default(false), first_column: z.string(), second_column: z.string(), }), blocks: discriminatedUnionArray(blocksSchema.options), system: systemSchema.merge( z.object({ created_at: z.string(), updated_at: z.string(), }) ), }), trackingProps: z.object({ url: z.string(), }), }) .transform((data) => { const blocks = data.campaign_page.blocks.map((block) => { if ( block.__typename === CampaignPageEnum.ContentStack.blocks.HotelListing ) { return { ...block, hotel_listing: { ...block.hotel_listing, hotelIds: data.campaign_page.included_hotels, }, } } return block }) return { ...data, campaign_page: { ...data.campaign_page, blocks: [...blocks], }, } }) /** REFS */ const campaignPageCarouselCardsRef = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.CarouselCards), }) .merge(carouselCardsRefsSchema) const campaignPageAccordionRefs = z .object({ __typename: z.literal(CampaignPageEnum.ContentStack.blocks.Accordion), }) .merge(accordionRefsSchema) const campaignPageBlockRefsItem = z.discriminatedUnion("__typename", [ campaignPageCarouselCardsRef, campaignPageAccordionRefs, ]) const heroRefsSchema = z.object({ button: linkConnectionRefs, }) export const campaignPageRefsSchema = z.object({ campaign_page: z.object({ hero: heroRefsSchema, blocks: discriminatedUnionArray( campaignPageBlockRefsItem.options ).nullable(), system: systemSchema, }), })