{"version":3,"sources":["../analytics-constants.ts","../visitor-tracker.tsx","../server/header-parser.ts","../analytics-bot-utils.ts","../server/middleware-utils.ts","../client/index.ts","../server/index.ts"],"names":["ip","userAgent","isbot"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Analytics configuration using environment variables\n * Both server and client components use NEXT_PUBLIC_* variables for consistency\n */\nexport const ANALYTICS_CONFIG = {\n  SERVER_URL: process.env.NEXT_PUBLIC_ANALYTICS_SERVER_URL || \"\",\n  SITE_ID: process.env.NEXT_PUBLIC_ANALYTICS_SITE_ID || \"\",\n} as const;\n\n/**\n * Validate that required environment variables are set\n */\nexport function validateAnalyticsConfig() {\n  const { SERVER_URL, SITE_ID } = ANALYTICS_CONFIG;\n  \n  if (!SERVER_URL || !SITE_ID) {\n    console.warn(\"[Analytics] Missing environment variables:\", {\n      SERVER_URL: SERVER_URL ? \"✓\" : \"✗ NEXT_PUBLIC_ANALYTICS_SERVER_URL\",\n      SITE_ID: SITE_ID ? \"✓\" : \"✗ NEXT_PUBLIC_ANALYTICS_SITE_ID\"\n    });\n    return false;\n  }\n  \n  return true;\n} ","\"use client\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport React, { useEffect, useRef, useCallback } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { isbot } from \"isbot\";\nimport {\n  ANALYTICS_CONFIG,\n  validateAnalyticsConfig,\n} from \"./analytics-constants\";\n\nexport interface VisitorTrackerProps {\n  ip: string;\n  country: string | null;\n  city: string | null;\n  region: string | null;\n  continent?: string | null;\n  latitude?: string | null;\n  longitude?: string | null;\n  timezone?: string | null;\n  postalCode?: string | null;\n  host?: string | null;\n  protocol?: \"http\" | \"https\" | null;\n  deploymentUrl?: string | null;\n  route: string;\n  userAgent: string;\n  // Optional server-side header data\n  edgeRegion?: string | null;\n  cacheStatus?: \"HIT\" | \"MISS\" | \"BYPASS\" | \"STALE\" | null;\n}\n\nexport function VisitorTracker({\n  ip,\n  country,\n  city,\n  region,\n  continent,\n  latitude,\n  longitude,\n  timezone,\n  postalCode,\n  host,\n  protocol,\n  deploymentUrl,\n  route,\n  userAgent,\n  edgeRegion,\n  cacheStatus,\n}: VisitorTrackerProps) {\n  const pathname = usePathname();\n  const isInitialized = useRef<boolean>(false);\n  const lastTrackedPath = useRef<string>(route);\n\n  // Check if this is a bot environment\n  const checkIfBot = useCallback(() => {\n    // Check server-provided user agent first\n    if (isbot(userAgent)) {\n      return true;\n    }\n\n    // Check client-side navigator user agent\n    if (typeof navigator !== \"undefined\" && isbot(navigator.userAgent)) {\n      return true;\n    }\n\n    // Additional client-side bot checks\n    if (typeof window !== \"undefined\") {\n      // Check for headless browser indicators\n      const win = window as Window & {\n        navigator?: Navigator & { webdriver?: boolean };\n        phantom?: unknown;\n        callPhantom?: unknown;\n        __nightmare?: unknown;\n      };\n      if (\n        win.navigator?.webdriver ||\n        win.phantom ||\n        win.callPhantom ||\n        win.__nightmare\n      ) {\n        return true;\n      }\n\n      // Check for missing typical browser features that bots might lack\n      if (!window.localStorage || !window.sessionStorage) {\n        return true;\n      }\n    }\n\n    return false;\n  }, [userAgent]);\n\n  // Generate consistent visitor and session IDs\n  const generateVisitorId = (ip: string, userAgent: string): string => {\n    const normalizedUA = userAgent.toLowerCase().replace(/\\s+/g, \"\");\n    const combined = `${ip}:${normalizedUA}`;\n    return btoa(combined)\n      .replace(/[^a-zA-Z0-9]/g, \"\")\n      .substring(0, 16);\n  };\n\n  const generateSessionId = (): string => {\n    // Check for existing session ID in sessionStorage\n    if (typeof window !== \"undefined\") {\n      const existingSessionId = sessionStorage.getItem(\"analytics_session_id\");\n      if (existingSessionId) {\n        return existingSessionId;\n      }\n    }\n\n    // Generate new lightweight session ID\n    const generateLightweightId = (): string => {\n      try {\n        // Use crypto.getRandomValues() for secure randomness\n        const array = new Uint8Array(4);\n        crypto.getRandomValues(array);\n\n        // Convert to base36 and combine with timestamp\n        const timestamp = Date.now().toString(36).slice(-4); // Last 4 chars of timestamp in base36\n        const randomPart = Array.from(array)\n          .map((byte) => byte.toString(36))\n          .join(\"\")\n          .slice(0, 4); // Take first 4 chars\n\n        return `${timestamp}${randomPart}`.substring(0, 8);\n      } catch {\n        // Fallback to Math.random() if crypto is unavailable\n        const timestamp = Date.now().toString(36).slice(-4);\n        const randomPart = Math.random().toString(36).substring(2, 6);\n        return `${timestamp}${randomPart}`.substring(0, 8);\n      }\n    };\n\n    const newSessionId = generateLightweightId();\n\n    // Store in sessionStorage (persists across page loads, expires with browser session)\n    if (typeof window !== \"undefined\") {\n      try {\n        sessionStorage.setItem(\"analytics_session_id\", newSessionId);\n      } catch {\n        // Continue without storage if sessionStorage is disabled\n      }\n    }\n\n    return newSessionId;\n  };\n\n  // Get enhanced client-side data\n  const getClientData = useCallback(() => {\n    // SSR Guard: Return safe defaults if running on server\n    if (typeof window === \"undefined\") {\n      return {\n        isNewVisitor: true,\n        screenResolution: null,\n        viewportSize: null,\n        connectionType: null,\n        clientTimeZone: null,\n        sessionStartTime: new Date().toISOString(),\n      };\n    }\n\n    // Check if this is a new visitor using session-level caching\n    const visitorId = generateVisitorId(ip, userAgent);\n    const sessionId = generateSessionId();\n    const sessionCacheKey = `isNewVisitor_${sessionId}`;\n\n    // Check if we already determined isNewVisitor for this session\n    const cachedIsNewVisitor = sessionStorage.getItem(sessionCacheKey);\n    let isNewVisitor: boolean;\n\n    if (cachedIsNewVisitor === null) {\n      // First event in this session - make the determination\n      const visitorExists = localStorage.getItem(\n        `analytics_visitor_${visitorId}`\n      );\n      isNewVisitor = !visitorExists;\n\n      // Cache the decision for this entire session\n      sessionStorage.setItem(sessionCacheKey, isNewVisitor.toString());\n\n      // Mark visitor as seen for future sessions (only if they're new)\n      if (isNewVisitor) {\n        localStorage.setItem(\n          `analytics_visitor_${visitorId}`,\n          Date.now().toString()\n        );\n      }\n    } else {\n      // Use the cached decision from earlier in this session\n      isNewVisitor = cachedIsNewVisitor === \"true\";\n    }\n\n    // Get session start time (persistent for this session)\n    // Note: reusing sessionId from above\n    let sessionStartTime = localStorage.getItem(\n      `analytics_session_start_${sessionId}`\n    );\n    if (!sessionStartTime) {\n      sessionStartTime = new Date().toISOString();\n      localStorage.setItem(\n        `analytics_session_start_${sessionId}`,\n        sessionStartTime\n      );\n    }\n\n    // Get screen and viewport data (safe now that we're client-side)\n    const screenResolution = `${screen.width}x${screen.height}`;\n    const viewportSize = `${window.innerWidth}x${window.innerHeight}`;\n\n    // Get connection type (if available)\n    const connectionType = (() => {\n      try {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        const nav = navigator as any;\n        return (\n          nav.connection?.effectiveType || nav.connection?.type || \"unknown\"\n        );\n      } catch {\n        return \"unknown\";\n      }\n    })();\n\n    // Get client timezone\n    const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n    return {\n      isNewVisitor,\n      screenResolution,\n      viewportSize,\n      connectionType,\n      clientTimeZone,\n      sessionStartTime,\n    };\n  }, [ip, userAgent]);\n\n  // Send event to analytics system\n  const sendAnalyticsEvent = useCallback(\n    async (\n      eventType: \"pageview\" | \"session_start\",\n      referrer?: string,\n      customPath?: string\n    ) => {\n      // Only run in production (temporarily disabled for debugging)\n      if (process.env.NODE_ENV !== \"production\" && false) {\n        return;\n      }\n\n      // Validate configuration\n      if (!validateAnalyticsConfig()) {\n        return;\n      }\n\n      const serverUrl = ANALYTICS_CONFIG.SERVER_URL;\n      const siteId = ANALYTICS_CONFIG.SITE_ID;\n\n      const endpoint = `${serverUrl}/api/log/ingest`;\n\n      // Extract standard client-side data with SSR guards\n      const language =\n        typeof navigator !== \"undefined\"\n          ? navigator.language || navigator.languages?.[0] || undefined\n          : undefined;\n      const doNotTrack =\n        typeof navigator !== \"undefined\" ? navigator.doNotTrack === \"1\" : false;\n      const isMobile =\n        typeof navigator !== \"undefined\"\n          ? /Mobi|Android/i.test(navigator.userAgent)\n          : /Mobi|Android/i.test(userAgent); // Fallback to server userAgent\n\n      // Get enhanced client data\n      const clientData = getClientData();\n\n      // Simulate development data when running locally\n      const isDev = process.env.NODE_ENV === \"development\";\n      const devCountry = isDev && !country ? \"US\" : country;\n      const devCity = isDev && !city ? \"San Francisco\" : city;\n      const devRegion = isDev && !region ? \"CA\" : region;\n      const devEdgeRegion = isDev && !edgeRegion ? \"sfo1\" : edgeRegion;\n\n      try {\n        const response = await fetch(endpoint, {\n          method: \"POST\",\n          headers: {\n            \"Content-Type\": \"application/json\",\n          },\n          mode: \"cors\",\n          body: JSON.stringify({\n            siteId,\n            path: customPath || route,\n            visitorId: generateVisitorId(ip, userAgent),\n            sessionId: generateSessionId(),\n            eventType,\n            // Enhanced client-side fields\n            isNewVisitor: clientData.isNewVisitor,\n            screenResolution: clientData.screenResolution,\n            viewportSize: clientData.viewportSize,\n            connectionType: clientData.connectionType,\n            clientTimeZone: clientData.clientTimeZone,\n            sessionStartTime: clientData.sessionStartTime,\n            // Server-side fields\n            ipAddress: ip,\n            userAgent,\n            referrer,\n            country: devCountry || undefined,\n            city: devCity || undefined,\n            region: devRegion || undefined,\n            continent: continent || undefined,\n            latitude: latitude ? parseFloat(latitude) : undefined,\n            longitude: longitude ? parseFloat(longitude) : undefined,\n            timezone: timezone || undefined,\n            postalCode: postalCode || undefined,\n            host: host || undefined,\n            protocol: protocol || undefined,\n            deploymentUrl: deploymentUrl || undefined,\n            edgeRegion: devEdgeRegion || undefined,\n            language,\n            doNotTrack,\n            isMobile,\n            cacheStatus: cacheStatus || \"UNKNOWN\",\n          }),\n        });\n\n        if (!response.ok) {\n          const error = await response.json();\n          console.error(\"[Analytics] Failed to track event:\", error);\n        }\n      } catch (error) {\n        // Silent error handling - don't block the page\n        console.error(\"[Analytics] Tracking failed:\", error);\n      }\n    },\n    [\n      ip,\n      country,\n      city,\n      region,\n      continent,\n      latitude,\n      longitude,\n      timezone,\n      postalCode,\n      host,\n      protocol,\n      deploymentUrl,\n      route,\n      userAgent,\n      edgeRegion,\n      cacheStatus,\n      getClientData,\n    ]\n  );\n\n  // Track session start, pageview and setup session end\n  useEffect(() => {\n    // SSR Guard: Only run on client\n    if (typeof window === \"undefined\") return;\n\n    // Only track in production environment\n    const isProduction =\n      process.env.NEXT_PUBLIC_VERCEL_ENV === \"production\" ||\n      (process.env.NODE_ENV === \"production\" &&\n        !process.env.NEXT_PUBLIC_VERCEL_ENV);\n\n    if (!isProduction) {\n      return;\n    }\n\n    // Check if this is a bot - if so, skip all client-side tracking\n    if (checkIfBot()) {\n      return;\n    }\n\n    const currentPath = pathname || route;\n\n    // Initial setup on first load\n    if (!isInitialized.current) {\n      isInitialized.current = true;\n\n      const sessionId = generateSessionId();\n      const sessionKey = `analytics_session_active_${sessionId}`;\n      const isSessionActive = localStorage.getItem(sessionKey);\n\n      // Send session_start if this is a new session\n      if (!isSessionActive) {\n        sendAnalyticsEvent(\"session_start\", undefined, currentPath);\n        localStorage.setItem(sessionKey, \"true\");\n      }\n\n      // Track initial pageview\n      const referrer =\n        document.referrer && document.referrer.length > 0\n          ? document.referrer\n          : undefined;\n      sendAnalyticsEvent(\"pageview\", referrer, currentPath);\n      lastTrackedPath.current = currentPath;\n\n      // No cleanup needed - sessions end naturally through timeout logic\n    }\n    // Handle route changes (client-side navigation)\n    else if (currentPath !== lastTrackedPath.current) {\n      // Track pageview for route change\n      sendAnalyticsEvent(\"pageview\", undefined, currentPath);\n      lastTrackedPath.current = currentPath;\n    }\n\n    // Return undefined for useEffect when no cleanup is needed\n    return;\n  }, [\n    pathname,\n    route,\n    ip,\n    country,\n    city,\n    region,\n    continent,\n    latitude,\n    longitude,\n    timezone,\n    postalCode,\n    host,\n    protocol,\n    deploymentUrl,\n    userAgent,\n    edgeRegion,\n    cacheStatus,\n    sendAnalyticsEvent,\n    getClientData,\n    checkIfBot,\n  ]); // Re-run if pathname or route changes\n\n  return null; // This component renders nothing\n}\n","/**\n * Server-side utility to parse analytics data from Next.js headers\n */\n\nexport interface ParsedAnalyticsHeaders {\n  ip: string;\n  country: string | null;\n  city: string | null;\n  region: string | null;\n  continent: string | null;\n  latitude: string | null;\n  longitude: string | null;\n  timezone: string | null;\n  postalCode: string | null;\n  host: string | null;\n  protocol: \"http\" | \"https\" | null;\n  deploymentUrl: string | null;\n  userAgent: string;\n  edgeRegion: string | null;\n  cacheStatus: \"HIT\" | \"MISS\" | \"BYPASS\" | \"STALE\" | null;\n}\n\nexport function parseAnalyticsHeaders(headers: Headers): ParsedAnalyticsHeaders {\n  const ip = headers.get(\"x-forwarded-for\") || headers.get(\"x-real-ip\") || \"unknown\";\n  const country = headers.get(\"x-vercel-ip-country\") || null;\n  const userAgent = headers.get(\"user-agent\") || \"\";\n  const city = headers.get(\"x-vercel-ip-city\") || null;\n  const region = headers.get(\"x-vercel-ip-country-region\") || null;\n  const continent = headers.get(\"x-vercel-ip-continent\") || null;\n  const latitude = headers.get(\"x-vercel-ip-latitude\") || null;\n  const longitude = headers.get(\"x-vercel-ip-longitude\") || null;\n  const timezone = headers.get(\"x-vercel-ip-timezone\") || null;\n  const postalCode = headers.get(\"x-vercel-ip-postal-code\") || null;\n  const host = headers.get(\"host\") || null;\n  const protocol = headers.get(\"x-forwarded-proto\") as \"http\" | \"https\" | null;\n  const deploymentUrl = headers.get(\"x-vercel-deployment-url\") || null;\n  const vercelId = headers.get(\"x-vercel-id\") || null;\n\n  // Extract edge region from x-vercel-id\n  const edgeRegion = vercelId ? vercelId.split(\"::\")[0] : null;\n  const cacheStatus = null; // This would need to be determined differently\n\n  return {\n    ip,\n    country,\n    city,\n    region,\n    continent,\n    latitude,\n    longitude,\n    timezone,\n    postalCode,\n    host,\n    protocol,\n    deploymentUrl,\n    userAgent,\n    edgeRegion,\n    cacheStatus,\n  };\n} ","import type { NextRequest } from 'next/server';\nimport { ANALYTICS_CONFIG, validateAnalyticsConfig } from './analytics-constants';\n\n/**\n * Simplified Bot Tracking Utility\n * \n * Fire-and-forget bot tracking with minimal data collection.\n * Designed for performance and reliability - no complex calculations.\n */\n\n// Simple hash generation for bot IDs (no complex session windows)\nfunction generateSimpleBotVisitorId(ip: string, userAgent: string): string {\n  const normalizedUA = userAgent.toLowerCase().replace(/\\s+/g, \"\");\n  const combined = `bot:${ip}:${normalizedUA}`;\n  return Buffer.from(combined)\n    .toString(\"base64\")\n    .replace(/[^a-zA-Z0-9]/g, \"\")\n    .substring(0, 16);\n}\n\nfunction generateSimpleBotSessionId(ip: string): string {\n  const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD\n  const combined = `bot-session:${ip}:${today}`;\n  return Buffer.from(combined)\n    .toString(\"base64\")\n    .replace(/[^a-zA-Z0-9]/g, \"\")\n    .substring(0, 16);\n}\n\n/**\n * Track bot visit with minimal data collection\n * Fire-and-forget: does not throw errors or block execution\n */\nexport function trackBotVisit(request: NextRequest, pathname: string): void {\n  // Fire-and-forget: run async without awaiting\n  void (async () => {\n    try {\n      // Validate configuration\n      if (!validateAnalyticsConfig()) {\n        return;\n      }\n\n      const serverUrl = ANALYTICS_CONFIG.SERVER_URL;\n      const siteId = ANALYTICS_CONFIG.SITE_ID;\n\n      // Extract essential bot data\n      const userAgent = request.headers.get('user-agent') || '';\n      const ip = request.headers.get('x-forwarded-for')?.split(',')[0] || \n                request.headers.get('x-real-ip') || \n                'unknown';\n\n      // Generate minimal required IDs\n      const visitorId = generateSimpleBotVisitorId(ip, userAgent);\n      const sessionId = generateSimpleBotSessionId(ip);\n\n      // Prepare minimal bot payload\n      const botPayload = {\n        // Required fields (minimal values)\n        siteId,\n        path: pathname,\n        visitorId,\n        sessionId,\n        eventType: \"pageview\" as const,\n        \n        // Essential bot data\n        userAgent,\n        ipAddress: ip,\n        \n        // Client-side fields (bots don't have these)\n        isNewVisitor: true,\n        screenResolution: null,\n        viewportSize: null,\n        connectionType: null,\n        clientTimeZone: null,\n        sessionStartTime: new Date().toISOString(),\n        \n        // Optional server fields (skip expensive lookups)\n        referrer: request.headers.get('referer') || null,\n        country: null,\n        city: null,\n        region: null,\n        continent: null,\n        latitude: null,\n        longitude: null,\n        timezone: null,\n        postalCode: null,\n        host: request.headers.get('host') || null,\n        protocol: request.headers.get('x-forwarded-proto') as \"http\" | \"https\" || null,\n        deploymentUrl: null,\n        edgeRegion: null,\n        language: null,\n        doNotTrack: false,\n        isMobile: /Mobi|Android/i.test(userAgent),\n        cacheStatus: \"UNKNOWN\" as const,\n      };\n\n      // Send to analytics server (fire-and-forget)\n      const endpoint = `${serverUrl}/api/log/ingest`;\n      \n      await fetch(endpoint, {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n        mode: 'cors',\n        body: JSON.stringify(botPayload),\n      });\n\n    } catch {\n      // Silent fail - do not log errors or throw exceptions\n      // Bot tracking should never break the application\n      return;\n    }\n  })();\n} ","import type { NextRequest } from 'next/server';\nimport { isbot } from 'isbot';\nimport { trackBotVisit } from '../analytics-bot-utils';\n\n/**\n * Combined middleware utility for analytics\n * Handles both pathname header injection and bot tracking\n */\nexport function setupAnalyticsMiddleware(request: NextRequest) {\n  // Extract pathname from URL\n  const pathname = request.nextUrl.pathname;\n  \n  // Clone headers and add pathname\n  const headers = new Headers(request.headers);\n  headers.set('x-pathname', pathname);\n  \n  // Track bot visits if this is a bot\n  const userAgent = request.headers.get('user-agent') || '';\n  if (isbot(userAgent)) {\n    trackBotVisit(request, pathname);\n  }\n  \n  return {\n    headers,\n    pathname\n  };\n} ","// Client-side analytics components\nexport { VisitorTracker, type VisitorTrackerProps } from '../visitor-tracker'; ","// Server-side analytics utilities\nexport { setupAnalyticsMiddleware } from './middleware-utils';\nexport { parseAnalyticsHeaders } from './header-parser';\nexport { trackBotVisit } from '../analytics-bot-utils'; "]}