import { createCounter } from "@scandic-hotels/common/telemetry" import { GetDestinationCityListData } from "../../../graphql/Query/DestinationCityPage/DestinationCityListData.graphql" import { GetCountryPageUrls } from "../../../graphql/Query/DestinationCountryPage/DestinationCountryPageUrl.graphql" import { request } from "../../../graphql/request" import { ApiCountry } from "../../../types/country" import { generateTag } from "../../../utils/generateTag" import { getCitiesByCountry } from "../../hotels/services/getCitiesByCountry" import { destinationCityListDataSchema } from "../destinationCityPage/output" import { countryPageUrlsSchema } from "./output" import type { Country } from "@scandic-hotels/common/constants/country" import type { Lang } from "@scandic-hotels/common/constants/language" import type { GetDestinationCityListDataResponse } from "../../../types/destinationCityPage" import type { GetCountryPageUrlsData } from "../../../types/destinationCountryPage" export async function getCityListDataByCityIdentifier( lang: Lang, cityIdentifier: string ) { const getCityListDataCounter = createCounter( "trpc.contentstack.cityListData.get" ) const metricsGetCityListData = getCityListDataCounter.init({ lang, cityIdentifier, }) metricsGetCityListData.start() const response = await request( GetDestinationCityListData, { locale: lang, cityIdentifier, }, { key: generateTag(lang, `city_list_data:${cityIdentifier}`), ttl: "max", } ) if (!response.data) { metricsGetCityListData.dataError( `Failed to get destination city page for cityIdentifier: ${cityIdentifier}` ) return null } const validatedResponse = destinationCityListDataSchema.safeParse( response.data ) if (!validatedResponse.success) { metricsGetCityListData.validationError(validatedResponse.error) return null } metricsGetCityListData.success() return validatedResponse.data } export async function getCityPages( lang: Lang, serviceToken: string, country: Country ) { const apiCountry = ApiCountry[lang][country] const cities = await getCitiesByCountry({ countries: [apiCountry], lang, serviceToken, }) const publishedCities = cities[apiCountry].filter((city) => city.isPublished) // It happens we receive duplicate cities with the same city identifier. // Remove duplicate cities based on city identifier const uniquePublishedCities = publishedCities.filter( (city, index, self) => index === self.findIndex((c) => c.cityIdentifier === city.cityIdentifier) ) const cityPages = await Promise.all( uniquePublishedCities.map(async (city) => { if (!city.cityIdentifier) { return null } const data = await getCityListDataByCityIdentifier( lang, city.cityIdentifier ) return data ? { ...data, cityName: city.name, cityIdentifier: city.cityIdentifier } : null }) ) return cityPages .flat() .filter((city): city is NonNullable => !!city) } export async function getCountryPageUrls(lang: Lang) { const getCountryPageUrlsCounter = createCounter( "trpc.contentstack.getCountryPageUrls" ) const metricsGetCountryPageUrls = getCountryPageUrlsCounter.init({ lang }) metricsGetCountryPageUrls.start() const tag = `${lang}:country_page_urls` const response = await request( GetCountryPageUrls, { locale: lang, }, { key: tag, ttl: "max", } ) if (!response.data) { metricsGetCountryPageUrls.dataError( `Failed to get country pages for lang: ${lang}` ) return [] } const validatedCountryPageUrls = countryPageUrlsSchema.safeParse( response.data ) if (!validatedCountryPageUrls.success) { metricsGetCountryPageUrls.validationError(validatedCountryPageUrls.error) return [] } metricsGetCountryPageUrls.success() return validatedCountryPageUrls.data }