import { dt } from "@scandic-hotels/common/dt" import { createCounter } from "@scandic-hotels/common/telemetry" import { notFoundError } from "../../../errors" import { GetCampaignPagesByHotelUid, GetCampaignPagesByHotelUidRefs, } from "../../../graphql/Query/CampaignPage/CampaignPagesByHotelUid.graphql" import { request } from "../../../graphql/request" import { CampaignPageEnum, type CampaignPageRefs, } from "../../../types/campaignPage" import { generateRefsResponseTag, generateTag, generateTagsFromSystem, } from "../../../utils/generateTag" import { campaignPagesByHotelUidRefsSchema, campaignPagesByHotelUidSchema, } from "./output" import type { Lang } from "@scandic-hotels/common/constants/language" import type { CarouselCardsBlock, GetCampaignPagesByHotelUidData, GetCampaignPagesByHotelUidRefsData, } from "../../../types/campaignPage" import type { System } from "../schemas/system" export function generatePageTags( validatedData: CampaignPageRefs, lang: Lang ): string[] { const connections = getConnections(validatedData) return [ generateTagsFromSystem(lang, connections), generateTag(lang, validatedData.campaign_page.system.uid), ].flat() } export function getConnections({ campaign_page }: CampaignPageRefs) { const connections: System["system"][] = [campaign_page.system] if (campaign_page.blocks) { campaign_page.blocks.forEach((block) => { switch (block.__typename) { case CampaignPageEnum.ContentStack.blocks.CarouselCards: { block.carousel_cards.card_groups.forEach((group) => { group.cardConnection.edges.forEach(({ node }) => { connections.push(node.system) }) }) break } case CampaignPageEnum.ContentStack.blocks.Accordion: { if (block.accordion.length) { connections.push(...block.accordion.filter((c) => !!c)) } break } } }) } return connections } export function getCarouselCardsBlockWithBookingCodeLinks( block: CarouselCardsBlock, bookingCode: string | null ): CarouselCardsBlock { if (!bookingCode) { return block } const { link, cards, ...carousel_cards } = block.carousel_cards return { ...block, carousel_cards: { ...carousel_cards, link: link ? { ...link, href: `${link.href}?bookingCode=${bookingCode}`, } : undefined, cards: cards.map(({ link, ...card }) => ({ ...card, link: link ? { ...link, href: `${link.href}?bookingCode=${bookingCode}`, } : undefined, })), }, } } export async function getCampaignPagesByHotelPageUid( hotelPageUid: string, lang: Lang ) { const today = dt().format("YYYY-MM-DD") const getCampaignPagesByHotelUidRefsCounter = createCounter( "trpc.contentstack.campaignPage.byHotelUid.get.refs" ) const metricsGetCampaignPagesByHotelUidRefs = getCampaignPagesByHotelUidRefsCounter.init({ lang, hotelPageUid, today, }) metricsGetCampaignPagesByHotelUidRefs.start() const refsTag = generateRefsResponseTag( lang, `${hotelPageUid}-${today}`, "hotel_page_campaigns" ) const variables = { locale: lang, hotelPageUid, today, } const refsResponse = await request( GetCampaignPagesByHotelUidRefs, variables, { key: refsTag, ttl: "1d", } ) if (!refsResponse.data) { metricsGetCampaignPagesByHotelUidRefs.noDataError() throw notFoundError({ message: "GetCampaignPagesByHotelUidRefs returned no data", errorDetails: variables, }) } const validatedRefsData = campaignPagesByHotelUidRefsSchema.safeParse( refsResponse.data ) if (!validatedRefsData.success) { metricsGetCampaignPagesByHotelUidRefs.validationError( validatedRefsData.error ) return null } metricsGetCampaignPagesByHotelUidRefs.success() const tags = generateTagsFromSystem(lang, validatedRefsData.data) const getCampaignPagesByHotelUidCounter = createCounter( "trpc.contentstack.campaignPage.byHotelUid.get" ) const metricsGetCampaignPagesByHotelUid = getCampaignPagesByHotelUidCounter.init({ lang, hotelPageUid, today, }) metricsGetCampaignPagesByHotelUid.start() const response = await request( GetCampaignPagesByHotelUid, { locale: lang, hotelPageUid, today, }, { key: [...tags, refsTag], ttl: "1d", } ) if (!response.data) { metricsGetCampaignPagesByHotelUid.noDataError() return null } const validatedResponse = campaignPagesByHotelUidSchema.safeParse( response.data ) if (!validatedResponse.success) { metricsGetCampaignPagesByHotelUid.validationError(validatedResponse.error) return null } metricsGetCampaignPagesByHotelUid.success() return validatedResponse.data }