import { z } from "zod" import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { ContentPageEnum } from "../../../types/contentPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { accordionRefsSchema, accordionSchema, } from "../schemas/blocks/accordion" import { cardGridRefsSchema, cardsGridSchema, } from "../schemas/blocks/cardsGrid" import { contentRefsSchema as blockContentRefsSchema, contentSchema as blockContentSchema, } from "../schemas/blocks/content" import { dynamicContentRefsSchema, dynamicContentSchema as blockDynamicContentSchema, } from "../schemas/blocks/dynamicContent" import { contentPageHotelListingSchema } from "../schemas/blocks/hotelListing" import { shortcutsRefsSchema, shortcutsSchema, } from "../schemas/blocks/shortcuts" import { tableSchema } from "../schemas/blocks/table" import { textColsRefsSchema, textColsSchema } from "../schemas/blocks/textCols" import { uspGridRefsSchema, uspGridSchema } from "../schemas/blocks/uspGrid" import { videoBlockRefsSchema, videoBlockSchema } from "../schemas/blocks/video" import { videoCardRefsSchema, videoCardSchema, } from "../schemas/blocks/videoCard" import { dynamicContentRefsSchema as headerDynamicContentRefsSchema, dynamicContentSchema as headerDynamicContentSchema, } from "../schemas/headers/dynamicContent" import { linkAndTitleSchema, linkConnectionRefs, } from "../schemas/linkConnection" import { internalOrExternalLinkSchema } from "../schemas/pageLinks" import { contentRefsSchema as sidebarContentRefsSchema, contentSchema as sidebarContentSchema, } from "../schemas/sidebar/content" import { dynamicContentSchema as sidebarDynamicContentSchema } from "../schemas/sidebar/dynamicContent" import { joinLoyaltyContactRefsSchema, joinLoyaltyContactSchema, } from "../schemas/sidebar/joinLoyaltyContact" import { quickLinksRefschema, quickLinksSchema, } from "../schemas/sidebar/quickLinks" import { scriptedCardRefschema, scriptedCardsSchema, } from "../schemas/sidebar/scriptedCard" import { teaserCardRefschema, teaserCardsSchema, } from "../schemas/sidebar/teaserCard" import { systemSchema } from "../schemas/system" import { transformedVideoSchema, videoRefSchema } from "../schemas/video" // Block schemas export const contentPageCards = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.CardsGrid), }) .merge(cardsGridSchema) export const contentPageContent = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Content), }) .merge(blockContentSchema) export const contentPageDynamicContent = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.DynamicContent), }) .merge(blockDynamicContentSchema) export const contentPageShortcuts = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Shortcuts), }) .merge(shortcutsSchema) export const contentPageTextCols = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols), }) .merge(textColsSchema) export const contentPageUspGrid = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.UspGrid), }) .merge(uspGridSchema) export const contentPageTable = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Table), }) .merge(tableSchema) export const contentPageAccordion = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Accordion), }) .merge(accordionSchema) export const contentPageHotelListing = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.HotelListing), }) .merge(contentPageHotelListingSchema) export const contentPageVideoCard = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.VideoCard), }) .merge(videoCardSchema) export const contentPageVideo = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Video), }) .merge(videoBlockSchema) export const blocksSchema = z.discriminatedUnion("__typename", [ contentPageAccordion, contentPageCards, contentPageContent, contentPageDynamicContent, contentPageShortcuts, contentPageTable, contentPageTextCols, contentPageUspGrid, contentPageHotelListing, contentPageVideoCard, contentPageVideo, ]) export const contentPageSidebarContent = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.Content), }) .merge(sidebarContentSchema) export const contentPageSidebarDynamicContent = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.DynamicContent), }) .merge(sidebarDynamicContentSchema) export const contentPageJoinLoyaltyContact = z .object({ __typename: z.literal( ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact ), }) .merge(joinLoyaltyContactSchema) export const contentPageSidebarScriptedCard = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard), }) .merge(scriptedCardsSchema) export const contentPageSidebarTeaserCard = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard), }) .merge(teaserCardsSchema) export const contentPageSidebarQuicklinks = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks), }) .merge(quickLinksSchema) export const sidebarSchema = z.discriminatedUnion("__typename", [ contentPageSidebarContent, contentPageSidebarDynamicContent, contentPageJoinLoyaltyContact, contentPageSidebarScriptedCard, contentPageSidebarTeaserCard, contentPageSidebarQuicklinks, ]) 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, })) }) // Content Page Schema and types export const contentPageSchema = z.object({ content_page: z.object({ hero_image: transformedImageVaultAssetSchema, hero_video: transformedVideoSchema, blocks: discriminatedUnionArray(blocksSchema.options).nullable(), sidebar: discriminatedUnionArray(sidebarSchema.options).nullable(), title: z.string(), header: z.object({ heading: z.string(), preamble: z.string(), top_primary_button: internalOrExternalLinkSchema.nullish(), navigation_links: navigationLinksSchema, dynamic_content: headerDynamicContentSchema.nullish(), }), meeting_package: z .object({ show_widget: z.boolean(), location: z.string(), }) .nullable(), system: systemSchema.merge( z.object({ created_at: z.string(), updated_at: z.string(), }) ), }), trackingProps: z.object({ url: z.string(), }), }) /** REFS */ const contentPageCardsRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.CardsGrid), }) .merge(cardGridRefsSchema) const contentPageBlockContentRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Content), }) .merge(blockContentRefsSchema) const contentPageDynamicContentRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.DynamicContent), }) .merge(dynamicContentRefsSchema) const contentPageShortcutsRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Shortcuts), }) .merge(shortcutsRefsSchema) const contentPageTextColsRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols), }) .merge(textColsRefsSchema) const contentPageUspGridRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.UspGrid), }) .merge(uspGridRefsSchema) const contentPageAccordionRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Accordion), }) .merge(accordionRefsSchema) const contentPageVideoCardRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.VideoCard), }) .merge(videoCardRefsSchema) const contentPageVideoRefs = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.blocks.Video), }) .merge(videoBlockRefsSchema) const contentPageBlockRefsItem = z.discriminatedUnion("__typename", [ contentPageAccordionRefs, contentPageBlockContentRefs, contentPageShortcutsRefs, contentPageCardsRefs, contentPageDynamicContentRefs, contentPageTextColsRefs, contentPageUspGridRefs, contentPageVideoCardRefs, contentPageVideoRefs, ]) const contentPageSidebarContentRef = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.Content), }) .merge(sidebarContentRefsSchema) const contentPageSidebarJoinLoyaltyContactRef = z .object({ __typename: z.literal( ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact ), }) .merge(joinLoyaltyContactRefsSchema) const contentPageSidebarScriptedCardRef = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.ScriptedCard), }) .merge(scriptedCardRefschema) const contentPageSidebarTeaserCardRef = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.TeaserCard), }) .merge(teaserCardRefschema) const contentPageSidebarQuickLinksRef = z .object({ __typename: z.literal(ContentPageEnum.ContentStack.sidebar.QuickLinks), }) .merge(quickLinksRefschema) const contentPageSidebarRefsItem = z.discriminatedUnion("__typename", [ contentPageSidebarContentRef, contentPageSidebarJoinLoyaltyContactRef, contentPageSidebarScriptedCardRef, contentPageSidebarTeaserCardRef, contentPageSidebarQuickLinksRef, ]) const contentPageHeaderRefs = z.object({ navigation_links: z.array(linkConnectionRefs), top_primary_button: linkConnectionRefs.nullable(), dynamic_content: headerDynamicContentRefsSchema.nullish(), }) export const contentPageRefsSchema = z.object({ content_page: z.object({ hero_video: videoRefSchema.nullish(), header: contentPageHeaderRefs, blocks: discriminatedUnionArray( contentPageBlockRefsItem.options ).nullable(), sidebar: discriminatedUnionArray( contentPageSidebarRefsItem.options ).nullable(), system: systemSchema, }), })