UNPKG

cxa-track

Version:

Convenient CLI to quickly update CxA tracked links

98 lines (79 loc) 2.69 kB
import { containsOnlyAlphanumeric, removeLocaleFromUrl, addLocaleToUrl } from './util.js'; export const trackedDomains = [ 'portal.azure.com', 'microsoft.com', 'msdn.com', 'visualstudio.com', 'microsoftazurepass.com', 'microsoftevents.com' ]; const trackingParam = 'WT.mc_id'; const urlRegex = /\bhttps?:\/\/[-\w+&@#/%?=~|!:,.;]*[-\w+&@#/%=~|]/gim; export function isTrackedDomain(url) { const { hostname } = new URL(url); return trackedDomains.some((domain) => hostname.includes(domain)); } export function checkTrackedDomain(url) { if (!isTrackedDomain(url)) throw new Error('URL domain is not tracked'); } export function mergeTrackingCode(baseTrackingCode, otherTrackingCode) { const base = baseTrackingCode ? parseTrackingCode(baseTrackingCode) : {}; const other = otherTrackingCode ? parseTrackingCode(otherTrackingCode) : {}; const area = other.area || base.area; const id = other.id || base.id; const alias = other.alias || base.alias; if (!area || !id || !alias) throw new Error('tracking code incomplete'); return `${area}-${id}-${alias}`; } export function generateTrackingParameters(trackingCode, params = {}) { return new URLSearchParams({ ...params, [trackingParam]: trackingCode }).toString(); } export function parseTrackingCode(partialTrackingCode) { if (!partialTrackingCode) throw new Error('no tracking code defined'); let [area, id, alias] = partialTrackingCode.split('-'); // If only a single value is set, it's the ID if (area !== undefined && id === undefined) { id = area; area = undefined; } if ( !containsOnlyAlphanumeric(id) || (area !== undefined && !containsOnlyAlphanumeric(area)) || (alias !== undefined && !containsOnlyAlphanumeric(alias)) ) throw new Error('tracking code can only contain alphanumeric characters'); return { area, id, alias }; } export function updateTrackedUrl(url, trackingCode, locale, extraParams = {}) { if (locale !== true) url = removeLocaleFromUrl(url); if (typeof locale === 'string') url = addLocaleToUrl(url, locale); const currentUrl = new URL(url); const existingParams = Object.fromEntries(currentUrl.searchParams.entries()); const newTrackingParameters = generateTrackingParameters(trackingCode, { ...existingParams, ...extraParams }); currentUrl.search = newTrackingParameters; return currentUrl.href; } export function updateTrackingCodeInText( text, trackingCode, locale, extraParams ) { return text ? text.replaceAll(urlRegex, (url) => isTrackedDomain(url) ? updateTrackedUrl(url, trackingCode, locale, extraParams) : url ) : text; }