import { metrics } from "@opentelemetry/api" import { batchRequest } from "@/lib/graphql/batchRequest" import { GetContentPageBlocksRefs, GetContentPageRefs, } from "@/lib/graphql/Query/ContentPage/ContentPage.graphql" import { notFound } from "@/server/errors/trpc" import { generateTag, generateTagsFromSystem } from "@/utils/generateTag" import { contentPageRefsSchema } from "./output" import { TrackingChannelEnum } from "@/types/components/tracking" import { ContentPageEnum } from "@/types/enums/contentPage" import type { System } from "@/types/requests/system" import type { ContentPageRefs, GetContentPageRefsSchema, } from "@/types/trpc/routers/contentstack/contentPage" import type { Lang } from "@/constants/languages" const meter = metrics.getMeter("trpc.contentPage") // OpenTelemetry metrics: ContentPage export const getContentPageCounter = meter.createCounter( "trpc.contentstack.contentPage.get" ) const getContentPageRefsCounter = meter.createCounter( "trpc.contentstack.contentPage.get" ) const getContentPageRefsFailCounter = meter.createCounter( "trpc.contentstack.contentPage.get-fail" ) const getContentPageRefsSuccessCounter = meter.createCounter( "trpc.contentstack.contentPage.get-success" ) export async function fetchContentPageRefs(lang: Lang, uid: string) { getContentPageRefsCounter.add(1, { lang, uid }) console.info( "contentstack.contentPage.refs start", JSON.stringify({ query: { lang, uid }, }) ) const res = await batchRequest([ { document: GetContentPageRefs, variables: { locale: lang, uid }, cacheOptions: { key: generateTag(lang, uid), ttl: "max", }, }, { document: GetContentPageBlocksRefs, variables: { locale: lang, uid }, cacheOptions: { key: generateTag(lang, uid + 1), ttl: "max", }, }, ]) if (!res.data) { const notFoundError = notFound(res) getContentPageRefsFailCounter.add(1, { lang, uid, error_type: "http_error", error: JSON.stringify({ code: notFoundError.code, }), }) console.error( "contentstack.contentPage.refs not found error", JSON.stringify({ query: { lang, uid, }, error: { code: notFoundError.code }, }) ) throw notFoundError } const validatedData = contentPageRefsSchema.safeParse(res.data) if (!validatedData.success) { getContentPageRefsFailCounter.add(1, { lang, uid, error_type: "validation_error", error: JSON.stringify(validatedData.error), }) console.error( "contentstack.contentPage.refs validation error", JSON.stringify({ query: { lang, uid }, error: validatedData.error, }) ) return null } getContentPageRefsSuccessCounter.add(1, { lang, uid }) console.info( "contentstack.contentPage.refs success", JSON.stringify({ query: { lang, uid }, }) ) return validatedData.data } export function generatePageTags( validatedData: ContentPageRefs, lang: Lang ): string[] { const connections = getConnections(validatedData) return [ generateTagsFromSystem(lang, connections), generateTag(lang, validatedData.content_page.system.uid), ].flat() } export function getConnections({ content_page }: ContentPageRefs) { const connections: System["system"][] = [content_page.system] if (content_page.blocks) { content_page.blocks.forEach((block) => { switch (block.__typename) { case ContentPageEnum.ContentStack.blocks.Accordion: { if (block.accordion.length) { connections.push(...block.accordion) } break } case ContentPageEnum.ContentStack.blocks.Content: { if (block.content.length) { // TS has trouble infering the filtered types // @ts-ignore connections.push(...block.content) } } break case ContentPageEnum.ContentStack.blocks.CardsGrid: { if (block.cards_grid.length) { connections.push(...block.cards_grid) } break } case ContentPageEnum.ContentStack.blocks.DynamicContent: { if (block.dynamic_content.link) { connections.push(block.dynamic_content.link) } break } case ContentPageEnum.ContentStack.blocks.Shortcuts: { if (block.shortcuts.shortcuts.length) { connections.push(...block.shortcuts.shortcuts) } break } case ContentPageEnum.ContentStack.blocks.TextCols: { if (block.text_cols.length) { connections.push(...block.text_cols) } break } case ContentPageEnum.ContentStack.blocks.UspGrid: { if (block.usp_grid.length) { connections.push(...block.usp_grid) } break } case ContentPageEnum.ContentStack.blocks.CardsGrid: { if (block.cards_grid.length) { block.cards_grid.forEach((card) => { connections.push(card) }) } break } } }) } if (content_page.sidebar) { content_page.sidebar.forEach((block) => { switch (block.__typename) { case ContentPageEnum.ContentStack.sidebar.Content: if (block.content.length) { connections.push(...block.content) } break case ContentPageEnum.ContentStack.sidebar.JoinLoyaltyContact: if (block.join_loyalty_contact?.button) { connections.push(block.join_loyalty_contact.button) } break case ContentPageEnum.ContentStack.sidebar.ScriptedCard: if (block.scripted_card?.length) { connections.push(...block.scripted_card) } break case ContentPageEnum.ContentStack.sidebar.TeaserCard: if (block.teaser_card?.length) { connections.push(...block.teaser_card) } break case ContentPageEnum.ContentStack.sidebar.QuickLinks: if (block.shortcuts.shortcuts.length) { connections.push(...block.shortcuts.shortcuts) } break default: break } }) } return connections } const signupContentPageUid = "blt0e6bd6c4d7224f07" const signupVerifyContentPageUid = "blt3247a2a29b34a8e8" export function createPageType(uid: string): string { switch (uid) { case signupContentPageUid: return "memberprofilecreatepage" case signupVerifyContentPageUid: return "memberprofilecreatesuccesspage" default: return "staticcontentpage" } } export function createChannel(uid: string): TrackingChannelEnum { switch (uid) { case signupContentPageUid: case signupVerifyContentPageUid: return TrackingChannelEnum["scandic-friends"] default: return TrackingChannelEnum["static-content-page"] } }