{"version":3,"file":"analytics.mjs","names":[],"sources":["../../src/analytics.ts"],"sourcesContent":["import type {\n  ClientBrowserParameters,\n  ShopifyAddToCartPayload,\n  ShopifyAnalytics,\n  ShopifyPageViewPayload,\n  ShopifyMonorailEvent,\n} from './analytics-types.js';\nimport {AnalyticsEventName} from './analytics-constants.js';\nimport {errorIfServer} from './analytics-utils.js';\n\nimport {pageView as trekkiePageView} from './analytics-schema-trekkie-storefront-page-view.js';\nimport {\n  pageView as customerPageView,\n  pageView2 as customerPageView2,\n  collectionView as customerCollectionView,\n  productView as customerProductView,\n  searchView as customerSearchView,\n  addToCart as customerAddToCart,\n} from './analytics-schema-custom-storefront-customer-tracking.js';\nimport {getTrackingValues} from './tracking-utils.js';\n\n/**\n * Set user and session cookies and refresh the expiry time. If `event.payload.hasUserConsent` is false, no analytics event will happen.\n * @param event - The analytics event.\n * @param shopDomain - The Online Store domain to sent Shopify analytics under the same\n *   top level domain.\n * @publicDocs\n */\nexport function sendShopifyAnalytics(\n  event: ShopifyAnalytics,\n  shopDomain?: string,\n): Promise<void> {\n  const {eventName, payload} = event;\n  if (!payload.hasUserConsent) return Promise.resolve();\n\n  let events: ShopifyMonorailEvent[] = [];\n  const pageViewPayload = payload as ShopifyPageViewPayload;\n\n  if (eventName === AnalyticsEventName.PAGE_VIEW) {\n    events = events.concat(\n      trekkiePageView(pageViewPayload),\n      customerPageView(pageViewPayload),\n    );\n  } else if (eventName === AnalyticsEventName.ADD_TO_CART) {\n    events = events.concat(\n      customerAddToCart(payload as ShopifyAddToCartPayload),\n    );\n  } else if (eventName === AnalyticsEventName.PAGE_VIEW_2) {\n    events = events.concat(\n      trekkiePageView(pageViewPayload),\n      customerPageView2(pageViewPayload),\n    );\n  } else if (eventName === AnalyticsEventName.COLLECTION_VIEW) {\n    events = events.concat(customerCollectionView(pageViewPayload));\n  } else if (eventName === AnalyticsEventName.PRODUCT_VIEW) {\n    events = events.concat(customerProductView(pageViewPayload));\n  } else if (eventName === AnalyticsEventName.SEARCH_VIEW) {\n    events = events.concat(customerSearchView(pageViewPayload));\n  }\n\n  if (events.length) {\n    return sendToShopify(events, shopDomain);\n  } else {\n    return Promise.resolve();\n  }\n}\n\n// Shopify monorail return invalid agent for Lighthouse userAgents\nfunction isLighthouseUserAgent(): boolean {\n  if (typeof window === 'undefined' || !window.navigator) return false;\n  return /Chrome-Lighthouse/.test(window.navigator.userAgent);\n}\n\ntype MonorailResponse = {\n  status: number;\n  message: string;\n};\n\nconst ERROR_MESSAGE = 'sendShopifyAnalytics request is unsuccessful';\n\nfunction sendToShopify(\n  events: ShopifyMonorailEvent[],\n  shopDomain?: string,\n): Promise<void> {\n  if (isLighthouseUserAgent()) {\n    return Promise.resolve();\n  }\n\n  const eventsToBeSent = {\n    events,\n    metadata: {\n      event_sent_at_ms: Date.now(),\n    },\n  };\n\n  try {\n    return fetch(\n      shopDomain\n        ? `https://${shopDomain}/.well-known/shopify/monorail/unstable/produce_batch`\n        : 'https://monorail-edge.shopifysvc.com/unstable/produce_batch',\n      {\n        method: 'post',\n        headers: {\n          'content-type': 'text/plain',\n        },\n        body: JSON.stringify(eventsToBeSent),\n      },\n    )\n      .then((response) => {\n        if (!response.ok) {\n          throw new Error('Response failed');\n        }\n        return response.text();\n      })\n      .then((data) => {\n        if (data) {\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n          const jsonResponse = JSON.parse(data);\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n          jsonResponse.result.forEach((eventResponse: MonorailResponse) => {\n            if (eventResponse.status !== 200) {\n              console.error(ERROR_MESSAGE, '\\n\\n', eventResponse.message);\n            }\n          });\n        }\n      })\n      .catch((err) => {\n        console.error(ERROR_MESSAGE, err);\n        if (__HYDROGEN_DEV__) {\n          throw new Error(ERROR_MESSAGE);\n        }\n      });\n  } catch (error) {\n    // Do nothing\n    return Promise.resolve();\n  }\n}\n\n/**\n * If executed on server, this method will return empty string for each field.\n * @publicDocs\n */\nexport function getClientBrowserParameters(): ClientBrowserParameters {\n  if (errorIfServer('getClientBrowserParameters')) {\n    return {\n      uniqueToken: '',\n      visitToken: '',\n      url: '',\n      path: '',\n      search: '',\n      referrer: '',\n      title: '',\n      userAgent: '',\n      navigationType: '',\n      navigationApi: '',\n    };\n  }\n\n  const [navigationType, navigationApi] = getNavigationType();\n  const trackingValues = getTrackingValues();\n\n  return {\n    uniqueToken: trackingValues.uniqueToken,\n    visitToken: trackingValues.visitToken,\n    url: location.href,\n    path: location.pathname,\n    search: location.search,\n    referrer: document.referrer,\n    title: document.title,\n    userAgent: navigator.userAgent,\n    navigationType,\n    navigationApi,\n  };\n}\n\nfunction getNavigationTypeExperimental(): string | undefined {\n  try {\n    const navigationEntries =\n      performance?.getEntriesByType &&\n      performance?.getEntriesByType('navigation');\n\n    if (navigationEntries && navigationEntries[0]) {\n      // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming\n      const rawType = (\n        window.performance.getEntriesByType(\n          'navigation',\n        )[0] as PerformanceNavigationTiming\n      )['type'];\n      const navType = rawType && rawType.toString();\n\n      return navType;\n    }\n  } catch (err) {\n    // Do nothing\n  }\n  return undefined;\n}\n\nfunction getNavigationTypeLegacy(): string | undefined {\n  try {\n    if (\n      PerformanceNavigation &&\n      performance?.navigation?.type !== null &&\n      performance?.navigation?.type !== undefined\n    ) {\n      //  https://developer.mozilla.org/en-US/docs/Web/API/Performance/navigation\n      const rawType = performance.navigation.type;\n      switch (rawType) {\n        case PerformanceNavigation.TYPE_NAVIGATE:\n          return 'navigate';\n        case PerformanceNavigation.TYPE_RELOAD:\n          return 'reload';\n        case PerformanceNavigation.TYPE_BACK_FORWARD:\n          return 'back_forward';\n        default:\n          return `unknown: ${rawType}`;\n      }\n    }\n  } catch (err) {\n    // do nothing\n  }\n  return undefined;\n}\n\nfunction getNavigationType(): [string, string] {\n  try {\n    let navApi = 'PerformanceNavigationTiming';\n    let navType = getNavigationTypeExperimental();\n    if (!navType) {\n      navType = getNavigationTypeLegacy();\n      navApi = 'performance.navigation';\n    }\n    if (navType) {\n      return [navType, navApi];\n    } else {\n      return ['unknown', 'unknown'];\n    }\n  } catch (err) {\n    // do nothing\n  }\n  return ['error', 'error'];\n}\n"],"mappings":"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"}