shopkit-analytics 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.js +1 -37
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +1 -1
- package/dist/{chunk-5E7HVZ7Z.mjs → chunk-EAWHMEHO.mjs} +2 -2
- package/dist/{chunk-XGOJHFHL.mjs → chunk-FS3XAQFM.mjs} +2 -38
- package/dist/chunk-FS3XAQFM.mjs.map +1 -0
- package/dist/events/index.js +1 -37
- package/dist/events/index.js.map +1 -1
- package/dist/events/index.mjs +2 -2
- package/dist/index.js +1 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-XGOJHFHL.mjs.map +0 -1
- /package/dist/{chunk-5E7HVZ7Z.mjs.map → chunk-EAWHMEHO.mjs.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/events/publisher.ts","../src/events/subscriber.ts","../src/index.ts","../src/ShopkitAnalytics.tsx","../src/logger/index.ts","../src/experiment/constants.ts","../src/experiment/experiment-tracker.ts","../src/adapters/base-adapter.ts","../src/types.ts","../src/utils/event-id.ts","../src/adapters/constants.ts","../src/utils/pii-hashing.ts","../src/adapters/multi-pixel-adapter.ts","../src/adapters/google-adapter.ts","../src/adapters/moengage-adapter.ts","../src/adapters/posthog-adapter.ts","../src/adapters/shopify-adapter.ts","../src/events/init.ts","../src/affiliate/AffiliateTracker.tsx","../src/affiliate/constants.ts","../src/affiliate/affiliate-tracker.ts","../src/affiliate/hooks.ts","../src/shopify/ShopifyAnalyticsScript.tsx","../src/events/index.ts"],"sourcesContent":["import type { TEvent } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\n\n/**\n * EventPublisher class responsible for publishing events to subscribers\n */\nclass EventPublisher {\n private static instance: EventPublisher;\n private subscribers: Array<(event: TEvent, params?: TAdapterParams) => void> =\n [];\n\n /**\n * Private constructor to enforce singleton pattern\n */\n private constructor() {}\n\n /**\n * Get the singleton instance of EventPublisher\n */\n public static getInstance(): EventPublisher {\n if (!EventPublisher.instance) {\n EventPublisher.instance = new EventPublisher();\n }\n return EventPublisher.instance;\n }\n\n /**\n * Subscribe to events\n * @param callback Function to be called when an event is published\n * @returns Unsubscribe function\n */\n public subscribe(\n callback: (event: TEvent, params?: TAdapterParams) => void\n ): () => void {\n this.subscribers.push(callback);\n\n // Return unsubscribe function\n return () => {\n this.subscribers = this.subscribers.filter(\n (subscriber) => subscriber !== callback\n );\n };\n }\n\n /**\n * Publish an event to all subscribers\n * @param event The event to publish\n * @param params Optional adapter-specific parameters\n */\n public publish(event: TEvent, params?: TAdapterParams): void {\n try {\n console.log(\"EventPublisher: Received event\", {\n type: event.type,\n data: event,\n params: params,\n });\n\n // Add timestamp if not already present\n const eventWithTimestamp = !event.timestamp\n ? { ...event, timestamp: Date.now() }\n : event;\n\n console.log(\n \"EventPublisher: Number of subscribers:\",\n this.subscribers.length\n );\n\n // Notify all subscribers\n for (const subscriber of this.subscribers) {\n try {\n console.log(\"EventPublisher: Notifying subscriber\");\n subscriber(eventWithTimestamp, params);\n console.log(\"EventPublisher: Subscriber notified successfully\");\n } catch (error) {\n console.error(\"EventPublisher: Error in subscriber:\", error);\n // Continue with other subscribers even if one fails\n }\n }\n\n console.log(\"EventPublisher: Event processing completed\");\n } catch (error) {\n console.error(\"Error publishing event:\", error, event);\n // Silently fail to prevent app crashes due to event publishing issues\n }\n }\n}\n\n// Export singleton instance\nexport const eventPublisher = EventPublisher.getInstance();\n\n/**\n * Helper function to publish events\n * @param event The event to publish\n * @param params Optional adapter-specific parameters\n */\nexport function publishEvent(event: TEvent, params?: TAdapterParams): void {\n try {\n eventPublisher.publish(event, params);\n } catch (error) {\n console.error(\"Error in publishEvent helper:\", error);\n // Silently fail to prevent app crashes due to event publishing issues\n }\n}\n","import type { TEvent } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { eventPublisher } from \"./publisher\";\n\n/**\n * Interface for tracking adapters\n */\nexport interface TrackingAdapter {\n /**\n * Name of the tracking adapter\n */\n name: string;\n\n /**\n * Whether the adapter is enabled\n */\n isEnabled: () => boolean;\n\n /**\n * Initialize the adapter\n */\n initialize: () => Promise<void>;\n\n /**\n * Track an event\n */\n trackEvent: (event: TEvent, params?: TAdapterParams) => Promise<void>;\n}\n\n/**\n * EventSubscriber class responsible for managing tracking adapters and forwarding events\n */\nclass EventSubscriber {\n private static instance: EventSubscriber;\n private adapters: TrackingAdapter[] = [];\n private initialized = false;\n private eventQueue: Array<{ event: TEvent; params?: TAdapterParams }> = [];\n private unsubscribe: (() => void) | null = null;\n\n /**\n * Private constructor to enforce singleton pattern\n */\n private constructor() {}\n\n /**\n * Get the singleton instance of EventSubscriber\n */\n public static getInstance(): EventSubscriber {\n if (!EventSubscriber.instance) {\n EventSubscriber.instance = new EventSubscriber();\n }\n return EventSubscriber.instance;\n }\n\n /**\n * Register a tracking adapter\n * @param adapter The tracking adapter to register\n */\n public registerAdapter(adapter: TrackingAdapter): void {\n // Check if adapter with the same name already exists\n const existingAdapter = this.adapters.find((a) => a.name === adapter.name);\n if (existingAdapter) {\n console.warn(\n `Tracking adapter with name \"${adapter.name}\" is already registered. Skipping.`\n );\n return;\n }\n\n this.adapters.push(adapter);\n\n // If already initialized, initialize the new adapter\n if (this.initialized) {\n this.initializeAdapter(adapter).catch((error) => {\n console.error(`Failed to initialize adapter \"${adapter.name}\":`, error);\n });\n }\n }\n\n /**\n * Unregister a tracking adapter by name\n * @param adapterName The name of the adapter to unregister\n */\n public unregisterAdapter(adapterName: string): void {\n this.adapters = this.adapters.filter(\n (adapter) => adapter.name !== adapterName\n );\n }\n\n /**\n * Initialize all registered adapters\n */\n public async initialize(): Promise<void> {\n console.log(\"Initializing EventSubscriber...\");\n\n if (this.initialized) {\n console.log(\"EventSubscriber already initialized\");\n return;\n }\n\n // Subscribe to events\n this.unsubscribe = eventPublisher.subscribe(this.handleEvent.bind(this));\n console.log(\"Subscribed to event publisher\");\n\n // Initialize all adapters\n console.log(`Initializing ${this.adapters.length} adapters...`);\n await Promise.all(\n this.adapters.map((adapter) => this.initializeAdapter(adapter))\n );\n\n this.initialized = true;\n console.log(\"EventSubscriber initialization complete\");\n\n // Process any queued events\n this.processEventQueue();\n }\n\n /**\n * Initialize a single adapter\n * @param adapter The adapter to initialize\n */\n private async initializeAdapter(adapter: TrackingAdapter): Promise<void> {\n try {\n await adapter.initialize();\n console.log(\n `Tracking adapter \"${adapter.name}\" initialized successfully.`\n );\n } catch (error) {\n console.error(`Failed to initialize adapter \"${adapter.name}\":`, error);\n }\n }\n\n /**\n * Handle an event by forwarding it to all enabled adapters\n * @param event The event to handle\n * @param params Optional adapter-specific parameters\n */\n private handleEvent(event: TEvent, params?: TAdapterParams): void {\n console.log(\"Handling event:\", event.type, \"with params:\", params);\n\n if (!this.initialized) {\n console.log(\"Subscriber not initialized, queueing event\");\n this.eventQueue.push({ event, params });\n return;\n }\n\n // Forward the event to all enabled adapters\n for (const adapter of this.adapters) {\n if (adapter.isEnabled()) {\n console.log(`Forwarding event to adapter: ${adapter.name}`);\n adapter.trackEvent(event, params).catch((error) => {\n console.error(\n `Error tracking event in adapter \"${adapter.name}\":`,\n error\n );\n });\n } else {\n console.log(`Adapter ${adapter.name} is disabled, skipping`);\n }\n }\n }\n\n /**\n * Process any events that were queued before initialization\n */\n private processEventQueue(): void {\n if (this.eventQueue.length === 0) {\n return;\n }\n\n console.log(`Processing ${this.eventQueue.length} queued events.`);\n\n // Process each queued event\n for (const { event, params } of this.eventQueue) {\n this.handleEvent(event, params);\n }\n\n // Clear the queue\n this.eventQueue = [];\n }\n\n /**\n * Shutdown the subscriber and all adapters\n */\n public shutdown(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n\n this.initialized = false;\n this.eventQueue = [];\n }\n\n /**\n * Get all registered adapters\n */\n public getAdapters(): TrackingAdapter[] {\n return [...this.adapters];\n }\n}\n\n// Export singleton instance\nexport const eventSubscriber = EventSubscriber.getInstance();\n","/**\n * @shopkit/analytics\n *\n * Unified analytics tracking package for e-commerce storefronts.\n * Supports multiple analytics platforms with a single event publishing interface.\n *\n * ## Supported Platforms\n * - Google Analytics 4\n * - Facebook Pixel (single and multi-pixel)\n * - MoEngage\n * - PostHog\n * - Shopify Analytics\n * - KwikPass\n * - KwikCheckout\n *\n * ## Usage\n *\n * ```typescript\n * import { ShopkitAnalytics, publishEvent, EventType } from '@shopkit/analytics';\n *\n * // In your app layout\n * <ShopkitAnalytics config={{\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * posthog: { apiKey: 'phc_xxx', apiHost: 'https://app.posthog.com' },\n * }} />\n *\n * // Track events anywhere in your app\n * publishEvent({\n * type: EventType.ADD_TO_CART,\n * productId: 'prod_123',\n * productName: 'Example Product',\n * price: 29.99,\n * currency: 'USD',\n * });\n * ```\n *\n * @packageDocumentation\n */\n\n// Export main ShopkitAnalytics component\nexport { default as ShopkitAnalytics, default } from \"./ShopkitAnalytics\";\n\nexport type {\n ShopkitAnalyticsConfig,\n ShopkitAnalyticsProps,\n} from \"./ShopkitAnalytics\";\n\n// Export event tracking functionality\nexport {\n eventPublisher,\n publishEvent,\n eventSubscriber,\n initializeEventTracking,\n initTracking,\n} from \"./events\";\nexport type { TrackingAdapter } from \"./events\";\n\n// Export affiliate tracking functionality\nexport {\n AffiliateTracker,\n useAffiliateTracker,\n useHasAffiliateData,\n useAffiliateSource,\n captureAffiliateParams,\n getAffiliateParams,\n clearAffiliateParams,\n hasAffiliateData,\n getAffiliateSource,\n} from \"./affiliate\";\nexport type {\n AffiliateTrackerProps,\n AffiliateParams,\n AffiliateData,\n AffiliateConfig,\n} from \"./affiliate\";\n\n// Export experiment tracking functionality\nexport {\n getExperimentParams,\n hasExperimentData,\n PRIMA_EXPERIMENT_COOKIES,\n PRIMA_EXPERIMENT_COOKIE_NAMES,\n} from \"./experiment\";\nexport type { ExperimentData } from \"./experiment\";\n\n// Export shared types and constants\nexport * from \"./types\";\n\n// Export adapters\nexport * from \"./adapters\";\n\n// Export adapter parameter types\nexport type {\n TAdapterParams,\n IAdapterParams,\n IBaseAdapterParams,\n} from \"./adapter-params\";\n\n// Export utilities\nexport { generateEventId, getBrowserInfo } from \"./utils/event-id\";\n\n// Export logger\nexport * from \"./logger\";\n\n// Export Shopify components\nexport { ShopifyAnalyticsScript } from \"./shopify/ShopifyAnalyticsScript\";\n","\"use client\";\n\n/**\n * ShopkitAnalytics Component\n *\n * Main analytics provider component that initializes and manages\n * all configured analytics adapters.\n *\n * @module @shopkit/analytics\n */\n\nimport React, { useEffect } from \"react\";\nimport { initializeEventTracking } from \"./events/init\";\nimport { AffiliateTracker } from \"./affiliate\";\nimport { createLogger, type LoggerConfig } from \"./logger\";\nimport {\n GoogleAdapter,\n MultiPixelAdapter,\n MoengageAdapter,\n PostHogAdapter,\n ShopifyAdapter,\n} from \"./adapters\";\nimport type {\n GoogleAdapterConfig,\n MultiPixelAdapterConfig,\n MoengageAdapterConfig,\n PostHogAdapterConfig,\n ShopifyAdapterConfig,\n} from \"./adapters\";\nimport type { TrackingAdapter } from \"./events/subscriber\";\nimport type { AffiliateConfig } from \"./affiliate/types\";\nimport { ShopifyAnalyticsScript } from \"./shopify/ShopifyAnalyticsScript\";\n\n/**\n * Configuration for ShopkitAnalytics component\n *\n * @example\n * ```typescript\n * const config: ShopkitAnalyticsConfig = {\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * posthog: { apiKey: 'phc_xxx', apiHost: 'https://app.posthog.com' },\n * logger: { enabled: true, level: 'info' },\n * };\n * ```\n */\nexport interface ShopkitAnalyticsConfig {\n // Analytics Adapters\n googleAnalytics?: GoogleAdapterConfig;\n facebookMultiPixel?: MultiPixelAdapterConfig;\n moengage?: MoengageAdapterConfig;\n posthog?: PostHogAdapterConfig;\n shopify?: ShopifyAdapterConfig;\n customAdapters?: TrackingAdapter[];\n\n // Affiliate Tracking\n affiliate?: {\n enabled?: boolean;\n config?: Partial<AffiliateConfig>;\n autoCapture?: boolean;\n };\n\n // Logger Settings\n logger?: LoggerConfig;\n\n // General Settings (deprecated - use logger.enabled instead)\n enableDebugLogs?: boolean;\n autoInitialize?: boolean;\n}\n\n/**\n * Props for ShopkitAnalytics component\n */\nexport interface ShopkitAnalyticsProps {\n /** Analytics configuration object */\n config: ShopkitAnalyticsConfig;\n /** Optional children to render */\n children?: React.ReactNode;\n /** Callback when analytics initialization completes */\n onInitialized?: () => void;\n /** Callback when an error occurs during initialization */\n onError?: (error: Error) => void;\n}\n\n/**\n * ShopkitAnalytics Component\n *\n * The main analytics provider that initializes all configured tracking adapters\n * and sets up event publishing infrastructure.\n *\n * Place this component in your app's root layout to enable analytics tracking\n * throughout your application.\n *\n * @param props - Component props\n * @returns React component with analytics initialization and affiliate tracking\n *\n * @example\n * ```typescript\n * // In your root layout\n * import { ShopkitAnalytics } from '@shopkit/analytics';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <ShopkitAnalytics\n * config={{\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * }}\n * onInitialized={() => console.log('Analytics ready')}\n * onError={(err) => console.error('Analytics error:', err)}\n * >\n * {children}\n * </ShopkitAnalytics>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nconst ShopkitAnalytics: React.FC<ShopkitAnalyticsProps> = ({\n config,\n children,\n onInitialized,\n onError,\n}) => {\n useEffect(() => {\n const initializeAnalytics = async () => {\n if (config.autoInitialize === false) return;\n\n // Create logger instance\n const loggerConfig: LoggerConfig = {\n enabled: config.logger?.enabled ?? config.enableDebugLogs ?? true,\n level: config.logger?.level ?? \"info\",\n name: \"@shopkit/analytics\",\n prettyPrint: config.logger?.prettyPrint ?? false,\n };\n\n const logger = createLogger(loggerConfig);\n\n try {\n logger.info(\"Starting initialization...\");\n\n const adapters: TrackingAdapter[] = [];\n\n // Helper function to add logger config to adapter config\n const addLoggerConfig = (adapterConfig: any) => ({\n ...adapterConfig,\n enableDebugLogs: loggerConfig.enabled,\n logLevel: loggerConfig.level,\n });\n\n // Google Analytics 4\n if (config.googleAnalytics) {\n const gaAdapter = new GoogleAdapter(\n addLoggerConfig(config.googleAnalytics),\n );\n adapters.push(gaAdapter);\n logger.info(\"Added Google Analytics adapter\");\n }\n\n // Facebook Multi-Pixel\n if (config.facebookMultiPixel) {\n const multiPixelAdapter = new MultiPixelAdapter(\n addLoggerConfig(config.facebookMultiPixel),\n );\n adapters.push(multiPixelAdapter);\n logger.info(\n `Added Facebook Multi-Pixel adapter with ${config.facebookMultiPixel.pixels.length} pixels`,\n );\n }\n\n // MoEngage\n if (config.moengage) {\n const moengageAdapter = new MoengageAdapter(\n addLoggerConfig(config.moengage),\n );\n adapters.push(moengageAdapter);\n logger.info(\"Added MoEngage adapter\");\n }\n\n // PostHog\n if (config.posthog) {\n const posthogAdapter = new PostHogAdapter(\n addLoggerConfig(config.posthog),\n );\n adapters.push(posthogAdapter);\n logger.info(\"Added PostHog adapter\");\n }\n\n // Shopify Analytics\n if (config.shopify) {\n const shopifyAdapter = new ShopifyAdapter(\n addLoggerConfig(config.shopify),\n );\n adapters.push(shopifyAdapter);\n logger.info(\"Added Shopify Analytics adapter\");\n }\n\n // Custom adapters\n if (config.customAdapters) {\n adapters.push(...config.customAdapters);\n logger.info(`Added ${config.customAdapters.length} custom adapters`);\n }\n\n if (adapters.length === 0) {\n logger.warn(\"No analytics adapters configured\");\n } else {\n // Initialize the event tracking system\n await initializeEventTracking(adapters);\n logger.info(\"Event tracking initialized with adapters\", {\n adapters: adapters.map((a) => a.name),\n });\n }\n\n logger.info(\"Initialization completed successfully\");\n onInitialized?.();\n } catch (err) {\n const error =\n err instanceof Error\n ? err\n : new Error(\"Unknown initialization error\");\n logger.error(\"Initialization failed\", error);\n onError?.(error);\n }\n };\n\n initializeAnalytics();\n }, [config, onInitialized, onError]);\n\n return (\n <>\n {/* Affiliate Tracker */}\n {config.affiliate?.enabled !== false && (\n <AffiliateTracker\n config={config.affiliate?.config}\n autoCapture={config.affiliate?.autoCapture}\n />\n )}\n\n {/* Shopify Analytics Script - Only render if Shopify config is provided */}\n {config.shopify?.domain && (\n <ShopifyAnalyticsScript domain={config.shopify.domain} />\n )}\n\n {children ? <>{children}</> : null}\n </>\n );\n};\n\nexport default ShopkitAnalytics;\n","/**\n * Logger configuration options\n */\nexport interface LoggerConfig {\n level?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n enabled?: boolean;\n name?: string;\n prettyPrint?: boolean;\n redact?: string[];\n}\n\n/**\n * Logger interface for consistent logging across adapters\n */\nexport interface Logger {\n trace: (message: string, ...args: any[]) => void;\n debug: (message: string, ...args: any[]) => void;\n info: (message: string, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, error?: Error, ...args: any[]) => void;\n fatal: (message: string, error?: Error, ...args: any[]) => void;\n child: (bindings: Record<string, any>) => Logger;\n}\n\n/**\n * Log levels with numeric values for comparison\n */\nconst LOG_LEVELS = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n} as const;\n\n/**\n * No-op logger for when logging is disabled\n */\nclass NoOpLogger implements Logger {\n trace() {}\n debug() {}\n info() {}\n warn() {}\n error() {}\n fatal() {}\n child(): Logger {\n return new NoOpLogger();\n }\n}\n\n/**\n * Simple universal logger that works in all environments\n */\nclass UniversalLogger implements Logger {\n private config: Required<LoggerConfig>;\n private bindings: Record<string, any>;\n\n constructor(\n config: Required<LoggerConfig>,\n bindings: Record<string, any> = {}\n ) {\n this.config = config;\n this.bindings = bindings;\n }\n\n private shouldLog(level: keyof typeof LOG_LEVELS): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[this.config.level];\n }\n\n private formatMessage(\n level: string,\n message: string,\n args: any[],\n error?: Error\n ): string {\n const timestamp = new Date().toISOString();\n const name = this.config.name;\n\n let logMessage = this.config.prettyPrint\n ? `[${timestamp}] ${level.toUpperCase()} [${name}]: ${message}`\n : JSON.stringify({\n timestamp,\n level,\n name,\n message,\n ...this.bindings,\n ...(args.length > 0 && { args }),\n ...(error && {\n error: { message: error.message, stack: error.stack },\n }),\n });\n\n if (this.config.prettyPrint && args.length > 0) {\n logMessage += ` ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`;\n }\n\n if (this.config.prettyPrint && error) {\n logMessage += ` Error: ${error.message}`;\n if (error.stack) {\n logMessage += `\\n${error.stack}`;\n }\n }\n\n return this.redactSensitiveData(logMessage);\n }\n\n private redactSensitiveData(message: string): string {\n let redactedMessage = message;\n for (const field of this.config.redact) {\n const regex = new RegExp(`\"${field}\"\\\\s*:\\\\s*\"[^\"]*\"`, \"gi\");\n redactedMessage = redactedMessage.replace(\n regex,\n `\"${field}\":\"[REDACTED]\"`\n );\n }\n return redactedMessage;\n }\n\n private log(\n level: keyof typeof LOG_LEVELS,\n message: string,\n args: any[],\n error?: Error\n ): void {\n if (!this.shouldLog(level)) return;\n\n const formattedMessage = this.formatMessage(level, message, args, error);\n\n // Use appropriate console method based on level\n switch (level) {\n case \"trace\":\n console.trace(formattedMessage);\n break;\n case \"debug\":\n console.debug(formattedMessage);\n break;\n case \"info\":\n console.info(formattedMessage);\n break;\n case \"warn\":\n console.warn(formattedMessage);\n break;\n case \"error\":\n case \"fatal\":\n console.error(formattedMessage);\n break;\n }\n }\n\n trace(message: string, ...args: any[]): void {\n this.log(\"trace\", message, args);\n }\n\n debug(message: string, ...args: any[]): void {\n this.log(\"debug\", message, args);\n }\n\n info(message: string, ...args: any[]): void {\n this.log(\"info\", message, args);\n }\n\n warn(message: string, ...args: any[]): void {\n this.log(\"warn\", message, args);\n }\n\n error(message: string, error?: Error, ...args: any[]): void {\n this.log(\"error\", message, args, error);\n }\n\n fatal(message: string, error?: Error, ...args: any[]): void {\n this.log(\"fatal\", message, args, error);\n }\n\n child(bindings: Record<string, any>): Logger {\n return new UniversalLogger(this.config, { ...this.bindings, ...bindings });\n }\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(config: LoggerConfig = {}): Logger {\n const fullConfig: Required<LoggerConfig> = {\n level: config.level || \"info\",\n enabled: config.enabled !== false,\n name: config.name || \"@shopkit/analytics\",\n prettyPrint: config.prettyPrint || false,\n redact: config.redact || [],\n };\n\n // Return no-op logger if disabled\n if (!fullConfig.enabled) {\n return new NoOpLogger();\n }\n\n return new UniversalLogger(fullConfig);\n}\n\n/**\n * Default logger instance\n */\nexport const logger = createLogger({\n enabled: true,\n level: \"info\",\n prettyPrint: false,\n});\n\n/**\n * Create adapter-specific logger\n */\nexport function createAdapterLogger(\n adapterName: string,\n config: LoggerConfig = {}\n): Logger {\n const baseLogger = createLogger(config);\n return baseLogger.child({ adapter: adapterName });\n}\n","/**\n * Prima PR A/B test experiment cookie names\n */\nexport const PRIMA_EXPERIMENT_COOKIES = {\n HOME: \"_prima_ptr_ab_home\",\n COLLECTION: \"_prima_ptr_ab_collection\",\n PRODUCT: \"_prima_ptr_ab_product\",\n} as const;\n\n/**\n * Array of all Prima experiment cookie names for iteration\n */\nexport const PRIMA_EXPERIMENT_COOKIE_NAMES = Object.values(\n PRIMA_EXPERIMENT_COOKIES\n);\n","import type { ExperimentData } from \"./types\";\nimport {\n PRIMA_EXPERIMENT_COOKIES,\n PRIMA_EXPERIMENT_COOKIE_NAMES,\n} from \"./constants\";\n\n/**\n * Get cookie value by name\n */\nfunction getCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts.length === 2) {\n return parts.pop()?.split(\";\").shift() || null;\n }\n return null;\n}\n\n/**\n * Get experiment parameters from cookies\n */\nexport function getExperimentParams(): ExperimentData {\n const payload = {\n [PRIMA_EXPERIMENT_COOKIES.HOME]: getCookie(PRIMA_EXPERIMENT_COOKIES.HOME),\n [PRIMA_EXPERIMENT_COOKIES.COLLECTION]: getCookie(\n PRIMA_EXPERIMENT_COOKIES.COLLECTION\n ),\n [PRIMA_EXPERIMENT_COOKIES.PRODUCT]: getCookie(\n PRIMA_EXPERIMENT_COOKIES.PRODUCT\n ),\n };\n\n return payload;\n}\n\n/**\n * Check if any experiment data exists\n */\nexport function hasExperimentData(): boolean {\n return PRIMA_EXPERIMENT_COOKIE_NAMES.some(\n (cookieName) => getCookie(cookieName) !== null\n );\n}\n","import type { TEvent } from \"../types\";\nimport type { TrackingAdapter } from \"../events/subscriber\";\nimport type { TAdapterParams, IBaseAdapterParams } from \"../adapter-params\";\nimport { createAdapterLogger, type Logger, type LoggerConfig } from \"../logger\";\nimport { getExperimentParams } from \"../experiment/experiment-tracker\";\nimport type { ExperimentData } from \"../experiment/types\";\nimport { PRIMA_EXPERIMENT_COOKIES } from \"../experiment\";\n\n/**\n * Abstract base class for tracking adapters\n */\nexport abstract class BaseAdapter implements TrackingAdapter {\n /**\n * Name of the tracking adapter\n */\n public abstract readonly name: string;\n\n /**\n * Configuration for the adapter\n */\n protected config: Record<string, any>;\n\n /**\n * Logger instance for this adapter\n */\n protected logger: Logger;\n\n /**\n * Whether the adapter has been initialized\n */\n protected initialized = false;\n\n /**\n * Constructor\n * @param config Configuration for the adapter\n */\n constructor(config: Record<string, any> = {}) {\n this.config = config;\n\n // Create a generic logger - will be properly initialized by subclasses\n const loggerConfig: LoggerConfig = {\n enabled: config.enableDebugLogs ?? true,\n level: config.logLevel ?? \"info\",\n name: \"@shopkit/analytics\",\n };\n\n this.logger = createAdapterLogger(\"BaseAdapter\", loggerConfig);\n }\n\n /**\n * Initialize logger with proper adapter name\n * Should be called by subclasses after name is available\n */\n protected initializeLogger(): void {\n const loggerConfig: LoggerConfig = {\n enabled: this.config.enableDebugLogs ?? true,\n level: this.config.logLevel ?? \"info\",\n name: \"@shopkit/analytics\",\n };\n\n this.logger = createAdapterLogger(this.name, loggerConfig);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return this.initialized;\n }\n\n /**\n * Initialize the adapter\n */\n public abstract initialize(): Promise<void>;\n\n /**\n * Track an event\n * @param event The event to track\n * @param params Optional adapter-specific parameters\n */\n public abstract trackEvent(\n event: TEvent,\n params?: TAdapterParams\n ): Promise<void>;\n\n /**\n * Extract adapter-specific parameters for this adapter\n * @param params The adapter parameters object\n * @returns Adapter-specific parameters or empty object\n */\n protected getAdapterParams(params?: TAdapterParams): IBaseAdapterParams {\n return params?.[this.name] || {};\n }\n\n /**\n * Get custom event name or fall back to default\n * @param params The adapter parameters object\n * @param defaultName The default event name to use\n * @returns Custom event name or default\n */\n protected getEventName(\n params: TAdapterParams | undefined,\n defaultName: string\n ): string {\n const adapterParams = this.getAdapterParams(params);\n return adapterParams.event_name || defaultName;\n }\n\n /**\n * Merge standard event data with adapter-specific parameters\n * @param params The adapter parameters object\n * @param standardData The standard event data\n * @returns Merged data with adapter-specific overrides\n */\n protected mergeEventData(\n standardData: Record<string, any>,\n params: TAdapterParams | undefined\n ): Record<string, any> {\n const adapterParams = this.getAdapterParams(params);\n\n // Remove event_name from adapter params to avoid conflicts\n const { event_name, ...customParams } = adapterParams;\n\n // Merge with priority: adapter-specific > standard\n return {\n ...standardData,\n ...customParams,\n };\n }\n\n /**\n * Get a configuration value\n * @param key The configuration key\n * @param defaultValue The default value if the key is not found\n */\n protected getConfig<T>(key: string, defaultValue?: T): T {\n return key in this.config ? this.config[key] : (defaultValue as T);\n }\n\n /**\n * Get affiliate parameters from session storage or custom implementation\n * Override this method to provide your own affiliate tracking implementation\n * @returns Affiliate parameters or null if not available\n */\n protected getAffiliateParams(): Record<string, string> | null {\n // Default implementation returns null\n // Users can override this method to integrate with their affiliate tracking system\n return null;\n }\n\n /**\n * Get experiment parameters from cookies\n * @returns Experiment parameters\n */\n protected getExperimentParams(): ExperimentData {\n try {\n return getExperimentParams();\n } catch (error) {\n // Silently fail if experiment tracking is not available\n return {\n [PRIMA_EXPERIMENT_COOKIES.HOME]: null,\n [PRIMA_EXPERIMENT_COOKIES.COLLECTION]: null,\n [PRIMA_EXPERIMENT_COOKIES.PRODUCT]: null,\n };\n }\n }\n\n /**\n * Enhance event parameters with affiliate data\n * @param params The original parameters\n * @returns Parameters enhanced with affiliate data\n */\n protected enhanceWithAffiliateParams(\n params: Record<string, any>\n ): Record<string, any> {\n const affiliateParams = this.getAffiliateParams();\n if (!affiliateParams) return params;\n\n return {\n ...params,\n // Add affiliate parameters\n ...affiliateParams,\n };\n }\n\n /**\n * Enhance event parameters with experiment data\n * @param params The original parameters\n * @returns Parameters enhanced with experiment data\n */\n protected enhanceWithExperimentParams(\n params: Record<string, any>\n ): Record<string, any> {\n const experimentParams = this.getExperimentParams();\n\n return {\n ...params,\n experiment: experimentParams,\n };\n }\n}\n","/**\n * Event types that can be tracked across the application\n * Organized by category for better maintainability and understanding\n */\nexport enum EventType {\n // ============================================================================\n // CORE E-COMMERCE EVENTS\n // Standard events used across all analytics platforms\n // ============================================================================\n\n /** Basic page view tracking */\n PAGE_VIEW = \"page_view\",\n\n /** Product viewing and interaction events */\n VIEW_CONTENT = \"view_content\",\n VIEWED_PRODUCT = \"viewed_product\",\n\n /** Shopping cart events */\n ADD_TO_CART = \"add_to_cart\",\n REMOVE_FROM_CART = \"remove_from_cart\",\n CART_VIEWED = \"cart_viewed\",\n\n /** Checkout flow events */\n INITIATE_CHECKOUT = \"initiate_checkout\",\n ADD_PAYMENT_INFO = \"add_payment_info\",\n PURCHASE = \"purchase\",\n\n /** Search and discovery events */\n SEARCH = \"search\",\n VIEW_SEARCH_RESULTS = \"view_search_results\",\n\n // ============================================================================\n // USER AUTHENTICATION EVENTS\n // Events specific to MoEngage for user lifecycle tracking\n // ============================================================================\n\n /** User account creation tracking */\n USER_SIGNUP = \"user_signup\",\n\n /** User login tracking */\n USER_LOGIN = \"user_login\",\n\n // ============================================================================\n // PLATFORM-SPECIFIC EVENTS\n // Events for specific platform integrations\n // ============================================================================\n\n /** Shopify analytics integration - Do Not Remove */\n SHOPIFY_PAGE_VIEW = \"shopify_page_view\",\n\n // ============================================================================\n // CUSTOM EVENTS\n // Generic events for flexible tracking requirements\n // ============================================================================\n\n /** Generic custom event for any tracking needs */\n CUSTOM = \"custom\",\n\n /** Specific custom event with predefined structure */\n SPECIFIC = \"specific\",\n}\n\n/**\n * Base event interface that all events should implement\n */\nexport interface BaseEvent {\n type: EventType;\n timestamp?: number;\n eventId?: string;\n event_category?: string;\n description?: string;\n [key: string]: any;\n}\n\n// ============================================================================\n// CORE ANALYTICS EVENTS\n// These are the fundamental events used across all analytics platforms\n// ============================================================================\n\n/**\n * Page view event - Tracks when a user views a page\n */\nexport interface IPageViewEvent extends BaseEvent {\n type: EventType.PAGE_VIEW;\n path: string;\n title: string;\n referrer?: string;\n}\n\n/**\n * Viewed product event - Triggered after user views a product for 20+ seconds\n */\nexport interface IViewedProductEvent extends BaseEvent {\n type: EventType.VIEWED_PRODUCT;\n productId: string;\n productName: string;\n price: number;\n currency: string;\n viewDuration?: number;\n}\n\n/**\n * Add to cart event - Tracks when user adds product to cart\n */\nexport interface IAddToCartEvent extends BaseEvent {\n type: EventType.ADD_TO_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity?: number;\n variant?: string;\n}\n\n/**\n * Remove from cart event - Tracks when user removes product from cart\n */\nexport interface IRemoveFromCartEvent extends BaseEvent {\n type: EventType.REMOVE_FROM_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Cart viewed event - Tracks when user views their cart\n */\nexport interface ICartViewedEvent extends BaseEvent {\n type: EventType.CART_VIEWED;\n cartId: string;\n products: Array<{\n variantId: string;\n price: number;\n quantity: number;\n }>;\n}\n\n/**\n * Search event - Tracks when user performs a search\n */\nexport interface ISearchEvent extends BaseEvent {\n type: EventType.SEARCH;\n searchTerm: string;\n content_ids: string[];\n resultsCount?: number;\n}\n\n/**\n * Add Payment Info event - Tracks when user adds payment information\n */\nexport interface IAddPaymentInfoEvent extends BaseEvent {\n type: EventType.ADD_PAYMENT_INFO;\n cartValue: number;\n currency?: string;\n itemCount: number;\n paymentType?: string;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n// ============================================================================\n// USER AUTHENTICATION EVENTS\n// Events specific to MoEngage for user authentication tracking\n// ============================================================================\n\n/**\n * User signup event - Tracks when a user creates an account\n */\nexport interface IUserSignupEvent extends BaseEvent {\n type: EventType.USER_SIGNUP;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * User login event - Tracks when a user logs into their account\n */\nexport interface IUserLoginEvent extends BaseEvent {\n type: EventType.USER_LOGIN;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n// ============================================================================\n// PLATFORM-SPECIFIC EVENTS\n// Events designed for specific analytics platforms\n// ============================================================================\n\n/**\n * View content event - Facebook Pixel specific event for content viewing\n */\nexport interface IViewContentEvent extends BaseEvent {\n type: EventType.VIEW_CONTENT;\n content_type?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n value?: number;\n currency?: string;\n items?: Array<any>;\n}\n\n/**\n * Purchase event - Facebook Pixel specific event for purchase tracking\n */\nexport interface IPurchaseEvent extends BaseEvent {\n type: EventType.PURCHASE;\n orderId?: string;\n cartValue?: number;\n currency?: string;\n itemCount?: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n transaction_id?: string;\n coupon?: string;\n shipping?: number;\n tax?: number;\n discount?: number | string;\n}\n\n/**\n * View search results event - Google Analytics 4 specific event\n */\nexport interface IViewSearchResultsEvent extends BaseEvent {\n type: EventType.VIEW_SEARCH_RESULTS;\n search_term?: string;\n}\n\n/**\n * Begin checkout event - Google Analytics 4 specific event for checkout initiation\n */\nexport interface IBeginCheckoutEvent extends BaseEvent {\n type: EventType.INITIATE_CHECKOUT;\n orderId?: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n coupon?: string;\n discount?: number | string;\n}\n\n// ============================================================================\n// CUSTOM EVENTS\n// Generic events for custom tracking needs\n// ============================================================================\n\n/**\n * Custom event - For any custom tracking requirements not covered by standard events\n */\nexport interface ICustomEvent extends BaseEvent {\n type: EventType.CUSTOM;\n}\n\n/**\n * Specific event - For specific tracking requirements with custom properties\n */\nexport interface ISpecificEvent extends BaseEvent {\n type: EventType.SPECIFIC;\n}\n\n// ============================================================================\n// SHOPIFY EVENTS\n// Events specific to Shopify platform integration\n// ============================================================================\n\n/**\n * Shopify page view event - Tracks page views specifically for Shopify analytics\n */\nexport interface IShopifyPageViewEvent extends BaseEvent {\n type: EventType.SHOPIFY_PAGE_VIEW;\n path?: string;\n}\n\n/**\n * Union type of all possible events\n */\nexport type TEvent =\n | IPageViewEvent\n | IAddToCartEvent\n | IRemoveFromCartEvent\n | ICartViewedEvent\n | ISearchEvent\n | IUserSignupEvent\n | IUserLoginEvent\n | IViewContentEvent\n | IPurchaseEvent\n | IViewSearchResultsEvent\n | IBeginCheckoutEvent\n | ICustomEvent\n | ISpecificEvent\n | IAddPaymentInfoEvent\n | IViewedProductEvent\n | IShopifyPageViewEvent;\n","/**\n * Generate a unique event ID for deduplication\n * Format: timestamp_randomString_eventType\n */\nexport function generateEventId(eventType: string): string {\n const timestamp = Date.now();\n const randomString = Math.random().toString(36).substring(2, 8);\n return `${timestamp}_${randomString}_${eventType}`;\n}\n\n/**\n * Extract browser information for CAPI user data\n */\nexport function getBrowserInfo(): {\n clientUserAgent?: string;\n fbc?: string;\n fbp?: string;\n} {\n if (typeof window === \"undefined\") {\n return {};\n }\n\n const userAgent = navigator.userAgent;\n\n // Get Facebook click ID from URL or cookies\n const fbc = getFacebookClickId();\n const fbp = getFacebookBrowserId();\n\n return {\n clientUserAgent: userAgent,\n fbc,\n fbp,\n };\n}\n\n/**\n * Get Facebook click ID (fbc) from URL parameters or cookies\n * CRITICAL: fbc must be consistent for deduplication to work\n */\nfunction getFacebookClickId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n // Check cookies first (most reliable, already set by Facebook)\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbc\") {\n return value;\n }\n }\n\n // Check URL parameters as fallback (from ad click)\n // Use the fbclid directly without adding timestamp\n // Facebook sets _fbc cookie automatically, so this shouldn't be needed\n const urlParams = new URLSearchParams(window.location.search);\n const fbclid = urlParams.get(\"fbclid\");\n\n if (fbclid) {\n // Return the fbclid as-is, don't add dynamic timestamp\n // Facebook's pixel will set the proper _fbc cookie\n return fbclid;\n }\n\n return undefined;\n}\n\n/**\n * Get Facebook browser ID (fbp) from cookies\n */\nfunction getFacebookBrowserId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbp\") {\n return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Get client IP address from request headers\n */\nexport function getClientIpAddress(request: any): string | \"\" {\n // Try different headers for IP address\n const h = request.headers;\n\n const candidates = [\n h.get(\"cf-connecting-ip\"),\n h.get(\"true-client-ip\"),\n h.get(\"x-vercel-forwarded-for\"), // Vercel specific\n h.get(\"x-forwarded-for\"),\n h.get(\"x-real-ip\"),\n ].filter(Boolean) as string[];\n\n if (candidates.length === 0) {\n return \"\";\n }\n\n // x-forwarded-for can be a list: \"client, proxy1, proxy2\"\n const first = candidates[0].split(\",\")[0].trim();\n\n // Optional: normalize IPv6-wrapped IPv4 like \"::ffff:1.2.3.4\"\n const ip = first.startsWith(\"::ffff:\") ? first.replace(\"::ffff:\", \"\") : first;\n\n return ip || \"\";\n}\n","import { EventType } from \"../types\";\n\nexport const SKIP_GOKWIK_EVENT = [\n EventType.INITIATE_CHECKOUT,\n EventType.ADD_PAYMENT_INFO,\n EventType.PURCHASE,\n];\n","/**\n * PII Hashing Utilities for Facebook CAPI\n *\n * Provides SHA-256 hashing functions for Personally Identifiable Information\n * before sending to Facebook's Conversion API. All functions normalize input\n * according to Facebook's guidelines.\n *\n * Reference: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters\n */\n\n/**\n * Generic hash function for strings using SHA-256\n * @param value String to hash\n * @param normalize Optional normalization function to apply before hashing\n * @returns Promise resolving to SHA-256 hash or fallback hash\n */\nexport async function hashString(\n value: string | undefined | null,\n normalize?: (v: string) => string\n): Promise<string | undefined> {\n if (!value) {\n return undefined;\n }\n\n try {\n const normalizedValue = normalize ? normalize(value) : value;\n\n // Use Web Crypto API if available (modern browsers and Node.js)\n if (typeof crypto !== \"undefined\" && crypto.subtle) {\n const encoder = new TextEncoder();\n const data = encoder.encode(normalizedValue);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return hashHex;\n }\n } catch (error) {\n console.error(\"Error hashing with SHA-256:\", error);\n }\n\n // Fallback to simple hash if Web Crypto not available\n return fallbackHash(value);\n}\n\n/**\n * Hash email address\n * Normalized: trimmed and lowercase\n * @param email Email address to hash\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashEmail(\n email: string | undefined | null\n): Promise<string | undefined> {\n return hashString(email, (value) =>\n value.trim().toLowerCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Hash phone number\n * Normalized: trimmed, lowercase, only digits\n * @param phone Phone number to hash\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashPhone(\n phone: string | undefined | null\n): Promise<string | undefined> {\n return hashString(phone, (value) =>\n value\n .trim()\n .toLowerCase()\n .replace(/\\D/g, \"\") // Remove all non-digits\n );\n}\n\n/**\n * Hash first name\n * Normalized: trimmed and lowercase\n * @param firstName First name to hash\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashFirstName(\n firstName: string | undefined | null\n): Promise<string | undefined> {\n return hashString(firstName, (value) =>\n value.trim().toLowerCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Hash last name\n * Normalized: trimmed and lowercase\n * @param lastName Last name to hash\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashLastName(\n lastName: string | undefined | null\n): Promise<string | undefined> {\n return hashString(lastName, (value) =>\n value.trim().toLowerCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Hash IP address\n * Normalized: trimmed\n * @param ip IP address to hash\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashIP(\n ip: string | undefined | null\n): Promise<string | undefined> {\n return hashString(ip, (value) => value.trim());\n}\n\n/**\n * Hash country code\n * Normalized: trimmed and uppercase\n * @param country Country code (US, CA, etc.)\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashCountry(\n country: string | undefined | null\n): Promise<string | undefined> {\n return hashString(country, (value) =>\n value.trim().toUpperCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Hash state/province code\n * Normalized: trimmed and uppercase\n * @param state State/province code\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashState(\n state: string | undefined | null\n): Promise<string | undefined> {\n return hashString(state, (value) =>\n value.trim().toUpperCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Hash zip/postal code\n * Normalized: trimmed and lowercase\n * @param zip Zip/postal code\n * @returns Promise resolving to SHA-256 hash\n */\nexport async function hashZip(\n zip: string | undefined | null\n): Promise<string | undefined> {\n return hashString(zip, (value) =>\n value.trim().toLowerCase().replace(/\\s+/g, \"\")\n );\n}\n\n/**\n * Utility function to hash multiple PII fields at once\n * @param pii Object containing PII fields\n * @returns Promise resolving to object with hashed fields\n */\nexport async function hashPIIFields(pii: {\n email?: string;\n phone?: string;\n firstName?: string;\n lastName?: string;\n country?: string;\n state?: string;\n zip?: string;\n dateOfBirth?: string;\n}): Promise<{\n em?: string;\n ph?: string;\n fn?: string;\n ln?: string;\n country?: string;\n st?: string;\n zp?: string;\n db?: string;\n}> {\n const [em, ph, fn, ln, country, st, zp, db] = await Promise.all([\n pii.email ? hashEmail(pii.email) : undefined,\n pii.phone ? hashPhone(pii.phone) : undefined,\n pii.firstName ? hashFirstName(pii.firstName) : undefined,\n pii.lastName ? hashLastName(pii.lastName) : undefined,\n pii.country ? hashCountry(pii.country) : undefined,\n pii.state ? hashState(pii.state) : undefined,\n pii.zip ? hashZip(pii.zip) : undefined,\n pii.dateOfBirth ? hashString(pii.dateOfBirth?.trim(), (v) => v) : undefined,\n ]);\n\n return {\n ...(em && { em }),\n ...(ph && { ph }),\n ...(fn && { fn }),\n ...(ln && { ln }),\n ...(country && { country }),\n ...(st && { st }),\n ...(zp && { zp }),\n ...(db && { db }),\n };\n}\n\n/**\n * Simple hash fallback for browsers without Web Crypto API\n * This uses a basic string hashing algorithm (not cryptographically secure)\n * @param value String to hash\n * @returns Hex-encoded hash string\n */\nfunction fallbackHash(value: string): string {\n let hash = 0;\n\n if (value.length === 0) {\n return \"0\";\n }\n\n for (let i = 0; i < value.length; i++) {\n const char = value.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n\n return Math.abs(hash).toString(16).padStart(16, \"0\");\n}\n\n/**\n * Check if crypto API is available in the current environment\n * @returns true if Web Crypto API is available\n */\nexport function isCryptoAvailable(): boolean {\n return typeof crypto !== \"undefined\" && crypto.subtle !== undefined;\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IViewContentEvent,\n type ISearchEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId, getBrowserInfo } from \"../utils/event-id\";\nimport { SKIP_GOKWIK_EVENT } from \"./constants\";\nimport { hashString } from \"../utils/pii-hashing\";\n\ndeclare global {\n interface Window {\n fbq?: (\n type: string,\n eventName: string,\n params?: Record<string, any>,\n options?: { eventID?: string; fbp?: string; fbc?: string },\n ) => void;\n }\n}\n\n/**\n * Configuration for a single Facebook Pixel\n */\ninterface SinglePixelConfig {\n /**\n * Facebook Pixel ID\n */\n pixelId: string;\n /**\n * Optional name/label for this pixel (for logging/debugging)\n */\n name?: string;\n /**\n * Enable server-side CAPI backup for this pixel\n * @default true\n */\n enableCAPI?: boolean;\n}\n\n/**\n * Configuration for the Multi-Pixel adapter\n */\nexport interface MultiPixelAdapterConfig {\n /**\n * Array of pixel configurations\n */\n pixels: SinglePixelConfig[];\n /**\n * Global CAPI setting (can be overridden per pixel)\n * @default true\n */\n enableCAPI?: boolean;\n\n /**\n * Skip certain events when GoKwik checkout is enabled to prevent duplicate tracking.\n * When true, events like checkout_initiated, purchase, and add_payment_info will be skipped\n * since GoKwik already tracks these events to Meta and Google if enabled.\n */\n gokwikEnabled?: boolean;\n}\n\n/**\n * Internal pixel instance for tracking\n */\ninterface PixelInstance {\n config: SinglePixelConfig;\n initialized: boolean;\n}\n\n/**\n * Multi-Pixel Facebook tracking adapter\n * Supports multiple Facebook Pixels with individual configurations\n */\nexport class MultiPixelAdapter extends BaseAdapter {\n public readonly name = \"MultiPixelFacebook\";\n private pixels: PixelInstance[] = [];\n\n constructor(config: MultiPixelAdapterConfig) {\n super(config);\n\n // Validate configuration\n if (!config.pixels || config.pixels.length === 0) {\n throw new Error(\n \"MultiPixelAdapter requires at least one pixel configuration\",\n );\n }\n\n // Initialize pixel instances\n this.pixels = config.pixels.map((pixelConfig) => ({\n config: {\n enableCAPI: config.enableCAPI ?? true,\n ...pixelConfig,\n },\n initialized: false,\n }));\n\n this.initializeLogger();\n }\n\n /**\n * Initialize all Facebook Pixels\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if fbq is available\n if (!window.fbq) {\n this.logger.warn(\n \"Facebook Pixel fbq not found. Make sure the script is loaded.\",\n );\n return;\n }\n\n // Initialize each pixel\n for (const pixel of this.pixels) {\n const { pixelId, name } = pixel.config;\n const pixelLabel = name || pixelId;\n\n try {\n // window.fbq!(\"init\", pixelId);\n pixel.initialized = true;\n } catch (error) {\n this.logger.error(\n `Failed to initialize pixel: ${pixelLabel}`,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n\n this.initialized = true;\n }\n\n protected shouldSkipEvent(eventType: EventType): boolean {\n const gokwikActive = this.getConfig(\"gokwikEnabled\", false);\n if (gokwikActive) {\n return SKIP_GOKWIK_EVENT.includes(eventType);\n }\n return false;\n }\n\n /**\n * Track an event across all configured pixels\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n // Skip events that GoKwik already tracks to prevent duplicate tracking\n if (this.shouldSkipEvent(event.type)) {\n return;\n }\n\n const timestamp = Date.now();\n\n const transformEvent = {\n ...event,\n eventId: event.eventId || generateEventId(event.type),\n timestamp: event.timestamp || timestamp,\n event_source_url:\n event.event_source_url || !(typeof window === \"undefined\")\n ? window.location.href\n : \"\",\n };\n\n // Track client-side once (fbq automatically sends to all initialized pixels)\n await this.trackClientSide(transformEvent, adapterParams);\n\n // Track server-side for each pixel (requires individual API calls)\n if (this.pixels.some((pixel) => pixel.config.enableCAPI)) {\n await this.trackServerSide(transformEvent, adapterParams);\n }\n }\n\n /**\n * Track event on client-side once (Facebook automatically sends to all initialized pixels)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n if (typeof window === \"undefined\" || !window.fbq) {\n this.logger.warn(\"Cannot track client-side event, fbq not available\", {\n eventType: event.type,\n });\n return;\n }\n\n // Check if any pixel is initialized\n const hasInitializedPixel = this.pixels.some((pixel) => pixel.initialized);\n if (!hasInitializedPixel) {\n this.logger.warn(\"No pixels initialized for client-side tracking\");\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams,\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n const browserInfo = getBrowserInfo();\n\n try {\n window.fbq(\"track\", eventName, enhancedParams, {\n eventID: event.eventId,\n fbc: browserInfo.fbc,\n fbp: browserInfo.fbp,\n });\n } catch (error) {\n console.error(\"Facebook Pixel tracking error:\", error);\n }\n }\n\n /**\n * Track event on server-side for all enabled pixels\n */\n private async trackServerSide(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n try {\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams,\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n const browserInfo = getBrowserInfo();\n\n const payload = {\n eventName,\n eventId: event.eventId,\n timestamp: event.timestamp,\n enhancedParams: enhancedParams,\n userInfo: browserInfo,\n };\n\n const endpoint = this.getConfig(\"capiEndpoint\", \"/api/events/multi\");\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n this.logger.error(`Server-side tracking failed: ${response.status}`);\n }\n } catch (error) {\n this.logger.error(\n `Server-side tracking failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n // Don't throw - analytics failures shouldn't break the user experience\n }\n }\n\n /**\n * Format event payload with pixel-specific customizations\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n switch (event.type) {\n case EventType.PAGE_VIEW: {\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, \"PageView\");\n baseParams = {\n event_source_url: pageViewEvent.event_source_url,\n };\n break;\n }\n\n case EventType.VIEW_CONTENT: {\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"ViewContent\");\n baseParams = {\n event_source_url: viewContentEvent.event_source_url,\n content_type: viewContentEvent.content_type || \"product\",\n content_ids: viewContentEvent.content_ids || [],\n content_name: viewContentEvent.content_name,\n content_category: viewContentEvent.content_category || \"product\",\n value: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || \"INR\",\n };\n break;\n }\n\n case EventType.ADD_TO_CART: {\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"AddToCart\");\n baseParams = {\n event_source_url: cartEvent.event_source_url,\n content_type: cartEvent.content_type || \"product\",\n content_ids: [cartEvent.productId],\n content_name: cartEvent.productName,\n value: cartEvent.price,\n currency: cartEvent.currency || \"INR\",\n };\n break;\n }\n\n case EventType.SEARCH: {\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, \"Search\");\n baseParams = {\n event_source_url: searchEvent.event_source_url,\n search_string: searchEvent.searchTerm,\n content_category: \"product\",\n content_ids: searchEvent.content_ids || [],\n };\n break;\n }\n\n case EventType.INITIATE_CHECKOUT: {\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"InitiateCheckout\");\n baseParams = {\n event_source_url: checkoutEvent.event_source_url,\n content_type: checkoutEvent.content_type || \"product\",\n currency: checkoutEvent.currency || \"INR\",\n value: checkoutEvent.cartValue,\n num_items:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n contents:\n checkoutEvent.items?.map((item) => ({\n id: item.productId,\n quantity: item.quantity || 1,\n item_price: item.price,\n })) || [],\n };\n break;\n }\n\n case EventType.PURCHASE: {\n const purchaseEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"Purchase\");\n baseParams = {\n event_source_url: purchaseEvent.event_source_url,\n content_type: purchaseEvent.content_type || \"product\",\n contents: purchaseEvent.contents || [],\n currency: purchaseEvent.currency || \"INR\",\n num_items:\n purchaseEvent.num_items || purchaseEvent.contents?.length || 0,\n value: purchaseEvent.value,\n order_id: purchaseEvent.order_id,\n city: hashString(purchaseEvent.city),\n postal_code: hashString(purchaseEvent.postal_code),\n surname: hashString(purchaseEvent.surname),\n };\n break;\n }\n\n default: {\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n }\n\n const enhancedParams = this.mergeEventData(baseParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n\n /**\n * Get configuration for all pixels\n */\n public getPixelConfigs(): SinglePixelConfig[] {\n return this.pixels.map((pixel) => pixel.config);\n }\n\n /**\n * Get initialization status for all pixels\n */\n public getPixelStatus(): Array<{\n pixelId: string;\n name?: string;\n initialized: boolean;\n }> {\n return this.pixels.map((pixel) => ({\n pixelId: pixel.config.pixelId,\n name: pixel.config.name,\n initialized: pixel.initialized,\n }));\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IViewedProductEvent,\n type IAddToCartEvent,\n type ISearchEvent,\n type IAddPaymentInfoEvent,\n type IViewSearchResultsEvent,\n type IBeginCheckoutEvent,\n type IViewContentEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\nimport { SKIP_GOKWIK_EVENT } from \"./constants\";\n\ndeclare global {\n interface Window {\n gtag?: (...args: any[]) => void;\n }\n}\n\n/**\n * Configuration for the Google Analytics adapter\n */\nexport interface GoogleAdapterConfig {\n /**\n * Google Analytics measurement ID (e.g., G-XXXXXXXXXX)\n */\n measurementId: string;\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n\n /**\n * Skip certain events when GoKwik checkout is enabled to prevent duplicate tracking.\n * When true, events like checkout_initiated, purchase, and add_payment_info will be skipped\n * since GoKwik already tracks these events to Meta and Google if enabled.\n */\n gokwikEnabled?: boolean;\n}\n\n/**\n * Google Analytics tracking adapter\n * Assumes that the Google Analytics script is already loaded in the page\n */\nexport class GoogleAdapter extends BaseAdapter {\n public readonly name = \"GoogleAnalytics\";\n\n constructor(config: GoogleAdapterConfig) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Initialize Google Analytics adapter\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if gtag is available\n if (!window.gtag) {\n this.logger.warn(\n \"Google Analytics gtag not found. Make sure the script is loaded.\"\n );\n return;\n }\n\n this.initialized = true;\n }\n\n protected shouldSkipEvent(eventType: EventType): boolean {\n const gokwikActive = this.getConfig(\"gokwikEnabled\", false);\n if (gokwikActive) {\n return SKIP_GOKWIK_EVENT.includes(eventType);\n }\n return false;\n }\n\n /**\n * Track an event with Google Analytics\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Skip events that GoKwik already tracks to prevent duplicate tracking\n if (this.shouldSkipEvent(event.type)) {\n return;\n }\n\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return this.initialized && typeof window !== \"undefined\" && !!window.gtag;\n }\n\n /**\n * Track event on client-side (browser Google Analytics)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\" || !window.gtag) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or gtag not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n window.gtag?.(\"event\", eventName, finalParams);\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n // Get the payload seprately\n const { type, ...payload } = event;\n\n switch (type) {\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"view_item\");\n baseParams = {\n currency: viewContentEvent.currency || \"USD\",\n value: viewContentEvent.value || 0,\n items:\n viewContentEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n };\n break;\n\n case EventType.VIEWED_PRODUCT:\n const viewedProductEvent = event as IViewedProductEvent;\n eventName = this.getEventName(adapterParams, \"viewed_product\");\n baseParams = {\n currency: viewedProductEvent.currency,\n value: viewedProductEvent.price,\n items: [\n {\n item_id: viewedProductEvent.productId,\n item_name: viewedProductEvent.productName,\n price: viewedProductEvent.price,\n currency: viewedProductEvent.currency,\n },\n ],\n view_duration: viewedProductEvent.viewDuration,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"add_to_cart\");\n baseParams = {\n currency: cartEvent.currency || \"INR\",\n value: cartEvent.price * (cartEvent.quantity || 1),\n items: [\n {\n item_id: cartEvent.productId,\n item_name: cartEvent.productName,\n price: cartEvent.price,\n quantity: cartEvent.quantity || 1,\n item_variant: cartEvent.variant,\n },\n ],\n };\n break;\n\n case EventType.SEARCH:\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, \"search\");\n baseParams = {\n search_term: searchEvent.searchTerm,\n page_location:\n typeof window !== \"undefined\" ? window.location.href : \"\",\n page_referrer:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_title: typeof document !== \"undefined\" ? document.title : \"\",\n };\n break;\n\n case EventType.VIEW_SEARCH_RESULTS:\n const viewSearchResultsEvent = event as IViewSearchResultsEvent;\n eventName = this.getEventName(adapterParams, \"view_search_results\");\n baseParams = {\n search_term: viewSearchResultsEvent.search_term,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"begin_checkout\");\n baseParams = {\n currency: checkoutEvent.currency || \"USD\",\n value: checkoutEvent.value || 0,\n coupon: checkoutEvent.coupon,\n items:\n checkoutEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n page_location:\n typeof window !== \"undefined\" ? window.location.href : \"\",\n page_referrer:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_title: typeof document !== \"undefined\" ? document.title : \"\",\n };\n break;\n\n case EventType.ADD_PAYMENT_INFO:\n const addPaymentInfoEvent = event as IAddPaymentInfoEvent;\n eventName = this.getEventName(adapterParams, \"add_payment_info\");\n baseParams = {\n currency: addPaymentInfoEvent.currency || \"INR\",\n value: addPaymentInfoEvent.cartValue,\n payment_type: addPaymentInfoEvent.paymentType || \"\",\n items:\n addPaymentInfoEvent.items?.map((item) => ({\n item_id: item.productId,\n item_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n item_variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.PURCHASE:\n const purchaseEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"purchase\");\n baseParams = {\n transaction_id: purchaseEvent.transaction_id,\n value: purchaseEvent.value,\n currency: purchaseEvent.currency || \"USD\",\n coupon: purchaseEvent.coupon,\n shipping: purchaseEvent.shipping,\n tax: purchaseEvent.tax,\n items:\n purchaseEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n };\n break;\n\n case EventType.CUSTOM:\n eventName = this.getEventName(adapterParams, \"custom\");\n baseParams = payload || {};\n break;\n\n case EventType.SPECIFIC:\n eventName = this.getEventName(adapterParams, \"\");\n if (!eventName) {\n this.logger.warn(`Skipping specific event with no event name`);\n return { eventName: \"\", enhancedParams: {} };\n }\n baseParams = payload || {};\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IRemoveFromCartEvent,\n type ISearchEvent,\n type IUserSignupEvent,\n type IUserLoginEvent,\n type IViewContentEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\n\nimport moengage from \"@moengage/web-sdk\";\n\n/**\n * Event name constants for tracking platforms\n */\nexport const EventNames = {\n // Page events\n PAGE_VIEWED: \"Page Viewed\",\n\n // Product events\n PRODUCT_VIEWED: \"Product Viewed\",\n ADDED_TO_CART: \"Added To Cart\",\n REMOVED_FROM_CART: \"Removed From Cart\",\n\n // Checkout events\n CHECKOUT_INITIATED: \"Checkout Started\",\n PURCHASE_COMPLETED: \"Purchase Completed\",\n\n // Search events\n SEARCH: \"Search\",\n\n // User events\n USER_SIGNED_UP: \"User Signed Up\",\n USER_LOGGED_IN: \"User Logged In\",\n};\n\n/**\n * Default currency code\n */\nexport const DEFAULT_CURRENCY = \"INR\";\n\n/**\n * Configuration for the MoenGage adapter\n */\nexport interface MoengageAdapterConfig {\n /**\n * MoenGage App ID (required for SDK initialization)\n */\n appId: string;\n /**\n * Whether to enable user identification\n */\n enableUserIdentification?: boolean;\n /**\n * Debug mode for MoenGage SDK\n */\n debug?: boolean;\n /**\n * Data center region (default: 'dc_01')\n */\n region?: string;\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n}\n\n/**\n * MoenGage tracking adapter using the official Web SDK\n */\nexport class MoengageAdapter extends BaseAdapter {\n public readonly name = \"MoEngage\";\n\n constructor(config: MoengageAdapterConfig) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Get MoEngage SDK instance from window\n */\n private getMoengageSDK(): any {\n return typeof window !== \"undefined\" ? (window as any).Moengage : null;\n }\n\n /**\n * Initialize the MoenGage adapter using the Web SDK\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n try {\n const appId = this.getConfig<string>(\"appId\");\n if (!appId) {\n this.logger.warn(\"App ID is required for initialization\");\n return;\n }\n\n // Initialize MoenGage SDK\n const region = this.getConfig<string>(\"region\", \"dc_01\");\n const config = {\n app_id: appId,\n debug_logs: this.getConfig<boolean>(\"debug\", false) ? 1 : 0,\n cluster: region,\n disableCookies: true,\n };\n\n // Initialize MoEngage SDK\n moengage.initialize(config);\n\n this.initialized = true;\n } catch (error) {\n this.logger.error(\"Failed to initialize\", error as Error);\n }\n }\n\n /**\n * Track an event with MoenGage SDK\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return (\n this.initialized &&\n typeof window !== \"undefined\" &&\n !!this.getMoengageSDK()\n );\n }\n\n /**\n * Track event on client-side (browser MoEngage)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n const sdk = this.getMoengageSDK();\n if (!this.initialized || typeof window === \"undefined\" || !sdk) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or SDK not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams, shouldIdentifyUser, userId } =\n this.formatEventPayload(event, adapterParams);\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n sdk?.track_event(eventName, finalParams);\n\n // Handle user identification for signup/login events\n if (\n shouldIdentifyUser &&\n userId &&\n this.getConfig<boolean>(\"enableUserIdentification\", true)\n ) {\n sdk?.add_unique_user_id(userId);\n }\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): {\n eventName: string;\n enhancedParams: Record<string, any>;\n shouldIdentifyUser?: boolean;\n userId?: string;\n } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n let shouldIdentifyUser = false;\n let userId: string | undefined;\n\n // Get the payload seprately\n const { type, ...payload } = event;\n\n switch (type) {\n case EventType.PAGE_VIEW:\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, EventNames.PAGE_VIEWED);\n baseParams = {\n page_location: pageViewEvent.page_location || pageViewEvent.path,\n page_title: pageViewEvent.page_title || pageViewEvent.title,\n page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n page_path: pageViewEvent.page_path || pageViewEvent.path,\n page_url: typeof window !== \"undefined\" ? window.location.href : \"\",\n referrer:\n pageViewEvent.referrer ||\n (typeof document !== \"undefined\" ? document.referrer : \"\"),\n };\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, EventNames.PRODUCT_VIEWED);\n baseParams = {\n content_type: viewContentEvent.content_type || \"product\",\n product_id: viewContentEvent.content_ids || [],\n product_name: viewContentEvent.content_name || \"\",\n category: viewContentEvent.content_category || \"\",\n price: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || DEFAULT_CURRENCY,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n const quantity = cartEvent.quantity ?? 1;\n eventName = this.getEventName(adapterParams, EventNames.ADDED_TO_CART);\n baseParams = {\n product_id: cartEvent.productId,\n product_name: cartEvent.productName,\n price: cartEvent.price,\n currency: cartEvent.currency || DEFAULT_CURRENCY,\n quantity: quantity,\n variant: cartEvent.variant,\n total_value: cartEvent.price * quantity,\n };\n break;\n\n case EventType.REMOVE_FROM_CART:\n const removeCartEvent = event as IRemoveFromCartEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.REMOVED_FROM_CART\n );\n baseParams = {\n product_id: removeCartEvent.productId,\n product_name: removeCartEvent.productName,\n price: removeCartEvent.price,\n currency: removeCartEvent.currency || DEFAULT_CURRENCY,\n quantity: removeCartEvent.quantity,\n variant: removeCartEvent.variant,\n total_value: removeCartEvent.price * removeCartEvent.quantity,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutStartedEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.CHECKOUT_INITIATED\n );\n baseParams = {\n cart_value: checkoutStartedEvent.cartValue,\n currency: checkoutStartedEvent.currency || DEFAULT_CURRENCY,\n item_count: checkoutStartedEvent.itemCount,\n items:\n checkoutStartedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.PURCHASE:\n const checkoutCompletedEvent = event as IPurchaseEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.PURCHASE_COMPLETED\n );\n baseParams = {\n order_id: checkoutCompletedEvent.orderId,\n cart_value: checkoutCompletedEvent.cartValue,\n currency: checkoutCompletedEvent.currency || DEFAULT_CURRENCY,\n item_count: checkoutCompletedEvent.itemCount,\n items:\n checkoutCompletedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.SEARCH:\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, EventNames.SEARCH);\n baseParams = {\n search_term: searchEvent.searchTerm,\n results_count: searchEvent.resultsCount,\n };\n break;\n\n case EventType.USER_SIGNUP:\n const signupEvent = event as IUserSignupEvent;\n eventName = this.getEventName(adapterParams, EventNames.USER_SIGNED_UP);\n baseParams = {\n user_id: signupEvent.userId,\n method: signupEvent.method,\n success: signupEvent.success,\n };\n shouldIdentifyUser = true;\n userId = signupEvent.userId;\n break;\n\n case EventType.USER_LOGIN:\n const loginEvent = event as IUserLoginEvent;\n eventName = this.getEventName(adapterParams, EventNames.USER_LOGGED_IN);\n baseParams = {\n user_id: loginEvent.userId,\n method: loginEvent.method,\n success: loginEvent.success,\n };\n shouldIdentifyUser = true;\n userId = loginEvent.userId;\n break;\n\n case EventType.CUSTOM:\n eventName = this.getEventName(adapterParams, \"custom\");\n baseParams = payload || {};\n break;\n\n case EventType.SPECIFIC:\n eventName = this.getEventName(adapterParams, \"\");\n if (!eventName) {\n this.logger.warn(`Skipping specific event with no event name`);\n return {\n eventName: \"\",\n enhancedParams: {},\n shouldIdentifyUser: false,\n };\n }\n baseParams = payload || {};\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {}, shouldIdentifyUser: false };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams, shouldIdentifyUser, userId };\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IViewContentEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\n\ndeclare global {\n interface Window {\n posthog?: {\n capture: (eventName: string, properties?: Record<string, any>) => void;\n identify: (distinctId: string, properties?: Record<string, any>) => void;\n };\n }\n}\n\n/**\n * Configuration for the PostHog adapter\n */\nexport interface PostHogAdapterConfig {\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n}\n\n/**\n * PostHog tracking adapter\n * Assumes that the PostHog script is already loaded in the page\n */\nexport class PostHogAdapter extends BaseAdapter {\n public readonly name = \"PostHog\";\n\n constructor(config: PostHogAdapterConfig = {}) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Initialize PostHog\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if posthog is available\n if (!window.posthog) {\n this.logger.warn(\n \"PostHog object not found. Make sure the script is loaded.\"\n );\n return;\n }\n\n this.initialized = true;\n }\n\n /**\n * Track an event with PostHog\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return (\n this.initialized && typeof window !== \"undefined\" && !!window.posthog\n );\n }\n\n /**\n * Track event on client-side (browser PostHog)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\" || !window.posthog) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or posthog not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n window.posthog?.capture(eventName, finalParams);\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n switch (event.type) {\n case EventType.PAGE_VIEW:\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, \"$pageview\");\n baseParams = {\n // PostHog-compatible parameters\n $current_url: pageViewEvent.page_location || pageViewEvent.path,\n $title: pageViewEvent.page_title || pageViewEvent.title,\n $referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n // Custom parameters\n page_location: pageViewEvent.page_location || pageViewEvent.path,\n page_title: pageViewEvent.page_title || pageViewEvent.title,\n page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n page_path: pageViewEvent.page_path || pageViewEvent.path,\n event_category: pageViewEvent.event_category,\n };\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"view_content\");\n baseParams = {\n content_type: viewContentEvent.content_type || \"product\",\n content_ids: viewContentEvent.content_ids || [],\n content_name: viewContentEvent.content_name || \"\",\n content_category: viewContentEvent.content_category || \"\",\n value: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || \"INR\",\n // PostHog specific format\n $product_id: viewContentEvent.content_ids || [],\n $product_name: viewContentEvent.content_name || \"\",\n $product_category: viewContentEvent.content_category || \"\",\n $product_price: viewContentEvent.value || 0,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"add_to_cart\");\n baseParams = {\n product_id: cartEvent.productId,\n product_name: cartEvent.productName,\n price: cartEvent.price,\n currency: cartEvent.currency || \"INR\",\n quantity: cartEvent.quantity,\n variant: cartEvent.variant,\n // PostHog specific format\n $product_id: cartEvent.productId,\n $product_name: cartEvent.productName,\n $product_price: cartEvent.price,\n $quantity: cartEvent.quantity,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"checkout_started\");\n baseParams = {\n currency: checkoutEvent.currency || \"INR\",\n value: checkoutEvent.cartValue,\n num_items:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n items:\n checkoutEvent.items?.map((item) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity || 1,\n variant: item.variant,\n })) || [],\n // PostHog specific format\n $cart_value: checkoutEvent.cartValue,\n $item_count:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n };\n break;\n\n case EventType.PURCHASE:\n const checkoutCompletedEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"purchase\");\n baseParams = {\n transaction_id: checkoutCompletedEvent.orderId,\n currency: checkoutCompletedEvent.currency || \"INR\",\n value: checkoutCompletedEvent.cartValue,\n num_items:\n checkoutCompletedEvent.itemCount ||\n checkoutCompletedEvent.items?.length ||\n 0,\n items:\n checkoutCompletedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity || 1,\n variant: item.variant,\n })) || [],\n // PostHog specific format\n $order_id: checkoutCompletedEvent.orderId,\n $order_value: checkoutCompletedEvent.cartValue,\n $order_currency: checkoutCompletedEvent.currency || \"INR\",\n $order_items_count:\n checkoutCompletedEvent.itemCount ||\n checkoutCompletedEvent.items?.length ||\n 0,\n };\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n}\n","import {\n sendShopifyAnalytics,\n getClientBrowserParameters,\n AnalyticsEventName,\n type ShopifyAnalyticsProduct,\n type ShopifyPageViewPayload,\n ShopifySalesChannel,\n} from \"@shopify/hydrogen-react\";\nimport { BaseAdapter } from \"./base-adapter\";\nimport type { TEvent } from \"../types\";\nimport { EventType } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\n\n// Constants based on environment variables\nconst DEFAULT_CURRENCY = \"INR\";\nconst DEFAULT_LANGUAGE = \"en\";\n\n/**\n * Type definitions for analytics payloads\n */\ntype SendPageViewPayload = {\n pageType?: string;\n products?: ShopifyAnalyticsProduct[];\n collectionHandle?: string;\n searchString?: string;\n totalValue?: number;\n cartId?: string;\n};\n\ntype SendAddToCartPayload = {\n cartId: string;\n products?: ShopifyAnalyticsProduct[];\n totalValue?: ShopifyPageViewPayload[\"totalValue\"];\n};\n\n/**\n * Configuration interface for Shopify Analytics Adapter\n */\nexport interface ShopifyAdapterConfig {\n shopId: string;\n domain: string;\n merchantName: string;\n currency?: string;\n}\n\n/**\n * Shopify Analytics Adapter for tracking events to Shopify Admin Analytics\n */\nexport class ShopifyAdapter extends BaseAdapter {\n public readonly name = \"ShopifyAnalytics\";\n private shopId: string;\n private domain: string;\n private currency: string;\n private merchantName: string;\n\n constructor(config: ShopifyAdapterConfig) {\n super(config);\n this.shopId = config.shopId;\n this.domain = config.domain;\n this.currency = config.currency || DEFAULT_CURRENCY;\n this.merchantName = config.merchantName;\n }\n\n /**\n * Initialize the Shopify Analytics adapter\n */\n public async initialize(): Promise<void> {\n this.initializeLogger();\n\n try {\n // Enable Shopify cookies for attribution tracking\n if (typeof window !== \"undefined\") {\n // Note: useShopifyCookies should be called at the React component level\n // This will be handled in the ShopkitAnalytics component\n }\n this.initialized = true;\n } catch (error) {\n this.logger.error(\n \"Failed to initialize Shopify Analytics\",\n error instanceof Error ? error : new Error(String(error))\n );\n throw error;\n }\n }\n\n /**\n * Convert product ID to Shopify GID format if it's not already\n */\n private formatProductGid(productId: string): string {\n return productId.startsWith(\"gid://shopify/Product/\")\n ? productId\n : `gid://shopify/Product/${productId}`;\n }\n\n /**\n * Get user consent status from your consent management system\n */\n private getUserConsent() {\n // Check if user has given consent (implement based on your consent system)\n const hasConsent = this.checkUserConsent();\n\n return {\n hasUserConsent: hasConsent,\n analyticsAllowed: hasConsent && this.checkAnalyticsConsent(),\n marketingAllowed: hasConsent && this.checkMarketingConsent(),\n saleOfDataAllowed: hasConsent && this.checkSaleOfDataConsent(),\n };\n }\n\n /**\n * Check user consent (implement based on your consent management)\n */\n private checkUserConsent(): boolean {\n // Example implementations:\n // return localStorage.getItem('user_consent') === 'true';\n // return document.cookie.includes('consent=granted');\n // return window.gtag?.('consent', 'query') === 'granted';\n\n // For now, return true but implement your actual consent logic\n return true;\n }\n\n private checkAnalyticsConsent(): boolean {\n // Implement your analytics consent check\n return true;\n }\n\n private checkMarketingConsent(): boolean {\n // Implement your marketing consent check\n return true;\n }\n\n private checkSaleOfDataConsent(): boolean {\n // Implement your sale of data consent check\n return true;\n }\n\n /**\n * Create base payload for all events\n */\n private createBasePayload(): any {\n const consent = this.getUserConsent();\n\n return {\n ...getClientBrowserParameters(),\n ...consent,\n storefrontId: this.shopId,\n shopifySalesChannel: ShopifySalesChannel.headless,\n shopId: `gid://shopify/Shop/${this.shopId}`,\n currency: this.currency,\n acceptedLanguage: DEFAULT_LANGUAGE,\n ...this.enhanceWithExperimentParams(this.enhanceWithAffiliateParams({})),\n };\n }\n\n /**\n * Send page view event using the enhanced functionality\n */\n public sendPageView = (\n eventName: keyof typeof AnalyticsEventName,\n payload?: SendPageViewPayload\n ) => {\n const enhancedPayload = {\n ...this.createBasePayload(),\n ...payload,\n };\n\n return sendShopifyAnalytics({\n eventName,\n payload: enhancedPayload,\n });\n };\n\n /**\n * Send add to cart event using the enhanced functionality\n */\n public sendAddToCart = ({\n cartId,\n totalValue,\n products,\n }: SendAddToCartPayload) => {\n return this.sendPageView(AnalyticsEventName.ADD_TO_CART, {\n cartId,\n totalValue,\n products,\n });\n };\n\n /**\n * Track an event using Shopify Analytics\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\") {\n this.logger.warn(\n \"Shopify Analytics not initialized or not in browser environment\"\n );\n return;\n }\n\n // Get adapter-specific parameters\n const params = this.getAdapterParams(adapterParams);\n const customEventName = this.getEventName(params, event.type);\n\n // Enhance event with affiliate and experiment data\n const affiliateParams = this.enhanceWithAffiliateParams(event);\n const enhancedEvent = this.enhanceWithExperimentParams(affiliateParams);\n\n try {\n switch (event.type) {\n case EventType.SHOPIFY_PAGE_VIEW:\n case EventType.PAGE_VIEW:\n const pageViewPayload = this.mergeEventData(enhancedEvent, params);\n this.sendPageView(AnalyticsEventName.PAGE_VIEW, pageViewPayload);\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentPayload = this.mergeEventData(enhancedEvent, params);\n this.sendPageView(\n AnalyticsEventName.PRODUCT_VIEW,\n viewContentPayload\n );\n break;\n\n case EventType.ADD_TO_CART:\n const addToCartPayload = this.mergeEventData(enhancedEvent, params);\n this.trackAddToCart(addToCartPayload);\n break;\n\n case EventType.INITIATE_CHECKOUT:\n // For checkout events, send as PAGE_VIEW with checkout page context\n const checkoutPayload = this.mergeEventData(\n { ...enhancedEvent, pageType: \"checkout\" },\n params\n );\n this.sendPageView(AnalyticsEventName.PAGE_VIEW, checkoutPayload);\n break;\n\n default:\n this.logger.warn(\"Event not supported by Shopify Analytics\", {\n eventType: event.type,\n });\n break;\n }\n } catch (error) {\n this.logger.error(\n \"Error tracking Shopify Analytics event\",\n error instanceof Error ? error : new Error(String(error)),\n { eventType: event.type }\n );\n }\n }\n\n /**\n * Check if Shopify session is properly established\n */\n public isSessionValid(): boolean {\n if (typeof window === \"undefined\") return false;\n\n const shopifyY = document.cookie.includes(\"_shopify_y=\");\n const shopifyS = document.cookie.includes(\"_shopify_s=\");\n\n return shopifyY && shopifyS;\n }\n\n /**\n * Get session debug information\n */\n public getSessionDebugInfo(): object {\n if (typeof window === \"undefined\")\n return { error: \"Not in browser environment\" };\n\n return {\n sessionValid: this.isSessionValid(),\n cookies: {\n shopify_y: document.cookie.includes(\"_shopify_y=\"),\n shopify_s: document.cookie.includes(\"_shopify_s=\"),\n all: document.cookie,\n },\n shopId: this.shopId,\n initialized: this.initialized,\n };\n }\n\n /**\n * Track add to cart event with enhanced error handling\n */\n private trackAddToCart(event: any): void {\n if (!event.productId) {\n this.logger.warn(\"ADD_TO_CART event missing productId\");\n return;\n }\n\n try {\n const productGid = this.formatProductGid(event.productId);\n const cartKey = `merchant_${this.merchantName}_cartId`;\n const cartId = localStorage.getItem(cartKey) || \"\";\n\n if (!cartId) {\n this.logger.warn(\"No cart ID found, creating anonymous session\");\n // You might want to generate a temporary cart ID or handle this case\n }\n\n // Validate product data\n if (!event.price || event.price <= 0) {\n this.logger.warn(\"Invalid or missing price for ADD_TO_CART\", {\n price: event.price,\n });\n }\n\n // Create products array for analytics\n const productPrice = Math.max(0, event.price || 0);\n const productQuantity = Math.max(1, event.quantity || 1);\n\n const products: ShopifyAnalyticsProduct[] = [\n {\n productGid: productGid,\n variantGid:\n event.variantId || productGid.replace(\"Product\", \"ProductVariant\"),\n quantity: productQuantity,\n price: productPrice.toString(), // Convert to string as required by ShopifyAnalyticsProduct\n name: event.productName || \"Unknown Product\",\n brand: event.brand || \"Unknown Brand\",\n },\n ];\n\n const totalValue = productPrice * productQuantity;\n\n // Use the enhanced sendAddToCart method\n this.sendAddToCart({\n cartId,\n products,\n totalValue,\n });\n } catch (error) {\n this.logger.error(\n \"Error in trackAddToCart\",\n error instanceof Error ? error : new Error(String(error))\n );\n // Don't throw - just log the error to prevent breaking the user experience\n }\n }\n}\n","import {\n GoogleAdapter,\n MoengageAdapter,\n PostHogAdapter,\n MultiPixelAdapter,\n} from \"../adapters\";\n\n/**\n * Initialize the event tracking system with the provided adapters\n * @param adapters Array of tracking adapters to register\n */\nexport async function initializeEventTracking(\n adapters: import(\"./subscriber\").TrackingAdapter[]\n): Promise<void> {\n // Import the subscriber\n const { eventSubscriber } = await import(\"./subscriber\");\n\n // Register each adapter using for...of instead of forEach\n for (const adapter of adapters) {\n eventSubscriber.registerAdapter(adapter);\n }\n\n // Initialize the subscriber\n await eventSubscriber.initialize();\n}\n\n/**\n * Example initialization function with common adapters\n * This is a convenience function that shows how to set up common tracking adapters\n * Users can customize this based on their needs\n */\nexport async function initTracking(config: {\n pixelId?: string;\n pixelIds?: string[];\n gaId?: string;\n moengageAppId?: string;\n moengageRegion?: string;\n enableDebugLogs?: boolean;\n}) {\n console.log(\"Initializing event tracking system...\");\n\n const adapters = [];\n\n // Facebook Pixel (Multi-Pixel)\n if (config.pixelId || config.pixelIds) {\n const pixelIds = config.pixelIds || (config.pixelId ? [config.pixelId] : []);\n if (pixelIds.length > 0) {\n const multiPixelAdapter = new MultiPixelAdapter({\n pixels: pixelIds.map((id) => ({ pixelId: id })),\n });\n adapters.push(multiPixelAdapter);\n }\n }\n\n // Google Analytics\n if (config.gaId) {\n const gaAdapter = new GoogleAdapter({\n measurementId: config.gaId,\n });\n adapters.push(gaAdapter);\n }\n\n // MoEngage\n if (config.moengageAppId) {\n const moengageAdapter = new MoengageAdapter({\n appId: config.moengageAppId,\n enableUserIdentification: true,\n region: config.moengageRegion || \"dc_01\",\n debug: config.enableDebugLogs || false,\n });\n adapters.push(moengageAdapter);\n }\n\n // PostHog\n const posthogAdapter = new PostHogAdapter({\n enableDebugLogs: config.enableDebugLogs || false,\n });\n adapters.push(posthogAdapter);\n\n console.log(\n \"Configured adapters:\",\n adapters.map((a) => a.name)\n );\n\n await initializeEventTracking(adapters);\n console.log(\"Event tracking system initialized successfully\");\n}\n","\"use client\";\n\n\nimport { useEffect } from \"react\";\nimport {\n captureAffiliateParams,\n configureAffiliateTracker,\n} from \"./affiliate-tracker\";\nimport type { AffiliateConfig } from \"./types\";\n\ninterface AffiliateTrackerProps {\n config?: Partial<AffiliateConfig>;\n autoCapture?: boolean;\n children?: React.ReactNode;\n}\n\nconst AffiliateTracker: React.FC<AffiliateTrackerProps> = ({\n config,\n autoCapture = true,\n children,\n}) => {\n useEffect(() => {\n // Configure the tracker if config is provided\n if (config) {\n configureAffiliateTracker(config);\n }\n\n // Auto-capture affiliate params if enabled\n if (autoCapture) {\n captureAffiliateParams();\n }\n }, [config, autoCapture]);\n\n return children ? <>{children}</> : null;\n};\n\nexport default AffiliateTracker;\nexport type { AffiliateTrackerProps };\n","/**\n * Centralized constants for affiliate tracking parameters\n */\n\n// Core UTM parameters\nexport const UTM_PARAMETERS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n// Click ID parameters from various platforms\nexport const CLICK_ID_PARAMETERS = [\n \"gclid\", // Google Ads\n \"fbclid\", // Facebook\n \"msclkid\", // Microsoft Ads\n \"ttclid\", // TikTok\n \"twclid\", // Twitter\n \"li_fat_id\", // LinkedIn\n] as const;\n\n// Generic affiliate parameters\nexport const AFFILIATE_PARAMETERS = [\n \"click_id\",\n \"affiliate_id\",\n \"ref\",\n \"source\",\n \"referrer\",\n] as const;\n\n// All supported affiliate tracking parameters\nexport const ALL_AFFILIATE_PARAMETERS = [\n ...UTM_PARAMETERS,\n ...CLICK_ID_PARAMETERS,\n ...AFFILIATE_PARAMETERS,\n] as const;\n\n// Default storage configuration\nexport const STORAGE_CONFIG = {\n DEFAULT_KEY: \"affiliateParams\",\n DEFAULT_TTL: 30 * 24 * 60 * 60 * 1000, // 30 days in milliseconds\n} as const;\n\n// Attribution models\nexport const ATTRIBUTION_MODELS = {\n FIRST_TOUCH: \"first-touch\",\n LAST_TOUCH: \"last-touch\",\n} as const;\n\n// Storage types\nexport const STORAGE_TYPES = {\n SESSION: \"sessionStorage\",\n LOCAL: \"localStorage\",\n} as const;\n\n// Event types\nexport const EVENT_TYPES = {\n CAPTURE: \"capture\",\n CLEAR: \"clear\",\n EXPIRE: \"expire\",\n} as const;\n\n// Attribution channels for classification\nexport const ATTRIBUTION_CHANNELS = {\n DIRECT: \"direct\",\n PAID_SEARCH: \"paid_search\",\n ORGANIC_SEARCH: \"organic_search\",\n SOCIAL: \"social\",\n EMAIL: \"email\",\n AFFILIATE: \"affiliate\",\n REFERRAL: \"referral\",\n DISPLAY: \"display\",\n} as const;\n\n// Search engines for referrer classification\nexport const SEARCH_ENGINES = [\n \"google.com\",\n \"bing.com\",\n \"yahoo.com\",\n \"duckduckgo.com\",\n \"baidu.com\",\n \"yandex.com\",\n \"ask.com\",\n] as const;\n\n// Social media platforms for source classification\nexport const SOCIAL_PLATFORMS = [\n \"facebook\",\n \"instagram\",\n \"twitter\",\n \"linkedin\",\n \"tiktok\",\n \"youtube\",\n \"pinterest\",\n \"snapchat\",\n] as const;\n\n// Type definitions for the constants\nexport type UTMParameter = (typeof UTM_PARAMETERS)[number];\nexport type ClickIdParameter = (typeof CLICK_ID_PARAMETERS)[number];\nexport type AffiliateParameter = (typeof AFFILIATE_PARAMETERS)[number];\nexport type AllAffiliateParameter = (typeof ALL_AFFILIATE_PARAMETERS)[number];\nexport type AttributionModel =\n (typeof ATTRIBUTION_MODELS)[keyof typeof ATTRIBUTION_MODELS];\nexport type StorageType = (typeof STORAGE_TYPES)[keyof typeof STORAGE_TYPES];\nexport type EventType = (typeof EVENT_TYPES)[keyof typeof EVENT_TYPES];\nexport type AttributionChannel =\n (typeof ATTRIBUTION_CHANNELS)[keyof typeof ATTRIBUTION_CHANNELS];\n","import type {\n AffiliateParams,\n AffiliateData,\n AffiliateConfig,\n AffiliateEvent,\n} from \"./types\";\nimport {\n ALL_AFFILIATE_PARAMETERS,\n STORAGE_CONFIG,\n ATTRIBUTION_MODELS,\n STORAGE_TYPES,\n} from \"./constants\";\n\nconst DEFAULT_CONFIG: Required<AffiliateConfig> = {\n storageKey: STORAGE_CONFIG.DEFAULT_KEY,\n storageType: STORAGE_TYPES.SESSION,\n attribution: ATTRIBUTION_MODELS.LAST_TOUCH,\n ttl: STORAGE_CONFIG.DEFAULT_TTL,\n customParams: [],\n enableReferrerCapture: true,\n enableUserAgentCapture: false,\n onCapture: () => {},\n onError: () => {},\n};\n\nlet currentConfig: Required<AffiliateConfig> = { ...DEFAULT_CONFIG };\nlet eventListeners: ((event: AffiliateEvent) => void)[] = [];\n\n/**\n * Configure the affiliate tracker\n */\nexport function configureAffiliateTracker(\n config: Partial<AffiliateConfig> = {}\n): void {\n currentConfig = { ...DEFAULT_CONFIG, ...config };\n}\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Get the appropriate storage object\n */\nfunction getStorage(): Storage | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n return currentConfig.storageType === \"localStorage\"\n ? window.localStorage\n : window.sessionStorage;\n } catch (error) {\n currentConfig.onError(new Error(`Storage not available: ${error}`));\n return null;\n }\n}\n\n/**\n * Check if stored data has expired\n */\nfunction isExpired(timestamp: number): boolean {\n return Date.now() - timestamp > currentConfig.ttl;\n}\n\n/**\n * Emit an event to all listeners\n */\nfunction emitEvent(event: AffiliateEvent): void {\n eventListeners.forEach((listener) => {\n try {\n listener(event);\n } catch (error) {\n currentConfig.onError(new Error(`Event listener error: ${error}`));\n }\n });\n}\n\n/**\n * Add an event listener\n */\nexport function addEventListener(\n listener: (event: AffiliateEvent) => void\n): () => void {\n eventListeners.push(listener);\n\n // Return unsubscribe function\n return () => {\n const index = eventListeners.indexOf(listener);\n if (index > -1) {\n eventListeners.splice(index, 1);\n }\n };\n}\n\n/**\n * Capture affiliate parameters from URL and store them\n */\nexport function captureAffiliateParams(\n customConfig?: Partial<AffiliateConfig>\n): AffiliateData | null {\n if (typeof window === \"undefined\") return null;\n\n // Temporarily override config if provided\n const originalConfig = currentConfig;\n if (customConfig) {\n currentConfig = { ...currentConfig, ...customConfig };\n }\n\n try {\n const storage = getStorage();\n if (!storage) return null;\n\n const urlParams = new URLSearchParams(window.location.search);\n const allKeys = [\n ...ALL_AFFILIATE_PARAMETERS,\n ...currentConfig.customParams,\n ];\n const affiliateParams: AffiliateParams = {};\n\n // Extract parameters from URL\n for (const key of allKeys) {\n const value = urlParams.get(key);\n if (value) {\n affiliateParams[key] = value;\n }\n }\n\n // Capture referrer if enabled and available\n if (currentConfig.enableReferrerCapture && document.referrer) {\n affiliateParams.referrer = document.referrer;\n }\n\n // Only proceed if we have affiliate data\n if (Object.keys(affiliateParams).length === 0) {\n return null;\n }\n\n // Check existing data for attribution logic\n const existingData = getAffiliateParams();\n let shouldUpdate = true;\n\n if (existingData && currentConfig.attribution === \"first-touch\") {\n // Don't update if we already have first-touch data\n shouldUpdate = false;\n }\n\n if (shouldUpdate) {\n const affiliateData: AffiliateData = {\n ...affiliateParams,\n timestamp: Date.now(),\n sessionId: generateSessionId(),\n attribution: currentConfig.attribution,\n url: window.location.href,\n ...(currentConfig.enableUserAgentCapture && {\n userAgent: navigator.userAgent,\n }),\n };\n\n storage.setItem(currentConfig.storageKey, JSON.stringify(affiliateData));\n\n // Emit capture event\n emitEvent({\n type: \"capture\",\n data: affiliateData,\n timestamp: Date.now(),\n });\n\n currentConfig.onCapture(affiliateData);\n return affiliateData;\n }\n\n return existingData;\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n return null;\n } finally {\n // Restore original config\n if (customConfig) {\n currentConfig = originalConfig;\n }\n }\n}\n\n/**\n * Get stored affiliate parameters\n */\nexport function getAffiliateParams(): AffiliateData | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n const storage = getStorage();\n if (!storage) return null;\n\n const stored = storage.getItem(currentConfig.storageKey);\n if (!stored) return null;\n\n const data: AffiliateData = JSON.parse(stored);\n\n // Check if data has expired\n if (isExpired(data.timestamp)) {\n clearAffiliateParams();\n emitEvent({\n type: \"expire\",\n data,\n timestamp: Date.now(),\n });\n return null;\n }\n\n return data;\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n return null;\n }\n}\n\n/**\n * Clear stored affiliate parameters\n */\nexport function clearAffiliateParams(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n const storage = getStorage();\n if (!storage) return;\n\n const existingData = getAffiliateParams();\n storage.removeItem(currentConfig.storageKey);\n\n // Emit clear event\n emitEvent({\n type: \"clear\",\n data: existingData || undefined,\n timestamp: Date.now(),\n });\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n }\n}\n\n/**\n * Get affiliate parameters as URL search params string\n */\nexport function getAffiliateParamsAsUrlString(): string {\n const data = getAffiliateParams();\n if (!data) return \"\";\n\n const params = new URLSearchParams();\n\n // Only include the actual affiliate parameters, not metadata\n const affiliateKeys = [\n ...ALL_AFFILIATE_PARAMETERS,\n ...currentConfig.customParams,\n ];\n\n for (const key of affiliateKeys) {\n const value = data[key];\n if (typeof value === \"string\" && value) {\n params.set(key, value);\n }\n }\n\n return params.toString();\n}\n\n/**\n * Append affiliate parameters to a URL\n */\nexport function appendAffiliateParams(url: string): string {\n const affiliateParams = getAffiliateParamsAsUrlString();\n if (!affiliateParams) return url;\n\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${separator}${affiliateParams}`;\n}\n\n/**\n * Check if current session has affiliate data\n */\nexport function hasAffiliateData(): boolean {\n return getAffiliateParams() !== null;\n}\n\n/**\n * Get affiliate source (utm_source or referrer domain)\n */\nexport function getAffiliateSource(): string | null {\n const data = getAffiliateParams();\n if (!data) return null;\n\n if (data.utm_source) return data.utm_source;\n if (data.referrer) {\n try {\n return new URL(data.referrer).hostname;\n } catch {\n return data.referrer;\n }\n }\n\n return null;\n}\n\n/**\n * Get current configuration\n */\nexport function getConfig(): Required<AffiliateConfig> {\n return { ...currentConfig };\n}\n\n/**\n * Reset configuration to defaults\n */\nexport function resetConfig(): void {\n currentConfig = { ...DEFAULT_CONFIG };\n}\n\n// Export constants for external use\nexport { ALL_AFFILIATE_PARAMETERS, DEFAULT_CONFIG };\n","\"use client\";\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport type {\n AffiliateData,\n AffiliateConfig,\n AffiliateTrackerHookReturn,\n AffiliateEvent,\n} from \"./types\";\nimport {\n captureAffiliateParams,\n getAffiliateParams,\n clearAffiliateParams,\n configureAffiliateTracker,\n addEventListener,\n hasAffiliateData,\n getAffiliateSource,\n} from \"./affiliate-tracker\";\n\n/**\n * Hook for tracking affiliate parameters\n */\nexport function useAffiliateTracker(\n config?: Partial<AffiliateConfig>\n): AffiliateTrackerHookReturn {\n const [affiliateParams, setAffiliateParams] = useState<AffiliateData | null>(\n null\n );\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const configRef = useRef(config);\n\n // Update config ref when config changes\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Configure tracker on mount\n useEffect(() => {\n if (configRef.current) {\n configureAffiliateTracker({\n ...configRef.current,\n onError: (err) => {\n setError(err);\n configRef.current?.onError?.(err);\n },\n });\n }\n }, []);\n\n // Load initial data\n const refreshParams = useCallback(() => {\n setIsLoading(true);\n setError(null);\n\n try {\n const params = getAffiliateParams();\n setAffiliateParams(params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n // Capture new params\n const captureParams = useCallback(() => {\n setError(null);\n\n try {\n const params = captureAffiliateParams(configRef.current);\n setAffiliateParams(params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n }\n }, []);\n\n // Clear params\n const clearParams = useCallback(() => {\n setError(null);\n\n try {\n clearAffiliateParams();\n setAffiliateParams(null);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n }\n }, []);\n\n // Listen for events\n useEffect(() => {\n const unsubscribe = addEventListener((event: AffiliateEvent) => {\n switch (event.type) {\n case \"capture\":\n setAffiliateParams(event.data || null);\n break;\n case \"clear\":\n case \"expire\":\n setAffiliateParams(null);\n break;\n }\n });\n\n return unsubscribe;\n }, []);\n\n // Initial load\n useEffect(() => {\n refreshParams();\n }, [refreshParams]);\n\n return {\n affiliateParams,\n isLoading,\n error,\n captureParams,\n clearParams,\n refreshParams,\n };\n}\n\n/**\n * Hook for checking if affiliate data exists\n */\nexport function useHasAffiliateData(): boolean {\n const [hasData, setHasData] = useState(false);\n\n useEffect(() => {\n const checkData = () => {\n setHasData(hasAffiliateData());\n };\n\n checkData();\n\n const unsubscribe = addEventListener(() => {\n checkData();\n });\n\n return unsubscribe;\n }, []);\n\n return hasData;\n}\n\n/**\n * Hook for getting affiliate source\n */\nexport function useAffiliateSource(): string | null {\n const [source, setSource] = useState<string | null>(null);\n\n useEffect(() => {\n const updateSource = () => {\n setSource(getAffiliateSource());\n };\n\n updateSource();\n\n const unsubscribe = addEventListener(() => {\n updateSource();\n });\n\n return unsubscribe;\n }, []);\n\n return source;\n}\n\n/**\n * Hook for auto-capturing affiliate params on mount\n */\nexport function useAutoCapture(config?: Partial<AffiliateConfig>): void {\n const hasRun = useRef(false);\n\n useEffect(() => {\n if (hasRun.current) return;\n hasRun.current = true;\n\n if (config) {\n configureAffiliateTracker(config);\n }\n\n captureAffiliateParams();\n }, [config]);\n}\n\n/**\n * Hook for listening to affiliate events\n */\nexport function useAffiliateEvents(\n callback: (event: AffiliateEvent) => void,\n eventTypes?: Array<\"capture\" | \"clear\" | \"expire\">\n): void {\n const callbackRef = useRef(callback);\n const eventTypesRef = useRef(eventTypes);\n\n useEffect(() => {\n callbackRef.current = callback;\n eventTypesRef.current = eventTypes;\n });\n\n useEffect(() => {\n const unsubscribe = addEventListener((event: AffiliateEvent) => {\n if (\n !eventTypesRef.current ||\n eventTypesRef.current.includes(event.type)\n ) {\n callbackRef.current(event);\n }\n });\n\n return unsubscribe;\n }, []);\n}\n","\"use client\";\n\nimport { useShopifyCookies } from \"@shopify/hydrogen-react\";\nimport { useEffect, useState } from \"react\";\nimport { EventType, publishEvent } from \"../events\";\n\n// Safe pathname hook that works in different environments\nfunction usePathnameCompat() {\n const [pathname, setPathname] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof window !== \"undefined\") {\n setPathname(window.location.pathname);\n \n // Listen for navigation changes\n const handleLocationChange = () => {\n setPathname(window.location.pathname);\n };\n\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", handleLocationChange);\n \n // For SPA navigation, we might need to listen to custom events\n // This is a fallback for when Next.js router is not available\n \n return () => {\n window.removeEventListener(\"popstate\", handleLocationChange);\n };\n }\n }, []);\n\n return pathname;\n}\n\n/**\n * Component to initialize Shopify Analytics cookies\n * This component handles the useShopifyCookies hook which must be used in a React component\n */\n\ninterface ShopifyAnalyticsScriptProps {\n domain: string;\n}\n\nexport function ShopifyAnalyticsScript({\n domain,\n}: ShopifyAnalyticsScriptProps) {\n const pathname = usePathnameCompat();\n\n const [sessionValid, setSessionValid] = useState(false);\n\n useShopifyCookies({\n hasUserConsent: true,\n domain: domain,\n });\n\n useEffect(() => {\n // Validate session after cookie initialization\n const validateSession = () => {\n const shopifyY = document.cookie.includes(\"_shopify_y=\");\n const shopifyS = document.cookie.includes(\"_shopify_s=\");\n\n if (shopifyY && shopifyS) {\n setSessionValid(true);\n console.log(\"✅ Shopify Analytics session validated\");\n } else {\n console.warn(\"⚠️ Shopify session cookies missing\");\n }\n };\n\n // Allow time for cookies to be set\n const timer = setTimeout(validateSession, 1000);\n return () => clearTimeout(timer);\n }, []);\n\n // Expose session status for debugging\n useEffect(() => {\n if (typeof window !== \"undefined\") {\n (window as any).__shopifySessionValid = sessionValid;\n }\n }, [sessionValid]);\n\n useEffect(() => {\n const trackPageView = () => {\n publishEvent({\n type: EventType.SHOPIFY_PAGE_VIEW,\n });\n };\n\n const timer = setTimeout(trackPageView, 1500);\n return () => clearTimeout(timer);\n }, [pathname]);\n\n return null; // This component doesn't render anything\n}\n","// Export event types\nexport * from \"../types\";\n\n// Export publisher\nexport { eventPublisher, publishEvent } from \"./publisher\";\n\n// Export subscriber\nexport { eventSubscriber } from \"./subscriber\";\nexport type { TrackingAdapter } from \"./subscriber\";\n\n// Export initialization functions\nexport { initializeEventTracking, initTracking } from \"./init\";\n"],"mappings":"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","names":["import_react","EventType","moengage","DEFAULT_CURRENCY","eventSubscriber","import_react","error","import_hydrogen_react","import_react","import_jsx_runtime","logger"]}
|
|
1
|
+
{"version":3,"sources":["../src/events/publisher.ts","../src/events/subscriber.ts","../src/index.ts","../src/ShopkitAnalytics.tsx","../src/logger/index.ts","../src/experiment/constants.ts","../src/experiment/experiment-tracker.ts","../src/adapters/base-adapter.ts","../src/types.ts","../src/utils/event-id.ts","../src/adapters/constants.ts","../src/adapters/multi-pixel-adapter.ts","../src/adapters/google-adapter.ts","../src/adapters/moengage-adapter.ts","../src/adapters/posthog-adapter.ts","../src/adapters/shopify-adapter.ts","../src/events/init.ts","../src/affiliate/AffiliateTracker.tsx","../src/affiliate/constants.ts","../src/affiliate/affiliate-tracker.ts","../src/affiliate/hooks.ts","../src/shopify/ShopifyAnalyticsScript.tsx","../src/events/index.ts"],"sourcesContent":["import type { TEvent } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\n\n/**\n * EventPublisher class responsible for publishing events to subscribers\n */\nclass EventPublisher {\n private static instance: EventPublisher;\n private subscribers: Array<(event: TEvent, params?: TAdapterParams) => void> =\n [];\n\n /**\n * Private constructor to enforce singleton pattern\n */\n private constructor() {}\n\n /**\n * Get the singleton instance of EventPublisher\n */\n public static getInstance(): EventPublisher {\n if (!EventPublisher.instance) {\n EventPublisher.instance = new EventPublisher();\n }\n return EventPublisher.instance;\n }\n\n /**\n * Subscribe to events\n * @param callback Function to be called when an event is published\n * @returns Unsubscribe function\n */\n public subscribe(\n callback: (event: TEvent, params?: TAdapterParams) => void\n ): () => void {\n this.subscribers.push(callback);\n\n // Return unsubscribe function\n return () => {\n this.subscribers = this.subscribers.filter(\n (subscriber) => subscriber !== callback\n );\n };\n }\n\n /**\n * Publish an event to all subscribers\n * @param event The event to publish\n * @param params Optional adapter-specific parameters\n */\n public publish(event: TEvent, params?: TAdapterParams): void {\n try {\n console.log(\"EventPublisher: Received event\", {\n type: event.type,\n data: event,\n params: params,\n });\n\n // Add timestamp if not already present\n const eventWithTimestamp = !event.timestamp\n ? { ...event, timestamp: Date.now() }\n : event;\n\n console.log(\n \"EventPublisher: Number of subscribers:\",\n this.subscribers.length\n );\n\n // Notify all subscribers\n for (const subscriber of this.subscribers) {\n try {\n console.log(\"EventPublisher: Notifying subscriber\");\n subscriber(eventWithTimestamp, params);\n console.log(\"EventPublisher: Subscriber notified successfully\");\n } catch (error) {\n console.error(\"EventPublisher: Error in subscriber:\", error);\n // Continue with other subscribers even if one fails\n }\n }\n\n console.log(\"EventPublisher: Event processing completed\");\n } catch (error) {\n console.error(\"Error publishing event:\", error, event);\n // Silently fail to prevent app crashes due to event publishing issues\n }\n }\n}\n\n// Export singleton instance\nexport const eventPublisher = EventPublisher.getInstance();\n\n/**\n * Helper function to publish events\n * @param event The event to publish\n * @param params Optional adapter-specific parameters\n */\nexport function publishEvent(event: TEvent, params?: TAdapterParams): void {\n try {\n eventPublisher.publish(event, params);\n } catch (error) {\n console.error(\"Error in publishEvent helper:\", error);\n // Silently fail to prevent app crashes due to event publishing issues\n }\n}\n","import type { TEvent } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { eventPublisher } from \"./publisher\";\n\n/**\n * Interface for tracking adapters\n */\nexport interface TrackingAdapter {\n /**\n * Name of the tracking adapter\n */\n name: string;\n\n /**\n * Whether the adapter is enabled\n */\n isEnabled: () => boolean;\n\n /**\n * Initialize the adapter\n */\n initialize: () => Promise<void>;\n\n /**\n * Track an event\n */\n trackEvent: (event: TEvent, params?: TAdapterParams) => Promise<void>;\n}\n\n/**\n * EventSubscriber class responsible for managing tracking adapters and forwarding events\n */\nclass EventSubscriber {\n private static instance: EventSubscriber;\n private adapters: TrackingAdapter[] = [];\n private initialized = false;\n private eventQueue: Array<{ event: TEvent; params?: TAdapterParams }> = [];\n private unsubscribe: (() => void) | null = null;\n\n /**\n * Private constructor to enforce singleton pattern\n */\n private constructor() {}\n\n /**\n * Get the singleton instance of EventSubscriber\n */\n public static getInstance(): EventSubscriber {\n if (!EventSubscriber.instance) {\n EventSubscriber.instance = new EventSubscriber();\n }\n return EventSubscriber.instance;\n }\n\n /**\n * Register a tracking adapter\n * @param adapter The tracking adapter to register\n */\n public registerAdapter(adapter: TrackingAdapter): void {\n // Check if adapter with the same name already exists\n const existingAdapter = this.adapters.find((a) => a.name === adapter.name);\n if (existingAdapter) {\n console.warn(\n `Tracking adapter with name \"${adapter.name}\" is already registered. Skipping.`\n );\n return;\n }\n\n this.adapters.push(adapter);\n\n // If already initialized, initialize the new adapter\n if (this.initialized) {\n this.initializeAdapter(adapter).catch((error) => {\n console.error(`Failed to initialize adapter \"${adapter.name}\":`, error);\n });\n }\n }\n\n /**\n * Unregister a tracking adapter by name\n * @param adapterName The name of the adapter to unregister\n */\n public unregisterAdapter(adapterName: string): void {\n this.adapters = this.adapters.filter(\n (adapter) => adapter.name !== adapterName\n );\n }\n\n /**\n * Initialize all registered adapters\n */\n public async initialize(): Promise<void> {\n console.log(\"Initializing EventSubscriber...\");\n\n if (this.initialized) {\n console.log(\"EventSubscriber already initialized\");\n return;\n }\n\n // Subscribe to events\n this.unsubscribe = eventPublisher.subscribe(this.handleEvent.bind(this));\n console.log(\"Subscribed to event publisher\");\n\n // Initialize all adapters\n console.log(`Initializing ${this.adapters.length} adapters...`);\n await Promise.all(\n this.adapters.map((adapter) => this.initializeAdapter(adapter))\n );\n\n this.initialized = true;\n console.log(\"EventSubscriber initialization complete\");\n\n // Process any queued events\n this.processEventQueue();\n }\n\n /**\n * Initialize a single adapter\n * @param adapter The adapter to initialize\n */\n private async initializeAdapter(adapter: TrackingAdapter): Promise<void> {\n try {\n await adapter.initialize();\n console.log(\n `Tracking adapter \"${adapter.name}\" initialized successfully.`\n );\n } catch (error) {\n console.error(`Failed to initialize adapter \"${adapter.name}\":`, error);\n }\n }\n\n /**\n * Handle an event by forwarding it to all enabled adapters\n * @param event The event to handle\n * @param params Optional adapter-specific parameters\n */\n private handleEvent(event: TEvent, params?: TAdapterParams): void {\n console.log(\"Handling event:\", event.type, \"with params:\", params);\n\n if (!this.initialized) {\n console.log(\"Subscriber not initialized, queueing event\");\n this.eventQueue.push({ event, params });\n return;\n }\n\n // Forward the event to all enabled adapters\n for (const adapter of this.adapters) {\n if (adapter.isEnabled()) {\n console.log(`Forwarding event to adapter: ${adapter.name}`);\n adapter.trackEvent(event, params).catch((error) => {\n console.error(\n `Error tracking event in adapter \"${adapter.name}\":`,\n error\n );\n });\n } else {\n console.log(`Adapter ${adapter.name} is disabled, skipping`);\n }\n }\n }\n\n /**\n * Process any events that were queued before initialization\n */\n private processEventQueue(): void {\n if (this.eventQueue.length === 0) {\n return;\n }\n\n console.log(`Processing ${this.eventQueue.length} queued events.`);\n\n // Process each queued event\n for (const { event, params } of this.eventQueue) {\n this.handleEvent(event, params);\n }\n\n // Clear the queue\n this.eventQueue = [];\n }\n\n /**\n * Shutdown the subscriber and all adapters\n */\n public shutdown(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n\n this.initialized = false;\n this.eventQueue = [];\n }\n\n /**\n * Get all registered adapters\n */\n public getAdapters(): TrackingAdapter[] {\n return [...this.adapters];\n }\n}\n\n// Export singleton instance\nexport const eventSubscriber = EventSubscriber.getInstance();\n","/**\n * @shopkit/analytics\n *\n * Unified analytics tracking package for e-commerce storefronts.\n * Supports multiple analytics platforms with a single event publishing interface.\n *\n * ## Supported Platforms\n * - Google Analytics 4\n * - Facebook Pixel (single and multi-pixel)\n * - MoEngage\n * - PostHog\n * - Shopify Analytics\n * - KwikPass\n * - KwikCheckout\n *\n * ## Usage\n *\n * ```typescript\n * import { ShopkitAnalytics, publishEvent, EventType } from '@shopkit/analytics';\n *\n * // In your app layout\n * <ShopkitAnalytics config={{\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * posthog: { apiKey: 'phc_xxx', apiHost: 'https://app.posthog.com' },\n * }} />\n *\n * // Track events anywhere in your app\n * publishEvent({\n * type: EventType.ADD_TO_CART,\n * productId: 'prod_123',\n * productName: 'Example Product',\n * price: 29.99,\n * currency: 'USD',\n * });\n * ```\n *\n * @packageDocumentation\n */\n\n// Export main ShopkitAnalytics component\nexport { default as ShopkitAnalytics, default } from \"./ShopkitAnalytics\";\n\nexport type {\n ShopkitAnalyticsConfig,\n ShopkitAnalyticsProps,\n} from \"./ShopkitAnalytics\";\n\n// Export event tracking functionality\nexport {\n eventPublisher,\n publishEvent,\n eventSubscriber,\n initializeEventTracking,\n initTracking,\n} from \"./events\";\nexport type { TrackingAdapter } from \"./events\";\n\n// Export affiliate tracking functionality\nexport {\n AffiliateTracker,\n useAffiliateTracker,\n useHasAffiliateData,\n useAffiliateSource,\n captureAffiliateParams,\n getAffiliateParams,\n clearAffiliateParams,\n hasAffiliateData,\n getAffiliateSource,\n} from \"./affiliate\";\nexport type {\n AffiliateTrackerProps,\n AffiliateParams,\n AffiliateData,\n AffiliateConfig,\n} from \"./affiliate\";\n\n// Export experiment tracking functionality\nexport {\n getExperimentParams,\n hasExperimentData,\n PRIMA_EXPERIMENT_COOKIES,\n PRIMA_EXPERIMENT_COOKIE_NAMES,\n} from \"./experiment\";\nexport type { ExperimentData } from \"./experiment\";\n\n// Export shared types and constants\nexport * from \"./types\";\n\n// Export adapters\nexport * from \"./adapters\";\n\n// Export adapter parameter types\nexport type {\n TAdapterParams,\n IAdapterParams,\n IBaseAdapterParams,\n} from \"./adapter-params\";\n\n// Export utilities\nexport { generateEventId, getBrowserInfo } from \"./utils/event-id\";\n\n// Export logger\nexport * from \"./logger\";\n\n// Export Shopify components\nexport { ShopifyAnalyticsScript } from \"./shopify/ShopifyAnalyticsScript\";\n","\"use client\";\n\n/**\n * ShopkitAnalytics Component\n *\n * Main analytics provider component that initializes and manages\n * all configured analytics adapters.\n *\n * @module @shopkit/analytics\n */\n\nimport React, { useEffect } from \"react\";\nimport { initializeEventTracking } from \"./events/init\";\nimport { AffiliateTracker } from \"./affiliate\";\nimport { createLogger, type LoggerConfig } from \"./logger\";\nimport {\n GoogleAdapter,\n MultiPixelAdapter,\n MoengageAdapter,\n PostHogAdapter,\n ShopifyAdapter,\n} from \"./adapters\";\nimport type {\n GoogleAdapterConfig,\n MultiPixelAdapterConfig,\n MoengageAdapterConfig,\n PostHogAdapterConfig,\n ShopifyAdapterConfig,\n} from \"./adapters\";\nimport type { TrackingAdapter } from \"./events/subscriber\";\nimport type { AffiliateConfig } from \"./affiliate/types\";\nimport { ShopifyAnalyticsScript } from \"./shopify/ShopifyAnalyticsScript\";\n\n/**\n * Configuration for ShopkitAnalytics component\n *\n * @example\n * ```typescript\n * const config: ShopkitAnalyticsConfig = {\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * posthog: { apiKey: 'phc_xxx', apiHost: 'https://app.posthog.com' },\n * logger: { enabled: true, level: 'info' },\n * };\n * ```\n */\nexport interface ShopkitAnalyticsConfig {\n // Analytics Adapters\n googleAnalytics?: GoogleAdapterConfig;\n facebookMultiPixel?: MultiPixelAdapterConfig;\n moengage?: MoengageAdapterConfig;\n posthog?: PostHogAdapterConfig;\n shopify?: ShopifyAdapterConfig;\n customAdapters?: TrackingAdapter[];\n\n // Affiliate Tracking\n affiliate?: {\n enabled?: boolean;\n config?: Partial<AffiliateConfig>;\n autoCapture?: boolean;\n };\n\n // Logger Settings\n logger?: LoggerConfig;\n\n // General Settings (deprecated - use logger.enabled instead)\n enableDebugLogs?: boolean;\n autoInitialize?: boolean;\n}\n\n/**\n * Props for ShopkitAnalytics component\n */\nexport interface ShopkitAnalyticsProps {\n /** Analytics configuration object */\n config: ShopkitAnalyticsConfig;\n /** Optional children to render */\n children?: React.ReactNode;\n /** Callback when analytics initialization completes */\n onInitialized?: () => void;\n /** Callback when an error occurs during initialization */\n onError?: (error: Error) => void;\n}\n\n/**\n * ShopkitAnalytics Component\n *\n * The main analytics provider that initializes all configured tracking adapters\n * and sets up event publishing infrastructure.\n *\n * Place this component in your app's root layout to enable analytics tracking\n * throughout your application.\n *\n * @param props - Component props\n * @returns React component with analytics initialization and affiliate tracking\n *\n * @example\n * ```typescript\n * // In your root layout\n * import { ShopkitAnalytics } from '@shopkit/analytics';\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <ShopkitAnalytics\n * config={{\n * googleAnalytics: { measurementId: 'G-XXXXXX' },\n * facebookPixel: { pixelId: '123456789' },\n * }}\n * onInitialized={() => console.log('Analytics ready')}\n * onError={(err) => console.error('Analytics error:', err)}\n * >\n * {children}\n * </ShopkitAnalytics>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nconst ShopkitAnalytics: React.FC<ShopkitAnalyticsProps> = ({\n config,\n children,\n onInitialized,\n onError,\n}) => {\n useEffect(() => {\n const initializeAnalytics = async () => {\n if (config.autoInitialize === false) return;\n\n // Create logger instance\n const loggerConfig: LoggerConfig = {\n enabled: config.logger?.enabled ?? config.enableDebugLogs ?? true,\n level: config.logger?.level ?? \"info\",\n name: \"@shopkit/analytics\",\n prettyPrint: config.logger?.prettyPrint ?? false,\n };\n\n const logger = createLogger(loggerConfig);\n\n try {\n logger.info(\"Starting initialization...\");\n\n const adapters: TrackingAdapter[] = [];\n\n // Helper function to add logger config to adapter config\n const addLoggerConfig = (adapterConfig: any) => ({\n ...adapterConfig,\n enableDebugLogs: loggerConfig.enabled,\n logLevel: loggerConfig.level,\n });\n\n // Google Analytics 4\n if (config.googleAnalytics) {\n const gaAdapter = new GoogleAdapter(\n addLoggerConfig(config.googleAnalytics),\n );\n adapters.push(gaAdapter);\n logger.info(\"Added Google Analytics adapter\");\n }\n\n // Facebook Multi-Pixel\n if (config.facebookMultiPixel) {\n const multiPixelAdapter = new MultiPixelAdapter(\n addLoggerConfig(config.facebookMultiPixel),\n );\n adapters.push(multiPixelAdapter);\n logger.info(\n `Added Facebook Multi-Pixel adapter with ${config.facebookMultiPixel.pixels.length} pixels`,\n );\n }\n\n // MoEngage\n if (config.moengage) {\n const moengageAdapter = new MoengageAdapter(\n addLoggerConfig(config.moengage),\n );\n adapters.push(moengageAdapter);\n logger.info(\"Added MoEngage adapter\");\n }\n\n // PostHog\n if (config.posthog) {\n const posthogAdapter = new PostHogAdapter(\n addLoggerConfig(config.posthog),\n );\n adapters.push(posthogAdapter);\n logger.info(\"Added PostHog adapter\");\n }\n\n // Shopify Analytics\n if (config.shopify) {\n const shopifyAdapter = new ShopifyAdapter(\n addLoggerConfig(config.shopify),\n );\n adapters.push(shopifyAdapter);\n logger.info(\"Added Shopify Analytics adapter\");\n }\n\n // Custom adapters\n if (config.customAdapters) {\n adapters.push(...config.customAdapters);\n logger.info(`Added ${config.customAdapters.length} custom adapters`);\n }\n\n if (adapters.length === 0) {\n logger.warn(\"No analytics adapters configured\");\n } else {\n // Initialize the event tracking system\n await initializeEventTracking(adapters);\n logger.info(\"Event tracking initialized with adapters\", {\n adapters: adapters.map((a) => a.name),\n });\n }\n\n logger.info(\"Initialization completed successfully\");\n onInitialized?.();\n } catch (err) {\n const error =\n err instanceof Error\n ? err\n : new Error(\"Unknown initialization error\");\n logger.error(\"Initialization failed\", error);\n onError?.(error);\n }\n };\n\n initializeAnalytics();\n }, [config, onInitialized, onError]);\n\n return (\n <>\n {/* Affiliate Tracker */}\n {config.affiliate?.enabled !== false && (\n <AffiliateTracker\n config={config.affiliate?.config}\n autoCapture={config.affiliate?.autoCapture}\n />\n )}\n\n {/* Shopify Analytics Script - Only render if Shopify config is provided */}\n {config.shopify?.domain && (\n <ShopifyAnalyticsScript domain={config.shopify.domain} />\n )}\n\n {children ? <>{children}</> : null}\n </>\n );\n};\n\nexport default ShopkitAnalytics;\n","/**\n * Logger configuration options\n */\nexport interface LoggerConfig {\n level?: \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n enabled?: boolean;\n name?: string;\n prettyPrint?: boolean;\n redact?: string[];\n}\n\n/**\n * Logger interface for consistent logging across adapters\n */\nexport interface Logger {\n trace: (message: string, ...args: any[]) => void;\n debug: (message: string, ...args: any[]) => void;\n info: (message: string, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, error?: Error, ...args: any[]) => void;\n fatal: (message: string, error?: Error, ...args: any[]) => void;\n child: (bindings: Record<string, any>) => Logger;\n}\n\n/**\n * Log levels with numeric values for comparison\n */\nconst LOG_LEVELS = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n} as const;\n\n/**\n * No-op logger for when logging is disabled\n */\nclass NoOpLogger implements Logger {\n trace() {}\n debug() {}\n info() {}\n warn() {}\n error() {}\n fatal() {}\n child(): Logger {\n return new NoOpLogger();\n }\n}\n\n/**\n * Simple universal logger that works in all environments\n */\nclass UniversalLogger implements Logger {\n private config: Required<LoggerConfig>;\n private bindings: Record<string, any>;\n\n constructor(\n config: Required<LoggerConfig>,\n bindings: Record<string, any> = {}\n ) {\n this.config = config;\n this.bindings = bindings;\n }\n\n private shouldLog(level: keyof typeof LOG_LEVELS): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[this.config.level];\n }\n\n private formatMessage(\n level: string,\n message: string,\n args: any[],\n error?: Error\n ): string {\n const timestamp = new Date().toISOString();\n const name = this.config.name;\n\n let logMessage = this.config.prettyPrint\n ? `[${timestamp}] ${level.toUpperCase()} [${name}]: ${message}`\n : JSON.stringify({\n timestamp,\n level,\n name,\n message,\n ...this.bindings,\n ...(args.length > 0 && { args }),\n ...(error && {\n error: { message: error.message, stack: error.stack },\n }),\n });\n\n if (this.config.prettyPrint && args.length > 0) {\n logMessage += ` ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`;\n }\n\n if (this.config.prettyPrint && error) {\n logMessage += ` Error: ${error.message}`;\n if (error.stack) {\n logMessage += `\\n${error.stack}`;\n }\n }\n\n return this.redactSensitiveData(logMessage);\n }\n\n private redactSensitiveData(message: string): string {\n let redactedMessage = message;\n for (const field of this.config.redact) {\n const regex = new RegExp(`\"${field}\"\\\\s*:\\\\s*\"[^\"]*\"`, \"gi\");\n redactedMessage = redactedMessage.replace(\n regex,\n `\"${field}\":\"[REDACTED]\"`\n );\n }\n return redactedMessage;\n }\n\n private log(\n level: keyof typeof LOG_LEVELS,\n message: string,\n args: any[],\n error?: Error\n ): void {\n if (!this.shouldLog(level)) return;\n\n const formattedMessage = this.formatMessage(level, message, args, error);\n\n // Use appropriate console method based on level\n switch (level) {\n case \"trace\":\n console.trace(formattedMessage);\n break;\n case \"debug\":\n console.debug(formattedMessage);\n break;\n case \"info\":\n console.info(formattedMessage);\n break;\n case \"warn\":\n console.warn(formattedMessage);\n break;\n case \"error\":\n case \"fatal\":\n console.error(formattedMessage);\n break;\n }\n }\n\n trace(message: string, ...args: any[]): void {\n this.log(\"trace\", message, args);\n }\n\n debug(message: string, ...args: any[]): void {\n this.log(\"debug\", message, args);\n }\n\n info(message: string, ...args: any[]): void {\n this.log(\"info\", message, args);\n }\n\n warn(message: string, ...args: any[]): void {\n this.log(\"warn\", message, args);\n }\n\n error(message: string, error?: Error, ...args: any[]): void {\n this.log(\"error\", message, args, error);\n }\n\n fatal(message: string, error?: Error, ...args: any[]): void {\n this.log(\"fatal\", message, args, error);\n }\n\n child(bindings: Record<string, any>): Logger {\n return new UniversalLogger(this.config, { ...this.bindings, ...bindings });\n }\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(config: LoggerConfig = {}): Logger {\n const fullConfig: Required<LoggerConfig> = {\n level: config.level || \"info\",\n enabled: config.enabled !== false,\n name: config.name || \"@shopkit/analytics\",\n prettyPrint: config.prettyPrint || false,\n redact: config.redact || [],\n };\n\n // Return no-op logger if disabled\n if (!fullConfig.enabled) {\n return new NoOpLogger();\n }\n\n return new UniversalLogger(fullConfig);\n}\n\n/**\n * Default logger instance\n */\nexport const logger = createLogger({\n enabled: true,\n level: \"info\",\n prettyPrint: false,\n});\n\n/**\n * Create adapter-specific logger\n */\nexport function createAdapterLogger(\n adapterName: string,\n config: LoggerConfig = {}\n): Logger {\n const baseLogger = createLogger(config);\n return baseLogger.child({ adapter: adapterName });\n}\n","/**\n * Prima PR A/B test experiment cookie names\n */\nexport const PRIMA_EXPERIMENT_COOKIES = {\n HOME: \"_prima_ptr_ab_home\",\n COLLECTION: \"_prima_ptr_ab_collection\",\n PRODUCT: \"_prima_ptr_ab_product\",\n} as const;\n\n/**\n * Array of all Prima experiment cookie names for iteration\n */\nexport const PRIMA_EXPERIMENT_COOKIE_NAMES = Object.values(\n PRIMA_EXPERIMENT_COOKIES\n);\n","import type { ExperimentData } from \"./types\";\nimport {\n PRIMA_EXPERIMENT_COOKIES,\n PRIMA_EXPERIMENT_COOKIE_NAMES,\n} from \"./constants\";\n\n/**\n * Get cookie value by name\n */\nfunction getCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts.length === 2) {\n return parts.pop()?.split(\";\").shift() || null;\n }\n return null;\n}\n\n/**\n * Get experiment parameters from cookies\n */\nexport function getExperimentParams(): ExperimentData {\n const payload = {\n [PRIMA_EXPERIMENT_COOKIES.HOME]: getCookie(PRIMA_EXPERIMENT_COOKIES.HOME),\n [PRIMA_EXPERIMENT_COOKIES.COLLECTION]: getCookie(\n PRIMA_EXPERIMENT_COOKIES.COLLECTION\n ),\n [PRIMA_EXPERIMENT_COOKIES.PRODUCT]: getCookie(\n PRIMA_EXPERIMENT_COOKIES.PRODUCT\n ),\n };\n\n return payload;\n}\n\n/**\n * Check if any experiment data exists\n */\nexport function hasExperimentData(): boolean {\n return PRIMA_EXPERIMENT_COOKIE_NAMES.some(\n (cookieName) => getCookie(cookieName) !== null\n );\n}\n","import type { TEvent } from \"../types\";\nimport type { TrackingAdapter } from \"../events/subscriber\";\nimport type { TAdapterParams, IBaseAdapterParams } from \"../adapter-params\";\nimport { createAdapterLogger, type Logger, type LoggerConfig } from \"../logger\";\nimport { getExperimentParams } from \"../experiment/experiment-tracker\";\nimport type { ExperimentData } from \"../experiment/types\";\nimport { PRIMA_EXPERIMENT_COOKIES } from \"../experiment\";\n\n/**\n * Abstract base class for tracking adapters\n */\nexport abstract class BaseAdapter implements TrackingAdapter {\n /**\n * Name of the tracking adapter\n */\n public abstract readonly name: string;\n\n /**\n * Configuration for the adapter\n */\n protected config: Record<string, any>;\n\n /**\n * Logger instance for this adapter\n */\n protected logger: Logger;\n\n /**\n * Whether the adapter has been initialized\n */\n protected initialized = false;\n\n /**\n * Constructor\n * @param config Configuration for the adapter\n */\n constructor(config: Record<string, any> = {}) {\n this.config = config;\n\n // Create a generic logger - will be properly initialized by subclasses\n const loggerConfig: LoggerConfig = {\n enabled: config.enableDebugLogs ?? true,\n level: config.logLevel ?? \"info\",\n name: \"@shopkit/analytics\",\n };\n\n this.logger = createAdapterLogger(\"BaseAdapter\", loggerConfig);\n }\n\n /**\n * Initialize logger with proper adapter name\n * Should be called by subclasses after name is available\n */\n protected initializeLogger(): void {\n const loggerConfig: LoggerConfig = {\n enabled: this.config.enableDebugLogs ?? true,\n level: this.config.logLevel ?? \"info\",\n name: \"@shopkit/analytics\",\n };\n\n this.logger = createAdapterLogger(this.name, loggerConfig);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return this.initialized;\n }\n\n /**\n * Initialize the adapter\n */\n public abstract initialize(): Promise<void>;\n\n /**\n * Track an event\n * @param event The event to track\n * @param params Optional adapter-specific parameters\n */\n public abstract trackEvent(\n event: TEvent,\n params?: TAdapterParams\n ): Promise<void>;\n\n /**\n * Extract adapter-specific parameters for this adapter\n * @param params The adapter parameters object\n * @returns Adapter-specific parameters or empty object\n */\n protected getAdapterParams(params?: TAdapterParams): IBaseAdapterParams {\n return params?.[this.name] || {};\n }\n\n /**\n * Get custom event name or fall back to default\n * @param params The adapter parameters object\n * @param defaultName The default event name to use\n * @returns Custom event name or default\n */\n protected getEventName(\n params: TAdapterParams | undefined,\n defaultName: string\n ): string {\n const adapterParams = this.getAdapterParams(params);\n return adapterParams.event_name || defaultName;\n }\n\n /**\n * Merge standard event data with adapter-specific parameters\n * @param params The adapter parameters object\n * @param standardData The standard event data\n * @returns Merged data with adapter-specific overrides\n */\n protected mergeEventData(\n standardData: Record<string, any>,\n params: TAdapterParams | undefined\n ): Record<string, any> {\n const adapterParams = this.getAdapterParams(params);\n\n // Remove event_name from adapter params to avoid conflicts\n const { event_name, ...customParams } = adapterParams;\n\n // Merge with priority: adapter-specific > standard\n return {\n ...standardData,\n ...customParams,\n };\n }\n\n /**\n * Get a configuration value\n * @param key The configuration key\n * @param defaultValue The default value if the key is not found\n */\n protected getConfig<T>(key: string, defaultValue?: T): T {\n return key in this.config ? this.config[key] : (defaultValue as T);\n }\n\n /**\n * Get affiliate parameters from session storage or custom implementation\n * Override this method to provide your own affiliate tracking implementation\n * @returns Affiliate parameters or null if not available\n */\n protected getAffiliateParams(): Record<string, string> | null {\n // Default implementation returns null\n // Users can override this method to integrate with their affiliate tracking system\n return null;\n }\n\n /**\n * Get experiment parameters from cookies\n * @returns Experiment parameters\n */\n protected getExperimentParams(): ExperimentData {\n try {\n return getExperimentParams();\n } catch (error) {\n // Silently fail if experiment tracking is not available\n return {\n [PRIMA_EXPERIMENT_COOKIES.HOME]: null,\n [PRIMA_EXPERIMENT_COOKIES.COLLECTION]: null,\n [PRIMA_EXPERIMENT_COOKIES.PRODUCT]: null,\n };\n }\n }\n\n /**\n * Enhance event parameters with affiliate data\n * @param params The original parameters\n * @returns Parameters enhanced with affiliate data\n */\n protected enhanceWithAffiliateParams(\n params: Record<string, any>\n ): Record<string, any> {\n const affiliateParams = this.getAffiliateParams();\n if (!affiliateParams) return params;\n\n return {\n ...params,\n // Add affiliate parameters\n ...affiliateParams,\n };\n }\n\n /**\n * Enhance event parameters with experiment data\n * @param params The original parameters\n * @returns Parameters enhanced with experiment data\n */\n protected enhanceWithExperimentParams(\n params: Record<string, any>\n ): Record<string, any> {\n const experimentParams = this.getExperimentParams();\n\n return {\n ...params,\n experiment: experimentParams,\n };\n }\n}\n","/**\n * Event types that can be tracked across the application\n * Organized by category for better maintainability and understanding\n */\nexport enum EventType {\n // ============================================================================\n // CORE E-COMMERCE EVENTS\n // Standard events used across all analytics platforms\n // ============================================================================\n\n /** Basic page view tracking */\n PAGE_VIEW = \"page_view\",\n\n /** Product viewing and interaction events */\n VIEW_CONTENT = \"view_content\",\n VIEWED_PRODUCT = \"viewed_product\",\n\n /** Shopping cart events */\n ADD_TO_CART = \"add_to_cart\",\n REMOVE_FROM_CART = \"remove_from_cart\",\n CART_VIEWED = \"cart_viewed\",\n\n /** Checkout flow events */\n INITIATE_CHECKOUT = \"initiate_checkout\",\n ADD_PAYMENT_INFO = \"add_payment_info\",\n PURCHASE = \"purchase\",\n\n /** Search and discovery events */\n SEARCH = \"search\",\n VIEW_SEARCH_RESULTS = \"view_search_results\",\n\n // ============================================================================\n // USER AUTHENTICATION EVENTS\n // Events specific to MoEngage for user lifecycle tracking\n // ============================================================================\n\n /** User account creation tracking */\n USER_SIGNUP = \"user_signup\",\n\n /** User login tracking */\n USER_LOGIN = \"user_login\",\n\n // ============================================================================\n // PLATFORM-SPECIFIC EVENTS\n // Events for specific platform integrations\n // ============================================================================\n\n /** Shopify analytics integration - Do Not Remove */\n SHOPIFY_PAGE_VIEW = \"shopify_page_view\",\n\n // ============================================================================\n // CUSTOM EVENTS\n // Generic events for flexible tracking requirements\n // ============================================================================\n\n /** Generic custom event for any tracking needs */\n CUSTOM = \"custom\",\n\n /** Specific custom event with predefined structure */\n SPECIFIC = \"specific\",\n}\n\n/**\n * Base event interface that all events should implement\n */\nexport interface BaseEvent {\n type: EventType;\n timestamp?: number;\n eventId?: string;\n event_category?: string;\n description?: string;\n [key: string]: any;\n}\n\n// ============================================================================\n// CORE ANALYTICS EVENTS\n// These are the fundamental events used across all analytics platforms\n// ============================================================================\n\n/**\n * Page view event - Tracks when a user views a page\n */\nexport interface IPageViewEvent extends BaseEvent {\n type: EventType.PAGE_VIEW;\n path: string;\n title: string;\n referrer?: string;\n}\n\n/**\n * Viewed product event - Triggered after user views a product for 20+ seconds\n */\nexport interface IViewedProductEvent extends BaseEvent {\n type: EventType.VIEWED_PRODUCT;\n productId: string;\n productName: string;\n price: number;\n currency: string;\n viewDuration?: number;\n}\n\n/**\n * Add to cart event - Tracks when user adds product to cart\n */\nexport interface IAddToCartEvent extends BaseEvent {\n type: EventType.ADD_TO_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity?: number;\n variant?: string;\n}\n\n/**\n * Remove from cart event - Tracks when user removes product from cart\n */\nexport interface IRemoveFromCartEvent extends BaseEvent {\n type: EventType.REMOVE_FROM_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Cart viewed event - Tracks when user views their cart\n */\nexport interface ICartViewedEvent extends BaseEvent {\n type: EventType.CART_VIEWED;\n cartId: string;\n products: Array<{\n variantId: string;\n price: number;\n quantity: number;\n }>;\n}\n\n/**\n * Search event - Tracks when user performs a search\n */\nexport interface ISearchEvent extends BaseEvent {\n type: EventType.SEARCH;\n searchTerm: string;\n content_ids: string[];\n resultsCount?: number;\n}\n\n/**\n * Add Payment Info event - Tracks when user adds payment information\n */\nexport interface IAddPaymentInfoEvent extends BaseEvent {\n type: EventType.ADD_PAYMENT_INFO;\n cartValue: number;\n currency?: string;\n itemCount: number;\n paymentType?: string;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n// ============================================================================\n// USER AUTHENTICATION EVENTS\n// Events specific to MoEngage for user authentication tracking\n// ============================================================================\n\n/**\n * User signup event - Tracks when a user creates an account\n */\nexport interface IUserSignupEvent extends BaseEvent {\n type: EventType.USER_SIGNUP;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * User login event - Tracks when a user logs into their account\n */\nexport interface IUserLoginEvent extends BaseEvent {\n type: EventType.USER_LOGIN;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n// ============================================================================\n// PLATFORM-SPECIFIC EVENTS\n// Events designed for specific analytics platforms\n// ============================================================================\n\n/**\n * View content event - Facebook Pixel specific event for content viewing\n */\nexport interface IViewContentEvent extends BaseEvent {\n type: EventType.VIEW_CONTENT;\n content_type?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n value?: number;\n currency?: string;\n items?: Array<any>;\n}\n\n/**\n * Purchase event - Facebook Pixel specific event for purchase tracking\n */\nexport interface IPurchaseEvent extends BaseEvent {\n type: EventType.PURCHASE;\n orderId?: string;\n cartValue?: number;\n currency?: string;\n itemCount?: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n transaction_id?: string;\n coupon?: string;\n shipping?: number;\n tax?: number;\n discount?: number | string;\n}\n\n/**\n * View search results event - Google Analytics 4 specific event\n */\nexport interface IViewSearchResultsEvent extends BaseEvent {\n type: EventType.VIEW_SEARCH_RESULTS;\n search_term?: string;\n}\n\n/**\n * Begin checkout event - Google Analytics 4 specific event for checkout initiation\n */\nexport interface IBeginCheckoutEvent extends BaseEvent {\n type: EventType.INITIATE_CHECKOUT;\n orderId?: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n coupon?: string;\n discount?: number | string;\n}\n\n// ============================================================================\n// CUSTOM EVENTS\n// Generic events for custom tracking needs\n// ============================================================================\n\n/**\n * Custom event - For any custom tracking requirements not covered by standard events\n */\nexport interface ICustomEvent extends BaseEvent {\n type: EventType.CUSTOM;\n}\n\n/**\n * Specific event - For specific tracking requirements with custom properties\n */\nexport interface ISpecificEvent extends BaseEvent {\n type: EventType.SPECIFIC;\n}\n\n// ============================================================================\n// SHOPIFY EVENTS\n// Events specific to Shopify platform integration\n// ============================================================================\n\n/**\n * Shopify page view event - Tracks page views specifically for Shopify analytics\n */\nexport interface IShopifyPageViewEvent extends BaseEvent {\n type: EventType.SHOPIFY_PAGE_VIEW;\n path?: string;\n}\n\n/**\n * Union type of all possible events\n */\nexport type TEvent =\n | IPageViewEvent\n | IAddToCartEvent\n | IRemoveFromCartEvent\n | ICartViewedEvent\n | ISearchEvent\n | IUserSignupEvent\n | IUserLoginEvent\n | IViewContentEvent\n | IPurchaseEvent\n | IViewSearchResultsEvent\n | IBeginCheckoutEvent\n | ICustomEvent\n | ISpecificEvent\n | IAddPaymentInfoEvent\n | IViewedProductEvent\n | IShopifyPageViewEvent;\n","/**\n * Generate a unique event ID for deduplication\n * Format: timestamp_randomString_eventType\n */\nexport function generateEventId(eventType: string): string {\n const timestamp = Date.now();\n const randomString = Math.random().toString(36).substring(2, 8);\n return `${timestamp}_${randomString}_${eventType}`;\n}\n\n/**\n * Extract browser information for CAPI user data\n */\nexport function getBrowserInfo(): {\n clientUserAgent?: string;\n fbc?: string;\n fbp?: string;\n} {\n if (typeof window === \"undefined\") {\n return {};\n }\n\n const userAgent = navigator.userAgent;\n\n // Get Facebook click ID from URL or cookies\n const fbc = getFacebookClickId();\n const fbp = getFacebookBrowserId();\n\n return {\n clientUserAgent: userAgent,\n fbc,\n fbp,\n };\n}\n\n/**\n * Get Facebook click ID (fbc) from URL parameters or cookies\n * CRITICAL: fbc must be consistent for deduplication to work\n */\nfunction getFacebookClickId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n // Check cookies first (most reliable, already set by Facebook)\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbc\") {\n return value;\n }\n }\n\n // Check URL parameters as fallback (from ad click)\n // Use the fbclid directly without adding timestamp\n // Facebook sets _fbc cookie automatically, so this shouldn't be needed\n const urlParams = new URLSearchParams(window.location.search);\n const fbclid = urlParams.get(\"fbclid\");\n\n if (fbclid) {\n // Return the fbclid as-is, don't add dynamic timestamp\n // Facebook's pixel will set the proper _fbc cookie\n return fbclid;\n }\n\n return undefined;\n}\n\n/**\n * Get Facebook browser ID (fbp) from cookies\n */\nfunction getFacebookBrowserId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbp\") {\n return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Get client IP address from request headers\n */\nexport function getClientIpAddress(request: any): string | \"\" {\n // Try different headers for IP address\n const h = request.headers;\n\n const candidates = [\n h.get(\"cf-connecting-ip\"),\n h.get(\"true-client-ip\"),\n h.get(\"x-vercel-forwarded-for\"), // Vercel specific\n h.get(\"x-forwarded-for\"),\n h.get(\"x-real-ip\"),\n ].filter(Boolean) as string[];\n\n if (candidates.length === 0) {\n return \"\";\n }\n\n // x-forwarded-for can be a list: \"client, proxy1, proxy2\"\n const first = candidates[0].split(\",\")[0].trim();\n\n // Optional: normalize IPv6-wrapped IPv4 like \"::ffff:1.2.3.4\"\n const ip = first.startsWith(\"::ffff:\") ? first.replace(\"::ffff:\", \"\") : first;\n\n return ip || \"\";\n}\n","import { EventType } from \"../types\";\n\nexport const SKIP_GOKWIK_EVENT = [\n EventType.INITIATE_CHECKOUT,\n EventType.ADD_PAYMENT_INFO,\n EventType.PURCHASE,\n];\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IViewContentEvent,\n type ISearchEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId, getBrowserInfo } from \"../utils/event-id\";\nimport { SKIP_GOKWIK_EVENT } from \"./constants\";\nimport { hashString } from \"../utils/pii-hashing\";\n\ndeclare global {\n interface Window {\n fbq?: (\n type: string,\n eventName: string,\n params?: Record<string, any>,\n options?: { eventID?: string; fbp?: string; fbc?: string },\n ) => void;\n }\n}\n\n/**\n * Configuration for a single Facebook Pixel\n */\ninterface SinglePixelConfig {\n /**\n * Facebook Pixel ID\n */\n pixelId: string;\n /**\n * Optional name/label for this pixel (for logging/debugging)\n */\n name?: string;\n /**\n * Enable server-side CAPI backup for this pixel\n * @default true\n */\n enableCAPI?: boolean;\n}\n\n/**\n * Configuration for the Multi-Pixel adapter\n */\nexport interface MultiPixelAdapterConfig {\n /**\n * Array of pixel configurations\n */\n pixels: SinglePixelConfig[];\n /**\n * Global CAPI setting (can be overridden per pixel)\n * @default true\n */\n enableCAPI?: boolean;\n\n /**\n * Skip certain events when GoKwik checkout is enabled to prevent duplicate tracking.\n * When true, events like checkout_initiated, purchase, and add_payment_info will be skipped\n * since GoKwik already tracks these events to Meta and Google if enabled.\n */\n gokwikEnabled?: boolean;\n}\n\n/**\n * Internal pixel instance for tracking\n */\ninterface PixelInstance {\n config: SinglePixelConfig;\n initialized: boolean;\n}\n\n/**\n * Multi-Pixel Facebook tracking adapter\n * Supports multiple Facebook Pixels with individual configurations\n */\nexport class MultiPixelAdapter extends BaseAdapter {\n public readonly name = \"MultiPixelFacebook\";\n private pixels: PixelInstance[] = [];\n\n constructor(config: MultiPixelAdapterConfig) {\n super(config);\n\n // Validate configuration\n if (!config.pixels || config.pixels.length === 0) {\n throw new Error(\n \"MultiPixelAdapter requires at least one pixel configuration\",\n );\n }\n\n // Initialize pixel instances\n this.pixels = config.pixels.map((pixelConfig) => ({\n config: {\n enableCAPI: config.enableCAPI ?? true,\n ...pixelConfig,\n },\n initialized: false,\n }));\n\n this.initializeLogger();\n }\n\n /**\n * Initialize all Facebook Pixels\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if fbq is available\n if (!window.fbq) {\n this.logger.warn(\n \"Facebook Pixel fbq not found. Make sure the script is loaded.\",\n );\n return;\n }\n\n // Initialize each pixel\n for (const pixel of this.pixels) {\n const { pixelId, name } = pixel.config;\n const pixelLabel = name || pixelId;\n\n try {\n // window.fbq!(\"init\", pixelId);\n pixel.initialized = true;\n } catch (error) {\n this.logger.error(\n `Failed to initialize pixel: ${pixelLabel}`,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n }\n\n this.initialized = true;\n }\n\n protected shouldSkipEvent(eventType: EventType): boolean {\n const gokwikActive = this.getConfig(\"gokwikEnabled\", false);\n if (gokwikActive) {\n return SKIP_GOKWIK_EVENT.includes(eventType);\n }\n return false;\n }\n\n /**\n * Track an event across all configured pixels\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n // Skip events that GoKwik already tracks to prevent duplicate tracking\n if (this.shouldSkipEvent(event.type)) {\n return;\n }\n\n const timestamp = Date.now();\n\n const transformEvent = {\n ...event,\n eventId: event.eventId || generateEventId(event.type),\n timestamp: event.timestamp || timestamp,\n event_source_url:\n event.event_source_url || !(typeof window === \"undefined\")\n ? window.location.href\n : \"\",\n };\n\n // Track client-side once (fbq automatically sends to all initialized pixels)\n await this.trackClientSide(transformEvent, adapterParams);\n\n // Track server-side for each pixel (requires individual API calls)\n if (this.pixels.some((pixel) => pixel.config.enableCAPI)) {\n await this.trackServerSide(transformEvent, adapterParams);\n }\n }\n\n /**\n * Track event on client-side once (Facebook automatically sends to all initialized pixels)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n if (typeof window === \"undefined\" || !window.fbq) {\n this.logger.warn(\"Cannot track client-side event, fbq not available\", {\n eventType: event.type,\n });\n return;\n }\n\n // Check if any pixel is initialized\n const hasInitializedPixel = this.pixels.some((pixel) => pixel.initialized);\n if (!hasInitializedPixel) {\n this.logger.warn(\"No pixels initialized for client-side tracking\");\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams,\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n const browserInfo = getBrowserInfo();\n\n try {\n window.fbq(\"track\", eventName, enhancedParams, {\n eventID: event.eventId,\n fbc: browserInfo.fbc,\n fbp: browserInfo.fbp,\n });\n } catch (error) {\n console.error(\"Facebook Pixel tracking error:\", error);\n }\n }\n\n /**\n * Track event on server-side for all enabled pixels\n */\n private async trackServerSide(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): Promise<void> {\n try {\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams,\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n const browserInfo = getBrowserInfo();\n\n const payload = {\n eventName,\n eventId: event.eventId,\n timestamp: event.timestamp,\n enhancedParams: enhancedParams,\n userInfo: browserInfo,\n };\n\n const endpoint = this.getConfig(\"capiEndpoint\", \"/api/events/multi\");\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n this.logger.error(`Server-side tracking failed: ${response.status}`);\n }\n } catch (error) {\n this.logger.error(\n `Server-side tracking failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n // Don't throw - analytics failures shouldn't break the user experience\n }\n }\n\n /**\n * Format event payload with pixel-specific customizations\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams,\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n switch (event.type) {\n case EventType.PAGE_VIEW: {\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, \"PageView\");\n baseParams = {\n event_source_url: pageViewEvent.event_source_url,\n };\n break;\n }\n\n case EventType.VIEW_CONTENT: {\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"ViewContent\");\n baseParams = {\n event_source_url: viewContentEvent.event_source_url,\n content_type: viewContentEvent.content_type || \"product\",\n content_ids: viewContentEvent.content_ids || [],\n content_name: viewContentEvent.content_name,\n content_category: viewContentEvent.content_category || \"product\",\n value: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || \"INR\",\n };\n break;\n }\n\n case EventType.ADD_TO_CART: {\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"AddToCart\");\n baseParams = {\n event_source_url: cartEvent.event_source_url,\n content_type: cartEvent.content_type || \"product\",\n content_ids: [cartEvent.productId],\n content_name: cartEvent.productName,\n value: cartEvent.price,\n currency: cartEvent.currency || \"INR\",\n };\n break;\n }\n\n case EventType.SEARCH: {\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, \"Search\");\n baseParams = {\n event_source_url: searchEvent.event_source_url,\n search_string: searchEvent.searchTerm,\n content_category: \"product\",\n content_ids: searchEvent.content_ids || [],\n };\n break;\n }\n\n case EventType.INITIATE_CHECKOUT: {\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"InitiateCheckout\");\n baseParams = {\n event_source_url: checkoutEvent.event_source_url,\n content_type: checkoutEvent.content_type || \"product\",\n currency: checkoutEvent.currency || \"INR\",\n value: checkoutEvent.cartValue,\n num_items:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n contents:\n checkoutEvent.items?.map((item) => ({\n id: item.productId,\n quantity: item.quantity || 1,\n item_price: item.price,\n })) || [],\n };\n break;\n }\n\n case EventType.PURCHASE: {\n const purchaseEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"Purchase\");\n baseParams = {\n event_source_url: purchaseEvent.event_source_url,\n content_type: purchaseEvent.content_type || \"product\",\n contents: purchaseEvent.contents || [],\n currency: purchaseEvent.currency || \"INR\",\n num_items:\n purchaseEvent.num_items || purchaseEvent.contents?.length || 0,\n value: purchaseEvent.value,\n order_id: purchaseEvent.order_id,\n };\n break;\n }\n\n default: {\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n }\n\n const enhancedParams = this.mergeEventData(baseParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n\n /**\n * Get configuration for all pixels\n */\n public getPixelConfigs(): SinglePixelConfig[] {\n return this.pixels.map((pixel) => pixel.config);\n }\n\n /**\n * Get initialization status for all pixels\n */\n public getPixelStatus(): Array<{\n pixelId: string;\n name?: string;\n initialized: boolean;\n }> {\n return this.pixels.map((pixel) => ({\n pixelId: pixel.config.pixelId,\n name: pixel.config.name,\n initialized: pixel.initialized,\n }));\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IViewedProductEvent,\n type IAddToCartEvent,\n type ISearchEvent,\n type IAddPaymentInfoEvent,\n type IViewSearchResultsEvent,\n type IBeginCheckoutEvent,\n type IViewContentEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\nimport { SKIP_GOKWIK_EVENT } from \"./constants\";\n\ndeclare global {\n interface Window {\n gtag?: (...args: any[]) => void;\n }\n}\n\n/**\n * Configuration for the Google Analytics adapter\n */\nexport interface GoogleAdapterConfig {\n /**\n * Google Analytics measurement ID (e.g., G-XXXXXXXXXX)\n */\n measurementId: string;\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n\n /**\n * Skip certain events when GoKwik checkout is enabled to prevent duplicate tracking.\n * When true, events like checkout_initiated, purchase, and add_payment_info will be skipped\n * since GoKwik already tracks these events to Meta and Google if enabled.\n */\n gokwikEnabled?: boolean;\n}\n\n/**\n * Google Analytics tracking adapter\n * Assumes that the Google Analytics script is already loaded in the page\n */\nexport class GoogleAdapter extends BaseAdapter {\n public readonly name = \"GoogleAnalytics\";\n\n constructor(config: GoogleAdapterConfig) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Initialize Google Analytics adapter\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if gtag is available\n if (!window.gtag) {\n this.logger.warn(\n \"Google Analytics gtag not found. Make sure the script is loaded.\"\n );\n return;\n }\n\n this.initialized = true;\n }\n\n protected shouldSkipEvent(eventType: EventType): boolean {\n const gokwikActive = this.getConfig(\"gokwikEnabled\", false);\n if (gokwikActive) {\n return SKIP_GOKWIK_EVENT.includes(eventType);\n }\n return false;\n }\n\n /**\n * Track an event with Google Analytics\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Skip events that GoKwik already tracks to prevent duplicate tracking\n if (this.shouldSkipEvent(event.type)) {\n return;\n }\n\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return this.initialized && typeof window !== \"undefined\" && !!window.gtag;\n }\n\n /**\n * Track event on client-side (browser Google Analytics)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\" || !window.gtag) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or gtag not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n window.gtag?.(\"event\", eventName, finalParams);\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n // Get the payload seprately\n const { type, ...payload } = event;\n\n switch (type) {\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"view_item\");\n baseParams = {\n currency: viewContentEvent.currency || \"USD\",\n value: viewContentEvent.value || 0,\n items:\n viewContentEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n };\n break;\n\n case EventType.VIEWED_PRODUCT:\n const viewedProductEvent = event as IViewedProductEvent;\n eventName = this.getEventName(adapterParams, \"viewed_product\");\n baseParams = {\n currency: viewedProductEvent.currency,\n value: viewedProductEvent.price,\n items: [\n {\n item_id: viewedProductEvent.productId,\n item_name: viewedProductEvent.productName,\n price: viewedProductEvent.price,\n currency: viewedProductEvent.currency,\n },\n ],\n view_duration: viewedProductEvent.viewDuration,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"add_to_cart\");\n baseParams = {\n currency: cartEvent.currency || \"INR\",\n value: cartEvent.price * (cartEvent.quantity || 1),\n items: [\n {\n item_id: cartEvent.productId,\n item_name: cartEvent.productName,\n price: cartEvent.price,\n quantity: cartEvent.quantity || 1,\n item_variant: cartEvent.variant,\n },\n ],\n };\n break;\n\n case EventType.SEARCH:\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, \"search\");\n baseParams = {\n search_term: searchEvent.searchTerm,\n page_location:\n typeof window !== \"undefined\" ? window.location.href : \"\",\n page_referrer:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_title: typeof document !== \"undefined\" ? document.title : \"\",\n };\n break;\n\n case EventType.VIEW_SEARCH_RESULTS:\n const viewSearchResultsEvent = event as IViewSearchResultsEvent;\n eventName = this.getEventName(adapterParams, \"view_search_results\");\n baseParams = {\n search_term: viewSearchResultsEvent.search_term,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"begin_checkout\");\n baseParams = {\n currency: checkoutEvent.currency || \"USD\",\n value: checkoutEvent.value || 0,\n coupon: checkoutEvent.coupon,\n items:\n checkoutEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n page_location:\n typeof window !== \"undefined\" ? window.location.href : \"\",\n page_referrer:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_title: typeof document !== \"undefined\" ? document.title : \"\",\n };\n break;\n\n case EventType.ADD_PAYMENT_INFO:\n const addPaymentInfoEvent = event as IAddPaymentInfoEvent;\n eventName = this.getEventName(adapterParams, \"add_payment_info\");\n baseParams = {\n currency: addPaymentInfoEvent.currency || \"INR\",\n value: addPaymentInfoEvent.cartValue,\n payment_type: addPaymentInfoEvent.paymentType || \"\",\n items:\n addPaymentInfoEvent.items?.map((item) => ({\n item_id: item.productId,\n item_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n item_variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.PURCHASE:\n const purchaseEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"purchase\");\n baseParams = {\n transaction_id: purchaseEvent.transaction_id,\n value: purchaseEvent.value,\n currency: purchaseEvent.currency || \"USD\",\n coupon: purchaseEvent.coupon,\n shipping: purchaseEvent.shipping,\n tax: purchaseEvent.tax,\n items:\n purchaseEvent.items?.map((item: any) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_category: item.item_category,\n item_category2: item.item_category2,\n item_category3: item.item_category3,\n item_category4: item.item_category4,\n item_category5: item.item_category5,\n item_brand: item.item_brand,\n item_variant: item.item_variant,\n price: item.price,\n quantity: item.quantity,\n })) || [],\n };\n break;\n\n case EventType.CUSTOM:\n eventName = this.getEventName(adapterParams, \"custom\");\n baseParams = payload || {};\n break;\n\n case EventType.SPECIFIC:\n eventName = this.getEventName(adapterParams, \"\");\n if (!eventName) {\n this.logger.warn(`Skipping specific event with no event name`);\n return { eventName: \"\", enhancedParams: {} };\n }\n baseParams = payload || {};\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IRemoveFromCartEvent,\n type ISearchEvent,\n type IUserSignupEvent,\n type IUserLoginEvent,\n type IViewContentEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\n\nimport moengage from \"@moengage/web-sdk\";\n\n/**\n * Event name constants for tracking platforms\n */\nexport const EventNames = {\n // Page events\n PAGE_VIEWED: \"Page Viewed\",\n\n // Product events\n PRODUCT_VIEWED: \"Product Viewed\",\n ADDED_TO_CART: \"Added To Cart\",\n REMOVED_FROM_CART: \"Removed From Cart\",\n\n // Checkout events\n CHECKOUT_INITIATED: \"Checkout Started\",\n PURCHASE_COMPLETED: \"Purchase Completed\",\n\n // Search events\n SEARCH: \"Search\",\n\n // User events\n USER_SIGNED_UP: \"User Signed Up\",\n USER_LOGGED_IN: \"User Logged In\",\n};\n\n/**\n * Default currency code\n */\nexport const DEFAULT_CURRENCY = \"INR\";\n\n/**\n * Configuration for the MoenGage adapter\n */\nexport interface MoengageAdapterConfig {\n /**\n * MoenGage App ID (required for SDK initialization)\n */\n appId: string;\n /**\n * Whether to enable user identification\n */\n enableUserIdentification?: boolean;\n /**\n * Debug mode for MoenGage SDK\n */\n debug?: boolean;\n /**\n * Data center region (default: 'dc_01')\n */\n region?: string;\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n}\n\n/**\n * MoenGage tracking adapter using the official Web SDK\n */\nexport class MoengageAdapter extends BaseAdapter {\n public readonly name = \"MoEngage\";\n\n constructor(config: MoengageAdapterConfig) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Get MoEngage SDK instance from window\n */\n private getMoengageSDK(): any {\n return typeof window !== \"undefined\" ? (window as any).Moengage : null;\n }\n\n /**\n * Initialize the MoenGage adapter using the Web SDK\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n try {\n const appId = this.getConfig<string>(\"appId\");\n if (!appId) {\n this.logger.warn(\"App ID is required for initialization\");\n return;\n }\n\n // Initialize MoenGage SDK\n const region = this.getConfig<string>(\"region\", \"dc_01\");\n const config = {\n app_id: appId,\n debug_logs: this.getConfig<boolean>(\"debug\", false) ? 1 : 0,\n cluster: region,\n disableCookies: true,\n };\n\n // Initialize MoEngage SDK\n moengage.initialize(config);\n\n this.initialized = true;\n } catch (error) {\n this.logger.error(\"Failed to initialize\", error as Error);\n }\n }\n\n /**\n * Track an event with MoenGage SDK\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return (\n this.initialized &&\n typeof window !== \"undefined\" &&\n !!this.getMoengageSDK()\n );\n }\n\n /**\n * Track event on client-side (browser MoEngage)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n const sdk = this.getMoengageSDK();\n if (!this.initialized || typeof window === \"undefined\" || !sdk) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or SDK not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams, shouldIdentifyUser, userId } =\n this.formatEventPayload(event, adapterParams);\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n sdk?.track_event(eventName, finalParams);\n\n // Handle user identification for signup/login events\n if (\n shouldIdentifyUser &&\n userId &&\n this.getConfig<boolean>(\"enableUserIdentification\", true)\n ) {\n sdk?.add_unique_user_id(userId);\n }\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): {\n eventName: string;\n enhancedParams: Record<string, any>;\n shouldIdentifyUser?: boolean;\n userId?: string;\n } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n let shouldIdentifyUser = false;\n let userId: string | undefined;\n\n // Get the payload seprately\n const { type, ...payload } = event;\n\n switch (type) {\n case EventType.PAGE_VIEW:\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, EventNames.PAGE_VIEWED);\n baseParams = {\n page_location: pageViewEvent.page_location || pageViewEvent.path,\n page_title: pageViewEvent.page_title || pageViewEvent.title,\n page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n page_path: pageViewEvent.page_path || pageViewEvent.path,\n page_url: typeof window !== \"undefined\" ? window.location.href : \"\",\n referrer:\n pageViewEvent.referrer ||\n (typeof document !== \"undefined\" ? document.referrer : \"\"),\n };\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, EventNames.PRODUCT_VIEWED);\n baseParams = {\n content_type: viewContentEvent.content_type || \"product\",\n product_id: viewContentEvent.content_ids || [],\n product_name: viewContentEvent.content_name || \"\",\n category: viewContentEvent.content_category || \"\",\n price: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || DEFAULT_CURRENCY,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n const quantity = cartEvent.quantity ?? 1;\n eventName = this.getEventName(adapterParams, EventNames.ADDED_TO_CART);\n baseParams = {\n product_id: cartEvent.productId,\n product_name: cartEvent.productName,\n price: cartEvent.price,\n currency: cartEvent.currency || DEFAULT_CURRENCY,\n quantity: quantity,\n variant: cartEvent.variant,\n total_value: cartEvent.price * quantity,\n };\n break;\n\n case EventType.REMOVE_FROM_CART:\n const removeCartEvent = event as IRemoveFromCartEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.REMOVED_FROM_CART\n );\n baseParams = {\n product_id: removeCartEvent.productId,\n product_name: removeCartEvent.productName,\n price: removeCartEvent.price,\n currency: removeCartEvent.currency || DEFAULT_CURRENCY,\n quantity: removeCartEvent.quantity,\n variant: removeCartEvent.variant,\n total_value: removeCartEvent.price * removeCartEvent.quantity,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutStartedEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.CHECKOUT_INITIATED\n );\n baseParams = {\n cart_value: checkoutStartedEvent.cartValue,\n currency: checkoutStartedEvent.currency || DEFAULT_CURRENCY,\n item_count: checkoutStartedEvent.itemCount,\n items:\n checkoutStartedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.PURCHASE:\n const checkoutCompletedEvent = event as IPurchaseEvent;\n eventName = this.getEventName(\n adapterParams,\n EventNames.PURCHASE_COMPLETED\n );\n baseParams = {\n order_id: checkoutCompletedEvent.orderId,\n cart_value: checkoutCompletedEvent.cartValue,\n currency: checkoutCompletedEvent.currency || DEFAULT_CURRENCY,\n item_count: checkoutCompletedEvent.itemCount,\n items:\n checkoutCompletedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity,\n variant: item.variant,\n })) || [],\n };\n break;\n\n case EventType.SEARCH:\n const searchEvent = event as ISearchEvent;\n eventName = this.getEventName(adapterParams, EventNames.SEARCH);\n baseParams = {\n search_term: searchEvent.searchTerm,\n results_count: searchEvent.resultsCount,\n };\n break;\n\n case EventType.USER_SIGNUP:\n const signupEvent = event as IUserSignupEvent;\n eventName = this.getEventName(adapterParams, EventNames.USER_SIGNED_UP);\n baseParams = {\n user_id: signupEvent.userId,\n method: signupEvent.method,\n success: signupEvent.success,\n };\n shouldIdentifyUser = true;\n userId = signupEvent.userId;\n break;\n\n case EventType.USER_LOGIN:\n const loginEvent = event as IUserLoginEvent;\n eventName = this.getEventName(adapterParams, EventNames.USER_LOGGED_IN);\n baseParams = {\n user_id: loginEvent.userId,\n method: loginEvent.method,\n success: loginEvent.success,\n };\n shouldIdentifyUser = true;\n userId = loginEvent.userId;\n break;\n\n case EventType.CUSTOM:\n eventName = this.getEventName(adapterParams, \"custom\");\n baseParams = payload || {};\n break;\n\n case EventType.SPECIFIC:\n eventName = this.getEventName(adapterParams, \"\");\n if (!eventName) {\n this.logger.warn(`Skipping specific event with no event name`);\n return {\n eventName: \"\",\n enhancedParams: {},\n shouldIdentifyUser: false,\n };\n }\n baseParams = payload || {};\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {}, shouldIdentifyUser: false };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams, shouldIdentifyUser, userId };\n }\n}\n","import { BaseAdapter } from \"./base-adapter\";\nimport {\n type TEvent,\n EventType,\n type IPageViewEvent,\n type IAddToCartEvent,\n type IViewContentEvent,\n type IBeginCheckoutEvent,\n type IPurchaseEvent,\n} from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\nimport { generateEventId } from \"../utils/event-id\";\n\ndeclare global {\n interface Window {\n posthog?: {\n capture: (eventName: string, properties?: Record<string, any>) => void;\n identify: (distinctId: string, properties?: Record<string, any>) => void;\n };\n }\n}\n\n/**\n * Configuration for the PostHog adapter\n */\nexport interface PostHogAdapterConfig {\n /**\n * Enable debug logs\n */\n enableDebugLogs?: boolean;\n}\n\n/**\n * PostHog tracking adapter\n * Assumes that the PostHog script is already loaded in the page\n */\nexport class PostHogAdapter extends BaseAdapter {\n public readonly name = \"PostHog\";\n\n constructor(config: PostHogAdapterConfig = {}) {\n super(config);\n // Initialize logger with proper adapter name\n this.initializeLogger();\n }\n\n /**\n * Initialize PostHog\n */\n public async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n // Skip initialization if running on server\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if posthog is available\n if (!window.posthog) {\n this.logger.warn(\n \"PostHog object not found. Make sure the script is loaded.\"\n );\n return;\n }\n\n this.initialized = true;\n }\n\n /**\n * Track an event with PostHog\n * @param event The event to track\n * @param adapterParams Optional adapter-specific parameters\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n // Generate unique event ID for deduplication if not already present\n if (!event.eventId) {\n event.eventId = generateEventId(event.type);\n }\n\n // Ensure timestamp is always available\n if (!event.timestamp) {\n event.timestamp = Date.now();\n }\n\n // Track client-side only\n await this.trackClientSide(event, adapterParams);\n }\n\n /**\n * Check if the adapter is enabled\n */\n public isEnabled(): boolean {\n return (\n this.initialized && typeof window !== \"undefined\" && !!window.posthog\n );\n }\n\n /**\n * Track event on client-side (browser PostHog)\n */\n private async trackClientSide(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\" || !window.posthog) {\n this.logger.warn(\n \"Cannot track client-side event, adapter not initialized or posthog not available\",\n {\n eventType: event.type,\n }\n );\n return;\n }\n\n const { eventName, enhancedParams } = this.formatEventPayload(\n event,\n adapterParams\n );\n\n // Skip tracking if eventName is empty (unknown event type)\n if (!eventName) {\n return;\n }\n\n // Add event_id for deduplication\n const finalParams = {\n ...enhancedParams,\n ...(event.eventId && { event_id: event.eventId }),\n };\n\n window.posthog?.capture(eventName, finalParams);\n }\n\n /**\n * Utility function to format event payload for client-side tracking\n */\n private formatEventPayload(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): { eventName: string; enhancedParams: Record<string, any> } {\n let baseParams: Record<string, any> = {};\n let eventName = \"\";\n\n switch (event.type) {\n case EventType.PAGE_VIEW:\n const pageViewEvent = event as IPageViewEvent;\n eventName = this.getEventName(adapterParams, \"$pageview\");\n baseParams = {\n // PostHog-compatible parameters\n $current_url: pageViewEvent.page_location || pageViewEvent.path,\n $title: pageViewEvent.page_title || pageViewEvent.title,\n $referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n // Custom parameters\n page_location: pageViewEvent.page_location || pageViewEvent.path,\n page_title: pageViewEvent.page_title || pageViewEvent.title,\n page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,\n page_path: pageViewEvent.page_path || pageViewEvent.path,\n event_category: pageViewEvent.event_category,\n };\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentEvent = event as IViewContentEvent;\n eventName = this.getEventName(adapterParams, \"view_content\");\n baseParams = {\n content_type: viewContentEvent.content_type || \"product\",\n content_ids: viewContentEvent.content_ids || [],\n content_name: viewContentEvent.content_name || \"\",\n content_category: viewContentEvent.content_category || \"\",\n value: viewContentEvent.value || 0,\n currency: viewContentEvent.currency || \"INR\",\n // PostHog specific format\n $product_id: viewContentEvent.content_ids || [],\n $product_name: viewContentEvent.content_name || \"\",\n $product_category: viewContentEvent.content_category || \"\",\n $product_price: viewContentEvent.value || 0,\n };\n break;\n\n case EventType.ADD_TO_CART:\n const cartEvent = event as IAddToCartEvent;\n eventName = this.getEventName(adapterParams, \"add_to_cart\");\n baseParams = {\n product_id: cartEvent.productId,\n product_name: cartEvent.productName,\n price: cartEvent.price,\n currency: cartEvent.currency || \"INR\",\n quantity: cartEvent.quantity,\n variant: cartEvent.variant,\n // PostHog specific format\n $product_id: cartEvent.productId,\n $product_name: cartEvent.productName,\n $product_price: cartEvent.price,\n $quantity: cartEvent.quantity,\n };\n break;\n\n case EventType.INITIATE_CHECKOUT:\n const checkoutEvent = event as IBeginCheckoutEvent;\n eventName = this.getEventName(adapterParams, \"checkout_started\");\n baseParams = {\n currency: checkoutEvent.currency || \"INR\",\n value: checkoutEvent.cartValue,\n num_items:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n items:\n checkoutEvent.items?.map((item) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity || 1,\n variant: item.variant,\n })) || [],\n // PostHog specific format\n $cart_value: checkoutEvent.cartValue,\n $item_count:\n checkoutEvent.itemCount || checkoutEvent.items?.length || 0,\n };\n break;\n\n case EventType.PURCHASE:\n const checkoutCompletedEvent = event as IPurchaseEvent;\n eventName = this.getEventName(adapterParams, \"purchase\");\n baseParams = {\n transaction_id: checkoutCompletedEvent.orderId,\n currency: checkoutCompletedEvent.currency || \"INR\",\n value: checkoutCompletedEvent.cartValue,\n num_items:\n checkoutCompletedEvent.itemCount ||\n checkoutCompletedEvent.items?.length ||\n 0,\n items:\n checkoutCompletedEvent.items?.map((item: any) => ({\n product_id: item.productId,\n product_name: item.productName,\n price: item.price,\n quantity: item.quantity || 1,\n variant: item.variant,\n })) || [],\n // PostHog specific format\n $order_id: checkoutCompletedEvent.orderId,\n $order_value: checkoutCompletedEvent.cartValue,\n $order_currency: checkoutCompletedEvent.currency || \"INR\",\n $order_items_count:\n checkoutCompletedEvent.itemCount ||\n checkoutCompletedEvent.items?.length ||\n 0,\n };\n break;\n\n default:\n // Skip tracking for unknown event types\n this.logger.warn(`Skipping unknown event type: ${event.type}`);\n return { eventName: \"\", enhancedParams: {} };\n }\n\n const affiliateParams = this.enhanceWithAffiliateParams(baseParams);\n const experimentParams = this.enhanceWithExperimentParams(affiliateParams);\n const enhancedParams = this.mergeEventData(experimentParams, adapterParams);\n\n return { eventName, enhancedParams };\n }\n}\n","import {\n sendShopifyAnalytics,\n getClientBrowserParameters,\n AnalyticsEventName,\n type ShopifyAnalyticsProduct,\n type ShopifyPageViewPayload,\n ShopifySalesChannel,\n} from \"@shopify/hydrogen-react\";\nimport { BaseAdapter } from \"./base-adapter\";\nimport type { TEvent } from \"../types\";\nimport { EventType } from \"../types\";\nimport type { TAdapterParams } from \"../adapter-params\";\n\n// Constants based on environment variables\nconst DEFAULT_CURRENCY = \"INR\";\nconst DEFAULT_LANGUAGE = \"en\";\n\n/**\n * Type definitions for analytics payloads\n */\ntype SendPageViewPayload = {\n pageType?: string;\n products?: ShopifyAnalyticsProduct[];\n collectionHandle?: string;\n searchString?: string;\n totalValue?: number;\n cartId?: string;\n};\n\ntype SendAddToCartPayload = {\n cartId: string;\n products?: ShopifyAnalyticsProduct[];\n totalValue?: ShopifyPageViewPayload[\"totalValue\"];\n};\n\n/**\n * Configuration interface for Shopify Analytics Adapter\n */\nexport interface ShopifyAdapterConfig {\n shopId: string;\n domain: string;\n merchantName: string;\n currency?: string;\n}\n\n/**\n * Shopify Analytics Adapter for tracking events to Shopify Admin Analytics\n */\nexport class ShopifyAdapter extends BaseAdapter {\n public readonly name = \"ShopifyAnalytics\";\n private shopId: string;\n private domain: string;\n private currency: string;\n private merchantName: string;\n\n constructor(config: ShopifyAdapterConfig) {\n super(config);\n this.shopId = config.shopId;\n this.domain = config.domain;\n this.currency = config.currency || DEFAULT_CURRENCY;\n this.merchantName = config.merchantName;\n }\n\n /**\n * Initialize the Shopify Analytics adapter\n */\n public async initialize(): Promise<void> {\n this.initializeLogger();\n\n try {\n // Enable Shopify cookies for attribution tracking\n if (typeof window !== \"undefined\") {\n // Note: useShopifyCookies should be called at the React component level\n // This will be handled in the ShopkitAnalytics component\n }\n this.initialized = true;\n } catch (error) {\n this.logger.error(\n \"Failed to initialize Shopify Analytics\",\n error instanceof Error ? error : new Error(String(error))\n );\n throw error;\n }\n }\n\n /**\n * Convert product ID to Shopify GID format if it's not already\n */\n private formatProductGid(productId: string): string {\n return productId.startsWith(\"gid://shopify/Product/\")\n ? productId\n : `gid://shopify/Product/${productId}`;\n }\n\n /**\n * Get user consent status from your consent management system\n */\n private getUserConsent() {\n // Check if user has given consent (implement based on your consent system)\n const hasConsent = this.checkUserConsent();\n\n return {\n hasUserConsent: hasConsent,\n analyticsAllowed: hasConsent && this.checkAnalyticsConsent(),\n marketingAllowed: hasConsent && this.checkMarketingConsent(),\n saleOfDataAllowed: hasConsent && this.checkSaleOfDataConsent(),\n };\n }\n\n /**\n * Check user consent (implement based on your consent management)\n */\n private checkUserConsent(): boolean {\n // Example implementations:\n // return localStorage.getItem('user_consent') === 'true';\n // return document.cookie.includes('consent=granted');\n // return window.gtag?.('consent', 'query') === 'granted';\n\n // For now, return true but implement your actual consent logic\n return true;\n }\n\n private checkAnalyticsConsent(): boolean {\n // Implement your analytics consent check\n return true;\n }\n\n private checkMarketingConsent(): boolean {\n // Implement your marketing consent check\n return true;\n }\n\n private checkSaleOfDataConsent(): boolean {\n // Implement your sale of data consent check\n return true;\n }\n\n /**\n * Create base payload for all events\n */\n private createBasePayload(): any {\n const consent = this.getUserConsent();\n\n return {\n ...getClientBrowserParameters(),\n ...consent,\n storefrontId: this.shopId,\n shopifySalesChannel: ShopifySalesChannel.headless,\n shopId: `gid://shopify/Shop/${this.shopId}`,\n currency: this.currency,\n acceptedLanguage: DEFAULT_LANGUAGE,\n ...this.enhanceWithExperimentParams(this.enhanceWithAffiliateParams({})),\n };\n }\n\n /**\n * Send page view event using the enhanced functionality\n */\n public sendPageView = (\n eventName: keyof typeof AnalyticsEventName,\n payload?: SendPageViewPayload\n ) => {\n const enhancedPayload = {\n ...this.createBasePayload(),\n ...payload,\n };\n\n return sendShopifyAnalytics({\n eventName,\n payload: enhancedPayload,\n });\n };\n\n /**\n * Send add to cart event using the enhanced functionality\n */\n public sendAddToCart = ({\n cartId,\n totalValue,\n products,\n }: SendAddToCartPayload) => {\n return this.sendPageView(AnalyticsEventName.ADD_TO_CART, {\n cartId,\n totalValue,\n products,\n });\n };\n\n /**\n * Track an event using Shopify Analytics\n */\n public async trackEvent(\n event: TEvent,\n adapterParams?: TAdapterParams\n ): Promise<void> {\n if (!this.initialized || typeof window === \"undefined\") {\n this.logger.warn(\n \"Shopify Analytics not initialized or not in browser environment\"\n );\n return;\n }\n\n // Get adapter-specific parameters\n const params = this.getAdapterParams(adapterParams);\n const customEventName = this.getEventName(params, event.type);\n\n // Enhance event with affiliate and experiment data\n const affiliateParams = this.enhanceWithAffiliateParams(event);\n const enhancedEvent = this.enhanceWithExperimentParams(affiliateParams);\n\n try {\n switch (event.type) {\n case EventType.SHOPIFY_PAGE_VIEW:\n case EventType.PAGE_VIEW:\n const pageViewPayload = this.mergeEventData(enhancedEvent, params);\n this.sendPageView(AnalyticsEventName.PAGE_VIEW, pageViewPayload);\n break;\n\n case EventType.VIEW_CONTENT:\n const viewContentPayload = this.mergeEventData(enhancedEvent, params);\n this.sendPageView(\n AnalyticsEventName.PRODUCT_VIEW,\n viewContentPayload\n );\n break;\n\n case EventType.ADD_TO_CART:\n const addToCartPayload = this.mergeEventData(enhancedEvent, params);\n this.trackAddToCart(addToCartPayload);\n break;\n\n case EventType.INITIATE_CHECKOUT:\n // For checkout events, send as PAGE_VIEW with checkout page context\n const checkoutPayload = this.mergeEventData(\n { ...enhancedEvent, pageType: \"checkout\" },\n params\n );\n this.sendPageView(AnalyticsEventName.PAGE_VIEW, checkoutPayload);\n break;\n\n default:\n this.logger.warn(\"Event not supported by Shopify Analytics\", {\n eventType: event.type,\n });\n break;\n }\n } catch (error) {\n this.logger.error(\n \"Error tracking Shopify Analytics event\",\n error instanceof Error ? error : new Error(String(error)),\n { eventType: event.type }\n );\n }\n }\n\n /**\n * Check if Shopify session is properly established\n */\n public isSessionValid(): boolean {\n if (typeof window === \"undefined\") return false;\n\n const shopifyY = document.cookie.includes(\"_shopify_y=\");\n const shopifyS = document.cookie.includes(\"_shopify_s=\");\n\n return shopifyY && shopifyS;\n }\n\n /**\n * Get session debug information\n */\n public getSessionDebugInfo(): object {\n if (typeof window === \"undefined\")\n return { error: \"Not in browser environment\" };\n\n return {\n sessionValid: this.isSessionValid(),\n cookies: {\n shopify_y: document.cookie.includes(\"_shopify_y=\"),\n shopify_s: document.cookie.includes(\"_shopify_s=\"),\n all: document.cookie,\n },\n shopId: this.shopId,\n initialized: this.initialized,\n };\n }\n\n /**\n * Track add to cart event with enhanced error handling\n */\n private trackAddToCart(event: any): void {\n if (!event.productId) {\n this.logger.warn(\"ADD_TO_CART event missing productId\");\n return;\n }\n\n try {\n const productGid = this.formatProductGid(event.productId);\n const cartKey = `merchant_${this.merchantName}_cartId`;\n const cartId = localStorage.getItem(cartKey) || \"\";\n\n if (!cartId) {\n this.logger.warn(\"No cart ID found, creating anonymous session\");\n // You might want to generate a temporary cart ID or handle this case\n }\n\n // Validate product data\n if (!event.price || event.price <= 0) {\n this.logger.warn(\"Invalid or missing price for ADD_TO_CART\", {\n price: event.price,\n });\n }\n\n // Create products array for analytics\n const productPrice = Math.max(0, event.price || 0);\n const productQuantity = Math.max(1, event.quantity || 1);\n\n const products: ShopifyAnalyticsProduct[] = [\n {\n productGid: productGid,\n variantGid:\n event.variantId || productGid.replace(\"Product\", \"ProductVariant\"),\n quantity: productQuantity,\n price: productPrice.toString(), // Convert to string as required by ShopifyAnalyticsProduct\n name: event.productName || \"Unknown Product\",\n brand: event.brand || \"Unknown Brand\",\n },\n ];\n\n const totalValue = productPrice * productQuantity;\n\n // Use the enhanced sendAddToCart method\n this.sendAddToCart({\n cartId,\n products,\n totalValue,\n });\n } catch (error) {\n this.logger.error(\n \"Error in trackAddToCart\",\n error instanceof Error ? error : new Error(String(error))\n );\n // Don't throw - just log the error to prevent breaking the user experience\n }\n }\n}\n","import {\n GoogleAdapter,\n MoengageAdapter,\n PostHogAdapter,\n MultiPixelAdapter,\n} from \"../adapters\";\n\n/**\n * Initialize the event tracking system with the provided adapters\n * @param adapters Array of tracking adapters to register\n */\nexport async function initializeEventTracking(\n adapters: import(\"./subscriber\").TrackingAdapter[]\n): Promise<void> {\n // Import the subscriber\n const { eventSubscriber } = await import(\"./subscriber\");\n\n // Register each adapter using for...of instead of forEach\n for (const adapter of adapters) {\n eventSubscriber.registerAdapter(adapter);\n }\n\n // Initialize the subscriber\n await eventSubscriber.initialize();\n}\n\n/**\n * Example initialization function with common adapters\n * This is a convenience function that shows how to set up common tracking adapters\n * Users can customize this based on their needs\n */\nexport async function initTracking(config: {\n pixelId?: string;\n pixelIds?: string[];\n gaId?: string;\n moengageAppId?: string;\n moengageRegion?: string;\n enableDebugLogs?: boolean;\n}) {\n console.log(\"Initializing event tracking system...\");\n\n const adapters = [];\n\n // Facebook Pixel (Multi-Pixel)\n if (config.pixelId || config.pixelIds) {\n const pixelIds = config.pixelIds || (config.pixelId ? [config.pixelId] : []);\n if (pixelIds.length > 0) {\n const multiPixelAdapter = new MultiPixelAdapter({\n pixels: pixelIds.map((id) => ({ pixelId: id })),\n });\n adapters.push(multiPixelAdapter);\n }\n }\n\n // Google Analytics\n if (config.gaId) {\n const gaAdapter = new GoogleAdapter({\n measurementId: config.gaId,\n });\n adapters.push(gaAdapter);\n }\n\n // MoEngage\n if (config.moengageAppId) {\n const moengageAdapter = new MoengageAdapter({\n appId: config.moengageAppId,\n enableUserIdentification: true,\n region: config.moengageRegion || \"dc_01\",\n debug: config.enableDebugLogs || false,\n });\n adapters.push(moengageAdapter);\n }\n\n // PostHog\n const posthogAdapter = new PostHogAdapter({\n enableDebugLogs: config.enableDebugLogs || false,\n });\n adapters.push(posthogAdapter);\n\n console.log(\n \"Configured adapters:\",\n adapters.map((a) => a.name)\n );\n\n await initializeEventTracking(adapters);\n console.log(\"Event tracking system initialized successfully\");\n}\n","\"use client\";\n\n\nimport { useEffect } from \"react\";\nimport {\n captureAffiliateParams,\n configureAffiliateTracker,\n} from \"./affiliate-tracker\";\nimport type { AffiliateConfig } from \"./types\";\n\ninterface AffiliateTrackerProps {\n config?: Partial<AffiliateConfig>;\n autoCapture?: boolean;\n children?: React.ReactNode;\n}\n\nconst AffiliateTracker: React.FC<AffiliateTrackerProps> = ({\n config,\n autoCapture = true,\n children,\n}) => {\n useEffect(() => {\n // Configure the tracker if config is provided\n if (config) {\n configureAffiliateTracker(config);\n }\n\n // Auto-capture affiliate params if enabled\n if (autoCapture) {\n captureAffiliateParams();\n }\n }, [config, autoCapture]);\n\n return children ? <>{children}</> : null;\n};\n\nexport default AffiliateTracker;\nexport type { AffiliateTrackerProps };\n","/**\n * Centralized constants for affiliate tracking parameters\n */\n\n// Core UTM parameters\nexport const UTM_PARAMETERS = [\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n] as const;\n\n// Click ID parameters from various platforms\nexport const CLICK_ID_PARAMETERS = [\n \"gclid\", // Google Ads\n \"fbclid\", // Facebook\n \"msclkid\", // Microsoft Ads\n \"ttclid\", // TikTok\n \"twclid\", // Twitter\n \"li_fat_id\", // LinkedIn\n] as const;\n\n// Generic affiliate parameters\nexport const AFFILIATE_PARAMETERS = [\n \"click_id\",\n \"affiliate_id\",\n \"ref\",\n \"source\",\n \"referrer\",\n] as const;\n\n// All supported affiliate tracking parameters\nexport const ALL_AFFILIATE_PARAMETERS = [\n ...UTM_PARAMETERS,\n ...CLICK_ID_PARAMETERS,\n ...AFFILIATE_PARAMETERS,\n] as const;\n\n// Default storage configuration\nexport const STORAGE_CONFIG = {\n DEFAULT_KEY: \"affiliateParams\",\n DEFAULT_TTL: 30 * 24 * 60 * 60 * 1000, // 30 days in milliseconds\n} as const;\n\n// Attribution models\nexport const ATTRIBUTION_MODELS = {\n FIRST_TOUCH: \"first-touch\",\n LAST_TOUCH: \"last-touch\",\n} as const;\n\n// Storage types\nexport const STORAGE_TYPES = {\n SESSION: \"sessionStorage\",\n LOCAL: \"localStorage\",\n} as const;\n\n// Event types\nexport const EVENT_TYPES = {\n CAPTURE: \"capture\",\n CLEAR: \"clear\",\n EXPIRE: \"expire\",\n} as const;\n\n// Attribution channels for classification\nexport const ATTRIBUTION_CHANNELS = {\n DIRECT: \"direct\",\n PAID_SEARCH: \"paid_search\",\n ORGANIC_SEARCH: \"organic_search\",\n SOCIAL: \"social\",\n EMAIL: \"email\",\n AFFILIATE: \"affiliate\",\n REFERRAL: \"referral\",\n DISPLAY: \"display\",\n} as const;\n\n// Search engines for referrer classification\nexport const SEARCH_ENGINES = [\n \"google.com\",\n \"bing.com\",\n \"yahoo.com\",\n \"duckduckgo.com\",\n \"baidu.com\",\n \"yandex.com\",\n \"ask.com\",\n] as const;\n\n// Social media platforms for source classification\nexport const SOCIAL_PLATFORMS = [\n \"facebook\",\n \"instagram\",\n \"twitter\",\n \"linkedin\",\n \"tiktok\",\n \"youtube\",\n \"pinterest\",\n \"snapchat\",\n] as const;\n\n// Type definitions for the constants\nexport type UTMParameter = (typeof UTM_PARAMETERS)[number];\nexport type ClickIdParameter = (typeof CLICK_ID_PARAMETERS)[number];\nexport type AffiliateParameter = (typeof AFFILIATE_PARAMETERS)[number];\nexport type AllAffiliateParameter = (typeof ALL_AFFILIATE_PARAMETERS)[number];\nexport type AttributionModel =\n (typeof ATTRIBUTION_MODELS)[keyof typeof ATTRIBUTION_MODELS];\nexport type StorageType = (typeof STORAGE_TYPES)[keyof typeof STORAGE_TYPES];\nexport type EventType = (typeof EVENT_TYPES)[keyof typeof EVENT_TYPES];\nexport type AttributionChannel =\n (typeof ATTRIBUTION_CHANNELS)[keyof typeof ATTRIBUTION_CHANNELS];\n","import type {\n AffiliateParams,\n AffiliateData,\n AffiliateConfig,\n AffiliateEvent,\n} from \"./types\";\nimport {\n ALL_AFFILIATE_PARAMETERS,\n STORAGE_CONFIG,\n ATTRIBUTION_MODELS,\n STORAGE_TYPES,\n} from \"./constants\";\n\nconst DEFAULT_CONFIG: Required<AffiliateConfig> = {\n storageKey: STORAGE_CONFIG.DEFAULT_KEY,\n storageType: STORAGE_TYPES.SESSION,\n attribution: ATTRIBUTION_MODELS.LAST_TOUCH,\n ttl: STORAGE_CONFIG.DEFAULT_TTL,\n customParams: [],\n enableReferrerCapture: true,\n enableUserAgentCapture: false,\n onCapture: () => {},\n onError: () => {},\n};\n\nlet currentConfig: Required<AffiliateConfig> = { ...DEFAULT_CONFIG };\nlet eventListeners: ((event: AffiliateEvent) => void)[] = [];\n\n/**\n * Configure the affiliate tracker\n */\nexport function configureAffiliateTracker(\n config: Partial<AffiliateConfig> = {}\n): void {\n currentConfig = { ...DEFAULT_CONFIG, ...config };\n}\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Get the appropriate storage object\n */\nfunction getStorage(): Storage | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n return currentConfig.storageType === \"localStorage\"\n ? window.localStorage\n : window.sessionStorage;\n } catch (error) {\n currentConfig.onError(new Error(`Storage not available: ${error}`));\n return null;\n }\n}\n\n/**\n * Check if stored data has expired\n */\nfunction isExpired(timestamp: number): boolean {\n return Date.now() - timestamp > currentConfig.ttl;\n}\n\n/**\n * Emit an event to all listeners\n */\nfunction emitEvent(event: AffiliateEvent): void {\n eventListeners.forEach((listener) => {\n try {\n listener(event);\n } catch (error) {\n currentConfig.onError(new Error(`Event listener error: ${error}`));\n }\n });\n}\n\n/**\n * Add an event listener\n */\nexport function addEventListener(\n listener: (event: AffiliateEvent) => void\n): () => void {\n eventListeners.push(listener);\n\n // Return unsubscribe function\n return () => {\n const index = eventListeners.indexOf(listener);\n if (index > -1) {\n eventListeners.splice(index, 1);\n }\n };\n}\n\n/**\n * Capture affiliate parameters from URL and store them\n */\nexport function captureAffiliateParams(\n customConfig?: Partial<AffiliateConfig>\n): AffiliateData | null {\n if (typeof window === \"undefined\") return null;\n\n // Temporarily override config if provided\n const originalConfig = currentConfig;\n if (customConfig) {\n currentConfig = { ...currentConfig, ...customConfig };\n }\n\n try {\n const storage = getStorage();\n if (!storage) return null;\n\n const urlParams = new URLSearchParams(window.location.search);\n const allKeys = [\n ...ALL_AFFILIATE_PARAMETERS,\n ...currentConfig.customParams,\n ];\n const affiliateParams: AffiliateParams = {};\n\n // Extract parameters from URL\n for (const key of allKeys) {\n const value = urlParams.get(key);\n if (value) {\n affiliateParams[key] = value;\n }\n }\n\n // Capture referrer if enabled and available\n if (currentConfig.enableReferrerCapture && document.referrer) {\n affiliateParams.referrer = document.referrer;\n }\n\n // Only proceed if we have affiliate data\n if (Object.keys(affiliateParams).length === 0) {\n return null;\n }\n\n // Check existing data for attribution logic\n const existingData = getAffiliateParams();\n let shouldUpdate = true;\n\n if (existingData && currentConfig.attribution === \"first-touch\") {\n // Don't update if we already have first-touch data\n shouldUpdate = false;\n }\n\n if (shouldUpdate) {\n const affiliateData: AffiliateData = {\n ...affiliateParams,\n timestamp: Date.now(),\n sessionId: generateSessionId(),\n attribution: currentConfig.attribution,\n url: window.location.href,\n ...(currentConfig.enableUserAgentCapture && {\n userAgent: navigator.userAgent,\n }),\n };\n\n storage.setItem(currentConfig.storageKey, JSON.stringify(affiliateData));\n\n // Emit capture event\n emitEvent({\n type: \"capture\",\n data: affiliateData,\n timestamp: Date.now(),\n });\n\n currentConfig.onCapture(affiliateData);\n return affiliateData;\n }\n\n return existingData;\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n return null;\n } finally {\n // Restore original config\n if (customConfig) {\n currentConfig = originalConfig;\n }\n }\n}\n\n/**\n * Get stored affiliate parameters\n */\nexport function getAffiliateParams(): AffiliateData | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n const storage = getStorage();\n if (!storage) return null;\n\n const stored = storage.getItem(currentConfig.storageKey);\n if (!stored) return null;\n\n const data: AffiliateData = JSON.parse(stored);\n\n // Check if data has expired\n if (isExpired(data.timestamp)) {\n clearAffiliateParams();\n emitEvent({\n type: \"expire\",\n data,\n timestamp: Date.now(),\n });\n return null;\n }\n\n return data;\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n return null;\n }\n}\n\n/**\n * Clear stored affiliate parameters\n */\nexport function clearAffiliateParams(): void {\n if (typeof window === \"undefined\") return;\n\n try {\n const storage = getStorage();\n if (!storage) return;\n\n const existingData = getAffiliateParams();\n storage.removeItem(currentConfig.storageKey);\n\n // Emit clear event\n emitEvent({\n type: \"clear\",\n data: existingData || undefined,\n timestamp: Date.now(),\n });\n } catch (error) {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n currentConfig.onError(errorObj);\n }\n}\n\n/**\n * Get affiliate parameters as URL search params string\n */\nexport function getAffiliateParamsAsUrlString(): string {\n const data = getAffiliateParams();\n if (!data) return \"\";\n\n const params = new URLSearchParams();\n\n // Only include the actual affiliate parameters, not metadata\n const affiliateKeys = [\n ...ALL_AFFILIATE_PARAMETERS,\n ...currentConfig.customParams,\n ];\n\n for (const key of affiliateKeys) {\n const value = data[key];\n if (typeof value === \"string\" && value) {\n params.set(key, value);\n }\n }\n\n return params.toString();\n}\n\n/**\n * Append affiliate parameters to a URL\n */\nexport function appendAffiliateParams(url: string): string {\n const affiliateParams = getAffiliateParamsAsUrlString();\n if (!affiliateParams) return url;\n\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${separator}${affiliateParams}`;\n}\n\n/**\n * Check if current session has affiliate data\n */\nexport function hasAffiliateData(): boolean {\n return getAffiliateParams() !== null;\n}\n\n/**\n * Get affiliate source (utm_source or referrer domain)\n */\nexport function getAffiliateSource(): string | null {\n const data = getAffiliateParams();\n if (!data) return null;\n\n if (data.utm_source) return data.utm_source;\n if (data.referrer) {\n try {\n return new URL(data.referrer).hostname;\n } catch {\n return data.referrer;\n }\n }\n\n return null;\n}\n\n/**\n * Get current configuration\n */\nexport function getConfig(): Required<AffiliateConfig> {\n return { ...currentConfig };\n}\n\n/**\n * Reset configuration to defaults\n */\nexport function resetConfig(): void {\n currentConfig = { ...DEFAULT_CONFIG };\n}\n\n// Export constants for external use\nexport { ALL_AFFILIATE_PARAMETERS, DEFAULT_CONFIG };\n","\"use client\";\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport type {\n AffiliateData,\n AffiliateConfig,\n AffiliateTrackerHookReturn,\n AffiliateEvent,\n} from \"./types\";\nimport {\n captureAffiliateParams,\n getAffiliateParams,\n clearAffiliateParams,\n configureAffiliateTracker,\n addEventListener,\n hasAffiliateData,\n getAffiliateSource,\n} from \"./affiliate-tracker\";\n\n/**\n * Hook for tracking affiliate parameters\n */\nexport function useAffiliateTracker(\n config?: Partial<AffiliateConfig>\n): AffiliateTrackerHookReturn {\n const [affiliateParams, setAffiliateParams] = useState<AffiliateData | null>(\n null\n );\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const configRef = useRef(config);\n\n // Update config ref when config changes\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Configure tracker on mount\n useEffect(() => {\n if (configRef.current) {\n configureAffiliateTracker({\n ...configRef.current,\n onError: (err) => {\n setError(err);\n configRef.current?.onError?.(err);\n },\n });\n }\n }, []);\n\n // Load initial data\n const refreshParams = useCallback(() => {\n setIsLoading(true);\n setError(null);\n\n try {\n const params = getAffiliateParams();\n setAffiliateParams(params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n // Capture new params\n const captureParams = useCallback(() => {\n setError(null);\n\n try {\n const params = captureAffiliateParams(configRef.current);\n setAffiliateParams(params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n }\n }, []);\n\n // Clear params\n const clearParams = useCallback(() => {\n setError(null);\n\n try {\n clearAffiliateParams();\n setAffiliateParams(null);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n }\n }, []);\n\n // Listen for events\n useEffect(() => {\n const unsubscribe = addEventListener((event: AffiliateEvent) => {\n switch (event.type) {\n case \"capture\":\n setAffiliateParams(event.data || null);\n break;\n case \"clear\":\n case \"expire\":\n setAffiliateParams(null);\n break;\n }\n });\n\n return unsubscribe;\n }, []);\n\n // Initial load\n useEffect(() => {\n refreshParams();\n }, [refreshParams]);\n\n return {\n affiliateParams,\n isLoading,\n error,\n captureParams,\n clearParams,\n refreshParams,\n };\n}\n\n/**\n * Hook for checking if affiliate data exists\n */\nexport function useHasAffiliateData(): boolean {\n const [hasData, setHasData] = useState(false);\n\n useEffect(() => {\n const checkData = () => {\n setHasData(hasAffiliateData());\n };\n\n checkData();\n\n const unsubscribe = addEventListener(() => {\n checkData();\n });\n\n return unsubscribe;\n }, []);\n\n return hasData;\n}\n\n/**\n * Hook for getting affiliate source\n */\nexport function useAffiliateSource(): string | null {\n const [source, setSource] = useState<string | null>(null);\n\n useEffect(() => {\n const updateSource = () => {\n setSource(getAffiliateSource());\n };\n\n updateSource();\n\n const unsubscribe = addEventListener(() => {\n updateSource();\n });\n\n return unsubscribe;\n }, []);\n\n return source;\n}\n\n/**\n * Hook for auto-capturing affiliate params on mount\n */\nexport function useAutoCapture(config?: Partial<AffiliateConfig>): void {\n const hasRun = useRef(false);\n\n useEffect(() => {\n if (hasRun.current) return;\n hasRun.current = true;\n\n if (config) {\n configureAffiliateTracker(config);\n }\n\n captureAffiliateParams();\n }, [config]);\n}\n\n/**\n * Hook for listening to affiliate events\n */\nexport function useAffiliateEvents(\n callback: (event: AffiliateEvent) => void,\n eventTypes?: Array<\"capture\" | \"clear\" | \"expire\">\n): void {\n const callbackRef = useRef(callback);\n const eventTypesRef = useRef(eventTypes);\n\n useEffect(() => {\n callbackRef.current = callback;\n eventTypesRef.current = eventTypes;\n });\n\n useEffect(() => {\n const unsubscribe = addEventListener((event: AffiliateEvent) => {\n if (\n !eventTypesRef.current ||\n eventTypesRef.current.includes(event.type)\n ) {\n callbackRef.current(event);\n }\n });\n\n return unsubscribe;\n }, []);\n}\n","\"use client\";\n\nimport { useShopifyCookies } from \"@shopify/hydrogen-react\";\nimport { useEffect, useState } from \"react\";\nimport { EventType, publishEvent } from \"../events\";\n\n// Safe pathname hook that works in different environments\nfunction usePathnameCompat() {\n const [pathname, setPathname] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof window !== \"undefined\") {\n setPathname(window.location.pathname);\n \n // Listen for navigation changes\n const handleLocationChange = () => {\n setPathname(window.location.pathname);\n };\n\n // Listen for popstate (back/forward navigation)\n window.addEventListener(\"popstate\", handleLocationChange);\n \n // For SPA navigation, we might need to listen to custom events\n // This is a fallback for when Next.js router is not available\n \n return () => {\n window.removeEventListener(\"popstate\", handleLocationChange);\n };\n }\n }, []);\n\n return pathname;\n}\n\n/**\n * Component to initialize Shopify Analytics cookies\n * This component handles the useShopifyCookies hook which must be used in a React component\n */\n\ninterface ShopifyAnalyticsScriptProps {\n domain: string;\n}\n\nexport function ShopifyAnalyticsScript({\n domain,\n}: ShopifyAnalyticsScriptProps) {\n const pathname = usePathnameCompat();\n\n const [sessionValid, setSessionValid] = useState(false);\n\n useShopifyCookies({\n hasUserConsent: true,\n domain: domain,\n });\n\n useEffect(() => {\n // Validate session after cookie initialization\n const validateSession = () => {\n const shopifyY = document.cookie.includes(\"_shopify_y=\");\n const shopifyS = document.cookie.includes(\"_shopify_s=\");\n\n if (shopifyY && shopifyS) {\n setSessionValid(true);\n console.log(\"✅ Shopify Analytics session validated\");\n } else {\n console.warn(\"⚠️ Shopify session cookies missing\");\n }\n };\n\n // Allow time for cookies to be set\n const timer = setTimeout(validateSession, 1000);\n return () => clearTimeout(timer);\n }, []);\n\n // Expose session status for debugging\n useEffect(() => {\n if (typeof window !== \"undefined\") {\n (window as any).__shopifySessionValid = sessionValid;\n }\n }, [sessionValid]);\n\n useEffect(() => {\n const trackPageView = () => {\n publishEvent({\n type: EventType.SHOPIFY_PAGE_VIEW,\n });\n };\n\n const timer = setTimeout(trackPageView, 1500);\n return () => clearTimeout(timer);\n }, [pathname]);\n\n return null; // This component doesn't render anything\n}\n","// Export event types\nexport * from \"../types\";\n\n// Export publisher\nexport { eventPublisher, publishEvent } from \"./publisher\";\n\n// Export subscriber\nexport { eventSubscriber } from \"./subscriber\";\nexport type { TrackingAdapter } from \"./subscriber\";\n\n// Export initialization functions\nexport { initializeEventTracking, initTracking } from \"./init\";\n"],"mappings":"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","names":["import_react","EventType","moengage","DEFAULT_CURRENCY","eventSubscriber","import_react","error","import_hydrogen_react","import_react","import_jsx_runtime","logger"]}
|