import parseCookie from 'cookie' ; import { prop } from 'ramda' ; import { PRODUCT_HEADER } from '../../constants' ; import { inflightUrlWithQuery , RequestTracingConfig } from '../../HttpClient' ; import { JanusClient } from './JanusClient' ; export interface SegmentData { campaigns ? : any ; channel : number ; channelPrivacy ? : 'public' | 'private' ; priceTables ? : any ; utm_campaign : string ; regionId ? : string ; utm_source : string ; utmi_campaign : string ; currencyCode : string ; currencySymbol : string ; countryCode : string ; cultureInfo : string ; [ key ] : any ; } const SEGMENT_COOKIE = 'vtex_segment' ; const SEGMENT_MAX_AGE_S = 60 * 60 ; const ALLOWED_QUERY_PREFIXES = [ 'utm' , 'cultureInfo' , 'supportedLocales' , '__bindingId' ] ; const filterAndSortQuery = ( query ? ) => { if ( ! query ) { return null ; } const filteredKeys = Object . keys ( query ) . filter ( ( k ) => ! ! k && ALLOWED_QUERY_PREFIXES . some ( ( prefix ) => k . startsWith ( prefix ) ) ) . sort ( ) ; return filteredKeys . reduce ( ( acc , val ) => { acc [ val ] = query [ val ] ; return acc ; } , { } ) ; } ; const routes = { base : '/api/segments' , segments : ( token ? ) => ( token ? `${ routes . base }/${ token }` : routes . base ) , } ; export class Segment extends JanusClient { memberof public getSegment = ( tracingConfig ? ) => this . rawSegment ( this . context ! . segmentToken , undefined , tracingConfig ) . then ( prop ( 'data' ) ) ; memberof public getSegmentByToken = ( token , tracingConfig ? ) => this . rawSegment ( token , undefined , tracingConfig ) . then ( prop ( 'data' ) ) ; public getOrCreateSegment = async ( query ? , token ? , tracingConfig ? ) => { const { data : segmentData , headers } = await this . rawSegment ( token , query , tracingConfig ) ; return { segmentData , segmentToken : extractSegmentCookie ( headers ) , } ; } ; private rawSegment = ( token ? , query ? , tracingConfig ? ) => { const { product , workspace } = this . context ; const filteredQuery = filterAndSortQuery ( query ) ; const metric = token ? 'segment-get-token' : 'segment-get-new' ; return this . http . getRaw < SegmentData > ( routes . segments ( token ) , { forceMaxAge : SEGMENT_MAX_AGE_S , headers : { 'Content-Type' : 'application/json' , [ PRODUCT_HEADER ] : product || '' , } , inflightKey : inflightUrlWithQuery , metric , params : { ... filteredQuery , session_path : product || '' , workspace , } , tracing : { requestSpanNameSuffix : metric , ... tracingConfig ?. tracing , } , } ) ; } ; } function extractSegmentCookie ( headers ) { for ( const setCookie of headers [ 'set-cookie' ] ?? [ ] ) { const parsedCookie = parseCookie . parse ( setCookie ) ; const segmentCookie = parsedCookie [ SEGMENT_COOKIE ] ; if ( segmentCookie != null ) { return segmentCookie ; } } return null ; }