import { cache } from "react" import { createCounter } from "@scandic-hotels/common/telemetry" import { router } from "../../.." import { PageContentTypeEnum } from "../../../enums/contentType" import { notFound } from "../../../errors" import { GetMyPagesBreadcrumbs, GetMyPagesBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/AccountPage.graphql" import { GetCampaignOverviewPageBreadcrumbs, GetCampaignOverviewPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/CampaignOverviewPage.graphql" import { GetCampaignPageBreadcrumbs, GetCampaignPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/CampaignPage.graphql" import { GetCollectionPageBreadcrumbs, GetCollectionPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/CollectionPage.graphql" import { GetContentPageBreadcrumbs, GetContentPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/ContentPage.graphql" import { GetDestinationCityPageBreadcrumbs, GetDestinationCityPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/DestinationCityPage.graphql" import { GetDestinationCountryPageBreadcrumbs, GetDestinationCountryPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/DestinationCountryPage.graphql" import { GetDestinationOverviewPageBreadcrumbs, GetDestinationOverviewPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/DestinationOverviewPage.graphql" import { GetHotelPageBreadcrumbs, GetHotelPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/HotelPage.graphql" import { GetLoyaltyPageBreadcrumbs, GetLoyaltyPageBreadcrumbsRefs, } from "../../../graphql/Query/Breadcrumbs/LoyaltyPage.graphql" import { request } from "../../../graphql/request" import { contentstackExtendedProcedureUID } from "../../../procedures" import { generateRefsResponseTag } from "../../../utils/generateTag" import { breadcrumbsRefsSchema, breadcrumbsSchema } from "./output" import { getTags } from "./utils" import type { Lang } from "@scandic-hotels/common/constants/language" import type { BreadcrumbsRefsSchema, RawBreadcrumbsSchema, } from "../../../types/breadcrumbs" interface BreadcrumbsPageData { dataKey: keyof T refQuery: string query: string } const getBreadcrumbs = cache(async function fetchMemoizedBreadcrumbs( { dataKey, refQuery, query }: BreadcrumbsPageData, { uid, lang }: { uid: string; lang: Lang } ) { const getBreadcrumbsRefsCounter = createCounter( "trpc.contentstack", "breadcrumbs.get.refs" ) const metricsGetBreadcrumbsRefs = getBreadcrumbsRefsCounter.init({ lang, uid, }) metricsGetBreadcrumbsRefs.start() const refsResponse = await request<{ [K in keyof T]: BreadcrumbsRefsSchema }>( refQuery, { locale: lang, uid }, { key: generateRefsResponseTag(lang, uid, "breadcrumbs"), ttl: "max", } ) const validatedRefsData = breadcrumbsRefsSchema.safeParse( refsResponse.data[dataKey] ) if (!validatedRefsData.success) { metricsGetBreadcrumbsRefs.validationError(validatedRefsData.error) return [] } metricsGetBreadcrumbsRefs.success() const tags = getTags(validatedRefsData.data, lang) const getBreadcrumbsCounter = createCounter( "trpc.contentstack", "breadcrumbs.get" ) const metricsGetBreadcrumbs = getBreadcrumbsCounter.init({ lang, uid, }) metricsGetBreadcrumbs.start() const response = await request( query, { locale: lang, uid }, { key: tags, ttl: "max", } ) if (!response.data) { const notFoundError = notFound(response) metricsGetBreadcrumbs.noDataError() throw notFoundError } const validatedBreadcrumbs = breadcrumbsSchema.safeParse( response.data[dataKey] ) if (!validatedBreadcrumbs.success) { metricsGetBreadcrumbs.validationError(validatedBreadcrumbs.error) return [] } metricsGetBreadcrumbs.success() return validatedBreadcrumbs.data }) export const breadcrumbsQueryRouter = router({ get: contentstackExtendedProcedureUID.query(async ({ ctx }) => { const variables = { lang: ctx.lang, uid: ctx.uid, } switch (ctx.contentType) { case PageContentTypeEnum.accountPage: return await getBreadcrumbs<{ account_page: RawBreadcrumbsSchema }>( { dataKey: "account_page", refQuery: GetMyPagesBreadcrumbsRefs, query: GetMyPagesBreadcrumbs, }, variables ) case PageContentTypeEnum.campaignOverviewPage: return await getBreadcrumbs<{ campaign_overview_page: RawBreadcrumbsSchema }>( { dataKey: "campaign_overview_page", refQuery: GetCampaignOverviewPageBreadcrumbsRefs, query: GetCampaignOverviewPageBreadcrumbs, }, variables ) case PageContentTypeEnum.campaignPage: return await getBreadcrumbs<{ campaign_page: RawBreadcrumbsSchema }>( { dataKey: "campaign_page", refQuery: GetCampaignPageBreadcrumbsRefs, query: GetCampaignPageBreadcrumbs, }, variables ) case PageContentTypeEnum.collectionPage: return await getBreadcrumbs<{ collection_page: RawBreadcrumbsSchema }>( { dataKey: "collection_page", refQuery: GetCollectionPageBreadcrumbsRefs, query: GetCollectionPageBreadcrumbs, }, variables ) case PageContentTypeEnum.contentPage: return await getBreadcrumbs<{ content_page: RawBreadcrumbsSchema }>( { dataKey: "content_page", refQuery: GetContentPageBreadcrumbsRefs, query: GetContentPageBreadcrumbs, }, variables ) case PageContentTypeEnum.destinationOverviewPage: return await getBreadcrumbs<{ destination_overview_page: RawBreadcrumbsSchema }>( { dataKey: "destination_overview_page", refQuery: GetDestinationOverviewPageBreadcrumbsRefs, query: GetDestinationOverviewPageBreadcrumbs, }, variables ) case PageContentTypeEnum.destinationCountryPage: return await getBreadcrumbs<{ destination_country_page: RawBreadcrumbsSchema }>( { dataKey: "destination_country_page", refQuery: GetDestinationCountryPageBreadcrumbsRefs, query: GetDestinationCountryPageBreadcrumbs, }, variables ) case PageContentTypeEnum.destinationCityPage: return await getBreadcrumbs<{ destination_city_page: RawBreadcrumbsSchema }>( { dataKey: "destination_city_page", refQuery: GetDestinationCityPageBreadcrumbsRefs, query: GetDestinationCityPageBreadcrumbs, }, variables ) case PageContentTypeEnum.hotelPage: return await getBreadcrumbs<{ hotel_page: RawBreadcrumbsSchema }>( { dataKey: "hotel_page", refQuery: GetHotelPageBreadcrumbsRefs, query: GetHotelPageBreadcrumbs, }, variables ) case PageContentTypeEnum.loyaltyPage: return await getBreadcrumbs<{ loyalty_page: RawBreadcrumbsSchema }>( { dataKey: "loyalty_page", refQuery: GetLoyaltyPageBreadcrumbsRefs, query: GetLoyaltyPageBreadcrumbs, }, variables ) default: return [] } }), })