{"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":""}