import { z } from "zod" import { CampaignOverviewPageEnum } from "../../../types/campaignOverviewPageEnum" import { CampaignPageEnum } from "../../../types/campaignPage" import { ContentEnum } from "../../../types/content" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { campaignPageHotelListing, heroSchema, includedHotelsSchema, } from "../campaignPage/output" import { promoHeroSchema } from "../promoCampaignPage/output" import { allCampaignsSchema } from "../schemas/blocks/allCampaigns" import { carouselCardsSchema } from "../schemas/blocks/carouselCards" import { campaignOverviewPageHotelListingSchema } from "../schemas/blocks/hotelListing" import { linkAndTitleSchema } 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 topCampaign = z.object({ typename: z .literal(ContentEnum.blocks.CampaignPage) .optional() .default(ContentEnum.blocks.CampaignPage), hero: heroSchema, included_hotels: includedHotelsSchema, blocks: discriminatedUnionArray(campaignPageBlocksSchema.options), url: z.string(), }) const topCampaignSchema = z .object({ __typename: z.literal(ContentEnum.blocks.CampaignPage), }) .merge(topCampaign) export const transformTopCampaign = (data: z.infer) => { const { blocks, included_hotels, ...rest } = data const hotelListingBlock = blocks?.find( (block) => block.__typename === CampaignPageEnum.ContentStack.blocks.HotelListing ) return { ...rest, __typename: ContentEnum.blocks.CampaignPage, hotel_listing: { heading: hotelListingBlock?.hotel_listing.heading || "", hotelIds: included_hotels, }, } } export const transformedTopCampaign = topCampaignSchema.transform(transformTopCampaign) const topPromoCampaign = z.object({ typename: z .literal(ContentEnum.blocks.PromoCampaignPage) .optional() .default(ContentEnum.blocks.PromoCampaignPage), promo_hero: promoHeroSchema.nullish(), url: z.string(), }) const topPromoCampaignSchema = z .object({ __typename: z.literal(ContentEnum.blocks.PromoCampaignPage), }) .merge(topPromoCampaign) export const transformTopPromoCampaign = ( data: z.infer ) => { const { promo_hero, ...rest } = data return { ...rest, __typename: ContentEnum.blocks.PromoCampaignPage, hero: promo_hero, } } export const transformedTopPromoCampaign = topPromoCampaignSchema.transform( transformTopPromoCampaign ) 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: z.discriminatedUnion("__typename", [ topCampaignSchema, topPromoCampaignSchema, ]), }) .transform((data) => { if (data.node.__typename === ContentEnum.blocks.CampaignPage) { return { node: transformTopCampaign(data.node), } } return { node: transformTopPromoCampaign(data.node), } }) ), }), }), 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(), }), })