import { z } from "zod" import { CampaignOverviewPageEnum } from "../../../types/campaignOverviewPageEnum" import { CampaignPageEnum } from "../../../types/campaignPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { campaignPageHotelListing, heroSchema, includedHotelsSchema, } from "../campaignPage/output" import { allCampaignsRefsSchema, allCampaignsSchema, } from "../schemas/blocks/allCampaigns" import { carouselCardsRefsSchema, carouselCardsSchema, } from "../schemas/blocks/carouselCards" import { campaignOverviewPageHotelListingSchema } from "../schemas/blocks/hotelListing" import { linkAndTitleSchema, linkConnectionRefs, } from "../schemas/linkConnection" import { systemSchema } from "../schemas/system" const navigationLinksSchema = z .array(linkAndTitleSchema) .nullable() .transform((data) => { if (!data) { return null } return data .filter((item) => !!item.link) .map((item) => ({ url: item.link!.url, title: item.title || item.link!.title, })) }) export const campaignPageBlocksSchema = z.discriminatedUnion("__typename", [ campaignPageHotelListing, ]) const topCampaignSchema = z .object({ hero: heroSchema, included_hotels: includedHotelsSchema, blocks: discriminatedUnionArray(campaignPageBlocksSchema.options), url: z.string(), }) .transform((data) => { const { blocks, included_hotels, ...rest } = data const hotelListingBlock = blocks.find( (block) => block.__typename === CampaignPageEnum.ContentStack.blocks.HotelListing ) return { ...rest, hotel_listing: { heading: hotelListingBlock?.hotel_listing.heading || "", hotelIds: included_hotels, }, } }) const campaignOverviewPageCarouselCards = z .object({ __typename: z.literal( CampaignOverviewPageEnum.ContentStack.blocks.CarouselCards ), }) .merge(carouselCardsSchema) const campaignOverviewPageAllCampaigns = z .object({ __typename: z.literal( CampaignOverviewPageEnum.ContentStack.blocks.AllCampaigns ), }) .merge(allCampaignsSchema) export const campaignOverviewPageHotelListing = z .object({ __typename: z.literal( CampaignOverviewPageEnum.ContentStack.blocks.HotelListing ), }) .merge(campaignOverviewPageHotelListingSchema) export const blocksSchema = z.discriminatedUnion("__typename", [ campaignOverviewPageAllCampaigns, campaignOverviewPageCarouselCards, campaignOverviewPageHotelListing, ]) export const campaignOverviewPageSchema = z.object({ campaign_overview_page: z .object({ title: z.string(), header: z.object({ heading: z.string(), preamble: z.string(), navigation_links: navigationLinksSchema, }), top_campaign_block: z.object({ heading: z.string().nullish(), campaignConnection: z.object({ edges: z.array( z.object({ node: topCampaignSchema, }) ), }), }), blocks: discriminatedUnionArray(blocksSchema.options), system: systemSchema.merge( z.object({ created_at: z.string(), updated_at: z.string(), }) ), }) .transform((data) => { const { top_campaign_block, ...rest } = data return { ...rest, topCampaign: { heading: top_campaign_block.heading, campaign: top_campaign_block.campaignConnection.edges.map( ({ node }) => node )[0], }, } }), trackingProps: z.object({ url: z.string(), }), }) /** REFS */ const campaignOverviewPageHeaderRefs = z.object({ navigation_links: z.array(linkConnectionRefs), }) const campaignOverviewPageCarouselCardsRef = z .object({ __typename: z.literal( CampaignOverviewPageEnum.ContentStack.blocks.CarouselCards ), }) .merge(carouselCardsRefsSchema) const campaignOverviewPageAllCampaignsRef = z .object({ __typename: z.literal( CampaignOverviewPageEnum.ContentStack.blocks.AllCampaigns ), }) .merge(allCampaignsRefsSchema) const blockRefsSchema = z.discriminatedUnion("__typename", [ campaignOverviewPageAllCampaignsRef, campaignOverviewPageCarouselCardsRef, ]) export const campaignOverviewPageRefsSchema = z.object({ campaign_overview_page: z.object({ header: campaignOverviewPageHeaderRefs, top_campaign_block: z.object({ campaignConnection: z.object({ edges: z.array( z.object({ node: z.object({ system: systemSchema, }), }) ), }), }), blocks: discriminatedUnionArray(blockRefsSchema.options).nullable(), system: systemSchema, }), })