import { metrics } from "@opentelemetry/api" import { Lang } from "@/constants/languages" import { baseUrls } from "@/constants/routes/baseUrls" import { batchRequest } from "@/lib/graphql/batchRequest" import { GetDaDeEnUrlsAccountPage, GetFiNoSvUrlsAccountPage, } from "@/lib/graphql/Query/AccountPage/AccountPage.graphql" import { GetDaDeEnUrlsCollectionPage, GetFiNoSvUrlsCollectionPage, } from "@/lib/graphql/Query/CollectionPage/CollectionPage.graphql" import { GetDaDeEnUrlsContentPage, GetFiNoSvUrlsContentPage, } from "@/lib/graphql/Query/ContentPage/ContentPage.graphql" import { GetDaDeEnUrlsCurrentBlocksPage, GetFiNoSvUrlsCurrentBlocksPage, } from "@/lib/graphql/Query/Current/LanguageSwitcher.graphql" import { GetDaDeEnUrlsDestinationCityPage, GetFiNoSvUrlsDestinationCityPage, } from "@/lib/graphql/Query/DestinationCityPage/DestinationCityPage.graphql" import { GetDaDeEnUrlsDestinationCountryPage, GetFiNoSvUrlsDestinationCountryPage, } from "@/lib/graphql/Query/DestinationCountryPage/DestinationCountryPage.graphql" import { GetDaDeEnUrlsDestinationOverviewPage, GetFiNoSvUrlsDestinationOverviewPage, } from "@/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql" import { GetDaDeEnUrlsHotelPage, GetFiNoSvUrlsHotelPage, } from "@/lib/graphql/Query/HotelPage/HotelPage.graphql" import { GetDaDeEnUrlsLoyaltyPage, GetFiNoSvUrlsLoyaltyPage, } from "@/lib/graphql/Query/LoyaltyPage/LoyaltyPage.graphql" import { GetDaDeEnUrlsStartPage, GetFiNoSvUrlsStartPage, } from "@/lib/graphql/Query/StartPage/StartPage.graphql" import { internalServerError } from "@/server/errors/trpc" import { publicProcedure, router } from "@/server/trpc" import { getUidAndContentTypeByPath } from "@/services/cms/getUidAndContentTypeByPath" import { generateTag } from "@/utils/generateTag" import { getLanguageSwitcherInput } from "./input" import { validateLanguageSwitcherData } from "./output" import { languageSwitcherAffix } from "./utils" import { PageContentTypeEnum } from "@/types/requests/contentType" import type { LanguageSwitcherData, LanguageSwitcherQueryDataRaw, } from "@/types/requests/languageSwitcher" interface LanguageSwitcherVariables { contentType: string uid: string } const meter = metrics.getMeter("trpc.contentstack.languageSwitcher") const getLanguageSwitcherCounter = meter.createCounter( "trpc.contentstack.languageSwitcher.get" ) const getLanguageSwitcherSuccessCounter = meter.createCounter( "trpc.contentstack.languageSwitcher.get-success" ) const getLanguageSwitcherFailCounter = meter.createCounter( "trpc.contentstack.languageSwitcher.get-fail" ) async function getLanguageSwitcher(options: LanguageSwitcherVariables) { const variables = { uid: options.uid } const tagsDaDeEn = [ generateTag(Lang.da, options.uid, languageSwitcherAffix), generateTag(Lang.de, options.uid, languageSwitcherAffix), generateTag(Lang.en, options.uid, languageSwitcherAffix), ] const tagsFiNoSv = [ generateTag(Lang.fi, options.uid, languageSwitcherAffix), generateTag(Lang.no, options.uid, languageSwitcherAffix), generateTag(Lang.sv, options.uid, languageSwitcherAffix), ] let daDeEnDocument = null let fiNoSvDocument = null switch (options.contentType) { case PageContentTypeEnum.accountPage: daDeEnDocument = GetDaDeEnUrlsAccountPage fiNoSvDocument = GetFiNoSvUrlsAccountPage break case PageContentTypeEnum.currentBlocksPage: daDeEnDocument = GetDaDeEnUrlsCurrentBlocksPage fiNoSvDocument = GetFiNoSvUrlsCurrentBlocksPage break case PageContentTypeEnum.loyaltyPage: daDeEnDocument = GetDaDeEnUrlsLoyaltyPage fiNoSvDocument = GetFiNoSvUrlsLoyaltyPage break case PageContentTypeEnum.hotelPage: daDeEnDocument = GetDaDeEnUrlsHotelPage fiNoSvDocument = GetFiNoSvUrlsHotelPage break case PageContentTypeEnum.contentPage: daDeEnDocument = GetDaDeEnUrlsContentPage fiNoSvDocument = GetFiNoSvUrlsContentPage break case PageContentTypeEnum.collectionPage: daDeEnDocument = GetDaDeEnUrlsCollectionPage fiNoSvDocument = GetFiNoSvUrlsCollectionPage break case PageContentTypeEnum.destinationOverviewPage: daDeEnDocument = GetDaDeEnUrlsDestinationOverviewPage fiNoSvDocument = GetFiNoSvUrlsDestinationOverviewPage break case PageContentTypeEnum.destinationCountryPage: daDeEnDocument = GetDaDeEnUrlsDestinationCountryPage fiNoSvDocument = GetFiNoSvUrlsDestinationCountryPage break case PageContentTypeEnum.destinationCityPage: daDeEnDocument = GetDaDeEnUrlsDestinationCityPage fiNoSvDocument = GetFiNoSvUrlsDestinationCityPage break case PageContentTypeEnum.startPage: daDeEnDocument = GetDaDeEnUrlsStartPage fiNoSvDocument = GetFiNoSvUrlsStartPage break default: console.error(`type: [${options.contentType}]`) console.error(`Trying to get a content type that is not supported`) throw internalServerError() } if (daDeEnDocument && fiNoSvDocument) { return await batchRequest([ { document: daDeEnDocument, variables, options: { cache: "force-cache", next: { tags: tagsDaDeEn, }, }, }, { document: fiNoSvDocument, variables, options: { cache: "force-cache", next: { tags: tagsFiNoSv, }, }, }, ]) } throw internalServerError() } export const languageSwitcherQueryRouter = router({ get: publicProcedure .input(getLanguageSwitcherInput) .query(async ({ input, ctx }) => { let uid = ctx.uid let contentType = ctx.contentType let lang = ctx.lang ?? input?.lang if (input) { const data = await getUidAndContentTypeByPath(input.pathName) uid = data.uid contentType = data.contentType ?? ctx.contentType } if (!uid || !lang) { return { lang: lang, urls: baseUrls } } getLanguageSwitcherCounter.add(1, { uid: uid, lang: lang, contentType: contentType, }) console.info( "contentstack.languageSwitcher start", JSON.stringify({ query: { uid: uid, lang: lang, contentType: contentType, }, }) ) const res = await getLanguageSwitcher({ contentType: contentType!, uid: uid, }) const urls = Object.keys(res.data).reduce( (acc, key) => { const item = res.data[key as Lang] const url = item ? item.web?.original_url || `/${key}${item.url}` : undefined return { ...acc, [key]: { url, isExternal: !!item?.web?.original_url }, } }, {} as LanguageSwitcherData ) const validatedLanguageSwitcherData = validateLanguageSwitcherData.safeParse(urls) if (!validatedLanguageSwitcherData.success) { getLanguageSwitcherFailCounter.add(1, { uid: uid, lang: lang, contentType: contentType, error_type: "validation_error", error: JSON.stringify(validatedLanguageSwitcherData.error), }) console.error( "contentstack.languageSwitcher validation error", JSON.stringify({ query: { uid: uid, lang: lang, contentType: contentType, }, error: validatedLanguageSwitcherData.error, }) ) return null } getLanguageSwitcherSuccessCounter.add(1, { uid: uid, lang: lang, contentType: contentType, }) console.info( "contentstack.languageSwitcher success", JSON.stringify({ query: { uid: uid, lang: lang, contentType: contentType, }, }) ) return { lang: lang, urls, } }), })