{"version":3,"sources":["webpack://casperEventHub/./src/login-prefill.ts","webpack://casperEventHub/./src/user.ts","webpack://casperEventHub/./src/eCapi.ts","webpack://casperEventHub/./src/urlParameters.ts"],"names":["isLoginPrefilled","prefillPromise","Promise","tempForm","document","tempEmail","clearAll","resolve","tempEmailRefresh","setInterval","window","tempPwd","initialState","timeId","setTimeout","clearInterval","clearTimeout","args","i","arguments","f","then","value","User","e","getState","dataLayerUser","body","result","user","status","isValid","off","this","isNotLoggedIn","urlParams","getUrlParams","Rule","recover","getUserDetails","userDetails","JSON","hasCookie","getProductsDetails","napiCatalog","productsDetails","productsProperties","productProperties","fields","categories","technologies","cupSizes","range","isStandingOrders","category","indexOf","processCategories","getProductsProperties","basketProducts","basketProduct","unitPrice","merged","getStandingOrders","getSubscriptions","subs","sub","product","subsDetails","marketSub","invoiceProduct","console","name","UrlParameters","readStoredParams","sessionParams"],"mappings":"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","file":"User.js","sourcesContent":["export let prefillPromise: Promise<boolean>\n\nexport async function isLoginPrefilled(): Promise<boolean> {\n if (prefillPromise != null) {\n return prefillPromise\n }\n return (prefillPromise = new Promise((resolve) => {\n // Init temporary form with email/password fields\n const tempForm = document.createElement('form')\n tempForm.style.display = 'none'\n tempForm.method = 'POST'\n\n const tempEmail = document.createElement('input')\n tempEmail.setAttribute('type', 'email')\n tempEmail.setAttribute('id', 'ta-header-username')\n tempEmail.setAttribute('autocomplete', 'username email')\n tempEmail.setAttribute('value', '')\n\n // IE/Edge change the value and fire events\n tempEmail.addEventListener(\n 'propertychange change click keyup input paste blur',\n () => {\n clearAll()\n resolve(!!tempEmail.value)\n }\n )\n // Chrome/Firefox don't fire events but change input style\n const tempEmailRefresh = setInterval(() => {\n if (\n tempEmail.value != '' ||\n window.getComputedStyle(tempEmail).backgroundColor !== initialState\n ) {\n clearAll()\n resolve(true)\n }\n }, 100)\n\n const tempPwd = document.createElement('input')\n tempPwd.setAttribute('type', 'password')\n tempPwd.setAttribute('id', 'ta-header-password')\n tempPwd.setAttribute('autocomplete', 'current-password')\n tempPwd.setAttribute('value', '')\n\n tempForm.appendChild(tempEmail)\n tempForm.appendChild(tempPwd)\n\n document.body.appendChild(tempForm)\n\n const initialState = window.getComputedStyle(tempEmail).backgroundColor\n\n // Remove temp form and resolve Promise if no change is detected\n const timeId = setTimeout(() => {\n clearInterval(tempEmailRefresh)\n tempForm.parentNode && tempForm.parentNode.removeChild(tempForm)\n resolve(false)\n }, 1000)\n\n const clearAll = (): void => {\n clearTimeout(timeId)\n clearInterval(tempEmailRefresh)\n tempForm.parentNode && tempForm.parentNode.removeChild(tempForm)\n }\n }))\n}\n","import { getUserDetails } from './eCapi'\nimport Rule from './rule'\nimport { readStoredParams as getUrlParams } from './urlParameters'\nimport { ITargetingRulesEvaluationResult } from './experience'\nimport { CustomerDetails, Possibilities } from './types'\nimport { isLoginPrefilled } from './login-prefill'\n\nfunction isTrafficSourceEmail(): boolean {\n const urlParams = getUrlParams()\n return (\n typeof urlParams.utm_source !== 'undefined' &&\n urlParams.utm_source === 'Email'\n )\n}\n\nexport default class User extends Rule {\n private eventHandler?: () => void\n constructor(callback: () => Promise<ITargetingRulesEvaluationResult>) {\n super()\n try {\n this.eventHandler = window.napi.data().on('user.login', callback)\n } catch (e) {\n // prevent error\n }\n }\n public async getState(): Promise<UserState> {\n let user: CustomerDetails\n const dataLayerUser = window[window.config.padl.namespace].dataLayer.user\n if (dataLayerUser && dataLayerUser.isLoggedIn) {\n user = await getUserDetails()\n } else if (await this.isNotLoggedIn()) {\n user = { status: 'not-logged-in' }\n } else {\n user = { status: 'anonymous' }\n }\n return {\n isValid: super.validate(([user] as unknown) as Possibilities), //TODO check is really necessary\n user,\n }\n }\n public off(): void {\n window.napi.data().off('user.login', this.eventHandler)\n }\n private async isNotLoggedIn(): Promise<boolean> {\n return isTrafficSourceEmail() || (await isLoginPrefilled())\n }\n}\n\ninterface UserState {\n isValid: boolean\n user: CustomerDetails\n}\n","import {\n Catalog,\n CartProducts,\n ICategory,\n ProductDetails,\n CustomerDetails,\n} from './types'\nimport { IStandingOrder } from './standingOrders'\nimport { CustomerSubscription, MergedSubscriptions } from './subscriptions'\n\nlet userDetails: CustomerDetails | null\n\nexport function clearCustomerDetails(): void {\n userDetails = null\n}\n\nexport async function getSubscriptions(): Promise<MergedSubscriptions[]> {\n try {\n const subs: CustomerSubscription[] = await window.napi\n .subscription()\n .getSubscriptions()\n const subsDetails = await window.napi.market().getSubscriptions()\n return (await Promise.all(\n subs.map(async (sub) => {\n let product\n if (sub.promotionalProductId) {\n product = await window.napi\n .catalog()\n .getProduct(sub.promotionalProductId)\n }\n const subDetails = subsDetails.subscriptionProfiles.find(\n (marketSub) => marketSub.id === sub.profileId\n )\n return { ...subDetails, ...sub, invoiceProduct: product }\n })\n )) as MergedSubscriptions[]\n } catch (e) {\n console.log('error with experience', e)\n return [] as MergedSubscriptions[]\n }\n}\n\nexport async function getStandingOrders(): Promise<IStandingOrder[]> {\n try {\n return await window.napi.standingOrders().getOrders('Responsive')\n } catch (e) {\n return [] as IStandingOrder[]\n }\n}\n\nfunction processCategories(categories: ICategory[]): IProductFields {\n const technologies = []\n const cupSizes = []\n let range: IProductFields['range'] = null\n let isStandingOrders = false\n for (const category of categories) {\n if (['original', 'vertuo'].indexOf(category.code) > -1) {\n technologies.push(category.code)\n } else if (\n category.code.indexOf('capsule-range') > -1 &&\n category.code.indexOf('-Mobile') === -1\n ) {\n range = category.code.replace('capsule-range-', '')\n } else if (category.code.indexOf('capsule-cupSize') > -1) {\n cupSizes.push(category.code.replace('capsule-cupSize-', ''))\n } else if (category.code === 'standing-orders') {\n isStandingOrders = true\n }\n }\n return {\n cupSizes,\n isStandingOrders,\n range,\n technologies,\n }\n}\n\nexport async function getProductsProperties(): Promise<IProductProps[]> {\n const napiCatalog: Catalog = window.napi.catalog()\n const basketProducts: CartProducts[] = await window.napi.cart().read()\n const productsDetails: IProductProps[] = []\n await Promise.all(\n basketProducts.map(async (basketProduct) => {\n try {\n const productDetail = await napiCatalog.getProduct(\n basketProduct.productId\n )\n const { unitPrice } = basketProduct\n const merged = {\n ...basketProduct,\n ...productDetail,\n }\n if (unitPrice !== 0 && merged.price === 0) {\n merged.price = unitPrice\n }\n productsDetails.push(merged)\n } catch (e) {\n return\n }\n })\n )\n return productsDetails\n}\n\nexport async function getProductsDetails(): Promise<IProduct[]> {\n const napiCatalog: Catalog = window.napi.catalog()\n const productsProperties: IProductProps[] = await getProductsProperties()\n const productsDetails: IProduct[] = []\n await Promise.all(\n productsProperties.map(async (productProperties) => {\n try {\n const categories: ICategory[] = await Promise.all(\n productProperties.supercategories.map(napiCatalog.getCategory)\n )\n const fields: IProductFields = processCategories(categories)\n productsDetails.push({\n ...productProperties,\n ...fields,\n })\n } catch (e) {\n return\n }\n })\n )\n return productsDetails\n}\n\nexport async function getUserDetails(): Promise<CustomerDetails> {\n if (userDetails == null) {\n try {\n userDetails = JSON.parse(\n JSON.stringify(await window.napi.customer().read())\n ) as CustomerDetails\n if (userDetails.preferredTechnology !== undefined) {\n userDetails.preferredTechnology = userDetails.preferredTechnology.slice(\n 30\n )\n }\n } catch (error) {\n userDetails = {\n status: 'anonymous',\n }\n if (\n window.localStorage.getItem('loggedTimestamp') ||\n window.sessionStorage.getItem('loggedTimestamp') ||\n hasCookie('ecapiLoginToken') ||\n hasCookie('autoLoginToken') ||\n hasCookie('nesLoginToken')\n ) {\n userDetails.status = 'not-logged-in'\n }\n }\n }\n return userDetails\n}\n\nfunction hasCookie(name: string) {\n return window.document.cookie.indexOf(name + '=') > -1\n}\n\nexport interface IProductProps extends ProductDetails, CartProducts {\n quantity: number\n price: number\n sku?: string\n unitPrice: number\n}\n\nexport interface IProduct extends IProductFields, ProductDetails, CartProducts {\n quantity: number\n price: number\n sku?: string\n unitPrice: number\n}\n\nexport interface IProductFields {\n range: string | null\n technologies: string[]\n cupSizes: string[]\n isStandingOrders: boolean\n}\n","import Rule, { IRule, IRuleState } from './rule'\nimport { urlParamsStorageNamespace } from './store'\nimport { IUnknownObject } from './types'\n\nexport default class UrlParameters extends Rule implements IRule {\n public getState(): IUrlParametersState {\n const urlParams = readStoredParams()\n const result: IUrlParametersState = {\n isValid: false,\n }\n if (urlParams) {\n result.isValid = super.validate([urlParams])\n result.urlParams = urlParams\n }\n return result\n }\n}\n\nexport function readStoredParams(): IUnknownObject {\n const sessionParams: string | null = window.sessionStorage.getItem(\n urlParamsStorageNamespace\n )\n if (!sessionParams) {\n return {}\n }\n return JSON.parse(sessionParams) as IUnknownObject\n}\n\nexport interface IUrlParametersState extends IRuleState {\n urlParams?: IUnknownObject\n}\n"],"sourceRoot":""}