import { z } from "zod" import { discriminatedUnionArray } from "@/lib/discriminatedUnion" import { removeMultipleSlashes } from "@/utils/url" import { accordionRefsSchema, accordionSchema, } from "../schemas/blocks/accordion" import { contentRefsSchema, contentSchema } from "../schemas/blocks/content" import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { linkRefsUnionSchema, linkUnionSchema, transformPageLink, } from "../schemas/pageLinks" import { systemSchema } from "../schemas/system" import type { ImageVaultAsset } from "@/types/components/imageVault" import { TrackingChannelEnum, type TrackingSDKPageData, } from "@/types/components/tracking" import { DestinationCityPageEnum } from "@/types/enums/destinationCityPage" export const destinationCityListDataSchema = z .object({ all_destination_city_page: z.object({ items: z.array( z .object({ heading: z.string(), preamble: z.string(), experiences: z .object({ destination_experiences: z.array(z.string()), }) .transform( ({ destination_experiences }) => destination_experiences ), images: z .array(z.object({ image: tempImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) .filter((image): image is ImageVaultAsset => !!image) ), url: z.string(), system: systemSchema, }) .transform((data) => { return { ...data, url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`), } }) ), }), }) .transform( ({ all_destination_city_page }) => all_destination_city_page.items?.[0] ) export const destinationCityPageContent = z .object({ __typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content), }) .merge(contentSchema) export const destinationCityPageAccordion = z .object({ __typename: z.literal( DestinationCityPageEnum.ContentStack.blocks.Accordion ), }) .merge(accordionSchema) export const blocksSchema = z.discriminatedUnion("__typename", [ destinationCityPageAccordion, destinationCityPageContent, ]) export const destinationCityPageSchema = z .object({ destination_city_page: z.object({ title: z.string(), destination_settings: z .object({ city_denmark: z.string().optional().nullable(), city_finland: z.string().optional().nullable(), city_germany: z.string().optional().nullable(), city_poland: z.string().optional().nullable(), city_norway: z.string().optional().nullable(), city_sweden: z.string().optional().nullable(), }) .transform( ({ city_denmark, city_finland, city_germany, city_norway, city_poland, city_sweden, }) => { const cities = [ city_denmark, city_finland, city_germany, city_poland, city_norway, city_sweden, ].filter((city): city is string => Boolean(city)) return { city: cities[0] } } ), heading: z.string(), preamble: z.string(), experiences: z .object({ destination_experiences: z.array(z.string()), }) .transform(({ destination_experiences }) => destination_experiences), images: z .array(z.object({ image: tempImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) .filter((image): image is ImageVaultAsset => !!image) ), has_sidepeek: z.boolean().default(false), sidepeek_button_text: z.string().default(""), sidepeek_content: z.object({ heading: z.string(), content: z.object({ json: z.any(), embedded_itemsConnection: z.object({ edges: z.array( z.object({ node: linkUnionSchema.transform((data) => { const link = transformPageLink(data) if (link) { return link } return data }), }) ), }), }), }), blocks: discriminatedUnionArray(blocksSchema.options).nullable(), system: systemSchema.merge( z.object({ created_at: z.string(), updated_at: z.string(), }) ), }), trackingProps: z.object({ url: z.string(), }), }) .transform((data) => { const destinationCityPage = data.destination_city_page const system = destinationCityPage.system const trackingUrl = data.trackingProps.url const tracking: TrackingSDKPageData = { pageId: system.uid, domainLanguage: system.locale, publishDate: system.updated_at, createDate: system.created_at, channel: TrackingChannelEnum["destination-page"], pageType: "staticcontentpage", pageName: trackingUrl, siteSections: trackingUrl, siteVersion: "new-web", } return { destinationCityPage, tracking, } }) /** REFS */ const destinationCityPageContentRefs = z .object({ __typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content), }) .merge(contentRefsSchema) const destinationCityPageAccordionRefs = z .object({ __typename: z.literal( DestinationCityPageEnum.ContentStack.blocks.Accordion ), }) .merge(accordionRefsSchema) const blocksRefsSchema = z.discriminatedUnion("__typename", [ destinationCityPageAccordionRefs, destinationCityPageContentRefs, ]) export const destinationCityPageRefsSchema = z.object({ destination_city_page: z.object({ sidepeek_content: z.object({ content: z.object({ embedded_itemsConnection: z.object({ edges: z.array( z.object({ node: linkRefsUnionSchema, }) ), }), }), }), blocks: discriminatedUnionArray(blocksRefsSchema.options).nullable(), system: systemSchema, }), })