{"version":3,"file":"content-transformers-JBP5cbT0.js","sources":["../../../../scripts/services/transformers/content-transformers.ts"],"sourcesContent":["import { tourBrandSupplierTypesRestricted } from \"config/collections\";\r\nimport { DotCMSFeaturedContent, DotCMSRealTravelerStories, DotCMSSponsoredCarouselSlideResponse } from \"interfaces/responses/dotcms-responses\";\r\nimport { CruisesSearchResponse, HotelsSearchResponse, ToursSearchResponse } from \"interfaces/responses/product-search-responses\";\r\nimport { ContentTile, ProductCard } from \"interfaces/card\";\r\nimport { CarouselSlide, RealTravelerStoriesCarousel, RealTravelerStoriesCarouselSlide } from \"interfaces/carousel\";\r\nimport { baseImageUrl, baseUrl } from \"services/cms/cms\";\r\nimport { extractCategories } from \"services/helpers/categories\";\r\nimport { formatLocation } from \"services/helpers/destinations\";\r\nimport { generateCmsImageUrl, generateMediaServerImageUrl } from \"services/helpers/images\";\r\nimport { formatProductDateRange, translateToConsumerUrl } from \"services/transformers/products\";\r\nimport { deriveWanderlistIdFromUrl, getHeartTypeByUrl } from \"services/wanderlist\";\r\nimport { cobrandLink, slugify } from \"virtuoso-shared-web-ui\";\r\n\r\n/**\r\n * Determines the Wanderlist heart info and other optional data and returns a transformed CarouselSlide\r\n * @param slide\r\n * @returns\r\n */\r\nexport function transformCmsFeatureCarouselSlideToCarouselSlide(slide: DotCMSSponsoredCarouselSlideResponse): CarouselSlide | null {\r\n    if (!slide || !slide.link || !slide.headline || !slide.image) {\r\n        return null;\r\n    }\r\n\r\n    let wlHeartType = getHeartTypeByUrl(slide.link);\r\n    let wlIdentifier = deriveWanderlistIdFromUrl(slide.link); // Will be blank if it's an article, MEID if it's a product, the link itself otherwise\r\n\r\n    // Broadstreet/interim redirect links or other non-product links use actualLink for the \"real\" destination\r\n    if (slide.actualLink) {\r\n        wlHeartType = getHeartTypeByUrl(slide.actualLink);\r\n        wlIdentifier = deriveWanderlistIdFromUrl(slide.actualLink);\r\n    }\r\n\r\n    // For articles only, use the provided ID (article IDs can't be derived from the URL alone)\r\n    // Otherwise, wlIdentifier remains blank and the heart won't display\r\n    if (wlHeartType === \"article\" && slide.associatedId) {\r\n        wlIdentifier = slide.associatedId;\r\n    }\r\n\r\n    // Append the campaignID to the link URL if it's present (and not already in the URL)\r\n    let campaignSuffix = \"\";\r\n    if (slide.broadstreetCampaignId) {\r\n        if (!(slide.link).includes(`/c${slide.broadstreetCampaignId}`)) {\r\n            campaignSuffix = `/c${slide.broadstreetCampaignId}`;\r\n        }\r\n    }\r\n\r\n    return {\r\n        broadstreetAdId: slide.adId || \"\",\r\n        broadstreetCampaignId: slide.broadstreetCampaignId || \"\",\r\n        categories: (slide.categories) ? extractCategories(slide.categories) : [],\r\n        heartType: wlHeartType,\r\n        identifier: wlIdentifier,\r\n        imageCropFocus: (slide.imageCropFocus) ? slide.imageCropFocus : \"center\",\r\n        imageUrl: generateCmsImageUrl(slide.image, { queryParams: { language_id: slide.languageId } }),\r\n        logoUrl: (slide.logo) ? baseImageUrl + slide.logo : \"\",\r\n        slideType: slide.slideType || \"generic\",\r\n        sponsoredText: (slide.sponsoredText) ? slide.sponsoredText : \"\",\r\n        title: slide.headline,\r\n        url: cobrandLink(slide.link + campaignSuffix)\r\n    };\r\n}\r\n\r\n\r\n/**\r\n * Takes a dotCMS FeaturedContent object and returns the transformed ContentTile.\r\n * @param FeaturedContent\r\n */\r\nexport function transformCmsFeaturedContentToContentTile(featuredContent: DotCMSFeaturedContent): ContentTile {\r\n    return {\r\n        categories: extractCategories(featuredContent.categories || []),\r\n        identifier: featuredContent.associatedId || featuredContent.identifier,\r\n        imageCropFocus: featuredContent.imageCropFocus || \"center\",\r\n        imageUrl: generateCmsImageUrl(featuredContent.image),\r\n        sponsoredText: featuredContent.sponsoredText || \"\",\r\n        title: featuredContent.headline,\r\n        url: cobrandLink(featuredContent.link),\r\n        tileLayout: (featuredContent.tileLayout === \"2col\") ? \"-twocol\" : \"\"\r\n    };\r\n}\r\n\r\n\r\n/**\r\n * Separate function to return the data for the Vue component since we can't splat it directly all the time\r\n * @param componentData\r\n */\r\nexport function transformRTSCarouselContent(componentData: DotCMSRealTravelerStories): RealTravelerStoriesCarousel {\r\n\r\n    const slides: RealTravelerStoriesCarouselSlide[] = [];\r\n\r\n    for (let slideIndex = 1; slideIndex <= 6; slideIndex++) {\r\n        const quoteKey = `quote${slideIndex}` as keyof DotCMSRealTravelerStories;\r\n        const imageKey = `image${slideIndex}` as keyof DotCMSRealTravelerStories;\r\n        const imageCropFocusKey = `image${slideIndex}CropFocus` as keyof DotCMSRealTravelerStories;\r\n        const attributionKey = `attribution${slideIndex}` as keyof DotCMSRealTravelerStories;\r\n        const linkKey = `link${slideIndex}` as keyof DotCMSRealTravelerStories;\r\n\r\n        if (componentData[quoteKey] && componentData[imageKey]) {\r\n            slides.push({\r\n                attribution: componentData[attributionKey],\r\n                imageCropFocus: componentData[imageCropFocusKey],\r\n                imageUrl: generateCmsImageUrl(componentData[imageKey]),\r\n                link: cobrandLink(componentData[linkKey]),\r\n                quote: componentData[quoteKey]\r\n            });\r\n        }\r\n    }\r\n\r\n    return {\r\n        buttonLink: componentData.buttonLink,\r\n        buttonText: componentData.buttonText,\r\n        cobrandedContent: componentData.cobrandedContent,\r\n        cobrandedHeader: componentData.cobrandedHeader,\r\n        content: componentData.content,\r\n        header: componentData.header,\r\n        slides: slides\r\n    };\r\n}\r\n\r\n\r\n/**\r\n * Transform hotel product response data into shape required for ProductCard\r\n * @param hotel\r\n */\r\nexport function transformHotelSearchResponseToProductCard(hotel: HotelsSearchResponse): ProductCard {\r\n\r\n    const product: ProductCard = {\r\n        company: \"\", // Don't know which property yet\r\n        id: hotel.id,\r\n        imageUrl:\r\n            generateMediaServerImageUrl(hotel.defaultImageUrl, {\r\n                width: 500\r\n            }) ||\r\n            baseUrl + \"/images/products/coming-soon-suitcase.jpg\",\r\n        link: cobrandLink(translateToConsumerUrl(hotel.detailUrl)),\r\n        location: formatLocation(hotel.city, hotel.state, hotel.country),\r\n        name: hotel.name,\r\n        neighborhood: hotel.neighborhood,\r\n        wanderlistName: hotel.country\r\n    };\r\n\r\n    return product;\r\n}\r\n\r\n\r\n/**\r\n * Transform cruise product response data into shape required for ProductCard\r\n * @param cruise\r\n */\r\nexport function transformCruiseSearchResponseToProductCard(cruise: CruisesSearchResponse): ProductCard {\r\n\r\n    const product: ProductCard = {\r\n        brandPageUrl: cobrandLink(`/travel/luxury-cruises/cruise-lines/${cruise.supplierId}/${slugify(cruise.company)}`),\r\n        company: cruise.company,\r\n        cruiseId: cruise.cruiseId,\r\n        id: cruise.id,\r\n        imageUrl:\r\n            generateMediaServerImageUrl(cruise.defaultImageUrl, {\r\n                width: 500\r\n            }) ||\r\n            baseUrl + \"/images/products/coming-soon-suitcase.jpg\",\r\n        link: cobrandLink(translateToConsumerUrl(cruise.detailUrl)),\r\n        location: `${cruise.startLocation} to ${cruise.endLocation}`,\r\n        name: cruise.name,\r\n        travelLength: cruise.travelLength,\r\n        shipName: cruise.ship,\r\n        shipUrl: cruise.ship !== \"Varies by Departure\" && cruise.shipId\r\n            ? cobrandLink(`/travel/luxury-cruises/ships/${cruise.shipId}/${slugify(cruise.ship)}`)\r\n            : \"\"\r\n    };\r\n\r\n    if (cruise.startDate && cruise.endDate) {\r\n        product.dates = formatProductDateRange(\r\n            cruise.startDate,\r\n            cruise.endDate\r\n        );\r\n    }\r\n\r\n    return product;\r\n}\r\n\r\n\r\n/**\r\n * Transform tour product response data into shape required for ProductCard\r\n * @param tour\r\n */\r\nexport function transformTourSearchResponseToProductCard(tour: ToursSearchResponse): ProductCard {\r\n\r\n\r\n    const startLocation = JSON.parse(tour.startCityStateCountry);\r\n    const endLocation = JSON.parse(tour.endCityStateCountry);\r\n\r\n    const product: ProductCard = {\r\n        company: tour.company,\r\n        dates: formatProductDateRange(tour.actualStartDate, tour.endDate, tour.type),\r\n        id: tour.id,\r\n        imageUrl:\r\n            generateMediaServerImageUrl(tour.defaultImageUrl, {\r\n                width: 500\r\n            }) ||\r\n            baseUrl + \"/images/products/coming-soon-suitcase.jpg\",\r\n        link: cobrandLink(translateToConsumerUrl(tour.detailUrl)),\r\n        location: tour.startLocation !== tour.endLocation\r\n            ? `${formatLocation(\r\n                startLocation.City,\r\n                startLocation.State,\r\n                startLocation.Country\r\n            )} to ${formatLocation(\r\n                endLocation.City,\r\n                endLocation.State,\r\n                endLocation.Country\r\n            )}`\r\n            : formatLocation(\r\n                startLocation.City,\r\n                startLocation.State,\r\n                startLocation.Country\r\n            ),\r\n        name: tour.name,\r\n        travelLength: tour.travelLength,\r\n        wanderlistName: (tour.type === \"Day Tour\") ? startLocation.City : \"\"\r\n    };\r\n\r\n    if (tourBrandSupplierTypesRestricted.includes(tour.companyType)) {\r\n        product.brandPageUrl = cobrandLink(`/travel/luxury-tours/tour-operators/${tour.supplierId}/${slugify(tour.company)}`);\r\n    }\r\n\r\n    return product;\r\n}\r\n\r\n"],"names":["transformCmsFeatureCarouselSlideToCarouselSlide","slide","wlHeartType","getHeartTypeByUrl","wlIdentifier","deriveWanderlistIdFromUrl","campaignSuffix","extractCategories","generateCmsImageUrl","baseImageUrl","cobrandLink","transformCmsFeaturedContentToContentTile","featuredContent","transformRTSCarouselContent","componentData","slides","slideIndex","quoteKey","imageKey","imageCropFocusKey","attributionKey","linkKey","transformHotelSearchResponseToProductCard","hotel","generateMediaServerImageUrl","baseUrl","translateToConsumerUrl","formatLocation","transformCruiseSearchResponseToProductCard","cruise","product","slugify","formatProductDateRange","transformTourSearchResponseToProductCard","tour","startLocation","endLocation","tourBrandSupplierTypesRestricted"],"mappings":"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"}