shopkit-analytics 1.2.1 → 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.
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  generateEventId,
7
7
  getBrowserInfo
8
- } from "./chunk-UFDN3A6M.mjs";
8
+ } from "./chunk-WPCXFATR.mjs";
9
9
 
10
10
  // src/logger/index.ts
11
11
  var LOG_LEVELS = {
@@ -346,10 +346,12 @@ var MultiPixelAdapter = class extends BaseAdapter {
346
346
  if (this.shouldSkipEvent(event.type)) {
347
347
  return;
348
348
  }
349
+ const timestamp = Date.now();
349
350
  const transformEvent = {
350
351
  ...event,
351
352
  eventId: event.eventId || generateEventId(event.type),
352
- timestamp: Date.now()
353
+ timestamp: event.timestamp || timestamp,
354
+ event_source_url: event.event_source_url || !(typeof window === "undefined") ? window.location.href : ""
353
355
  };
354
356
  await this.trackClientSide(transformEvent, adapterParams);
355
357
  if (this.pixels.some((pixel) => pixel.config.enableCAPI)) {
@@ -378,9 +380,12 @@ var MultiPixelAdapter = class extends BaseAdapter {
378
380
  if (!eventName) {
379
381
  return;
380
382
  }
383
+ const browserInfo = getBrowserInfo();
381
384
  try {
382
385
  window.fbq("track", eventName, enhancedParams, {
383
- eventID: event.eventId
386
+ eventID: event.eventId,
387
+ fbc: browserInfo.fbc,
388
+ fbp: browserInfo.fbp
384
389
  });
385
390
  } catch (error) {
386
391
  console.error("Facebook Pixel tracking error:", error);
@@ -430,55 +435,58 @@ var MultiPixelAdapter = class extends BaseAdapter {
430
435
  let baseParams = {};
431
436
  let eventName = "";
432
437
  switch (event.type) {
433
- case "page_view" /* PAGE_VIEW */:
438
+ case "page_view" /* PAGE_VIEW */: {
434
439
  const pageViewEvent = event;
435
440
  eventName = this.getEventName(adapterParams, "PageView");
436
441
  baseParams = {
437
- content_name: pageViewEvent.page_title || pageViewEvent.title,
438
- content_category: pageViewEvent.event_category,
439
- page_location: pageViewEvent.page_location || pageViewEvent.path,
440
- page_title: pageViewEvent.page_title || pageViewEvent.title,
441
- page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,
442
- page_path: pageViewEvent.page_path || pageViewEvent.path
442
+ event_source_url: pageViewEvent.event_source_url
443
443
  };
444
444
  break;
445
- case "view_content" /* VIEW_CONTENT */:
445
+ }
446
+ case "view_content" /* VIEW_CONTENT */: {
446
447
  const viewContentEvent = event;
447
448
  eventName = this.getEventName(adapterParams, "ViewContent");
448
449
  baseParams = {
450
+ event_source_url: viewContentEvent.event_source_url,
449
451
  content_type: viewContentEvent.content_type || "product",
450
452
  content_ids: viewContentEvent.content_ids || [],
451
- content_name: viewContentEvent.content_name || "",
452
- content_category: viewContentEvent.content_category || "",
453
+ content_name: viewContentEvent.content_name,
454
+ content_category: viewContentEvent.content_category || "product",
453
455
  value: viewContentEvent.value || 0,
454
456
  currency: viewContentEvent.currency || "INR"
455
457
  };
456
458
  break;
457
- case "add_to_cart" /* ADD_TO_CART */:
459
+ }
460
+ case "add_to_cart" /* ADD_TO_CART */: {
458
461
  const cartEvent = event;
459
462
  eventName = this.getEventName(adapterParams, "AddToCart");
460
463
  baseParams = {
461
- content_type: "product_group",
464
+ event_source_url: cartEvent.event_source_url,
465
+ content_type: cartEvent.content_type || "product",
462
466
  content_ids: [cartEvent.productId],
463
467
  content_name: cartEvent.productName,
464
468
  value: cartEvent.price,
465
469
  currency: cartEvent.currency || "INR"
466
470
  };
467
471
  break;
468
- case "search" /* SEARCH */:
472
+ }
473
+ case "search" /* SEARCH */: {
469
474
  const searchEvent = event;
470
475
  eventName = this.getEventName(adapterParams, "Search");
471
476
  baseParams = {
477
+ event_source_url: searchEvent.event_source_url,
472
478
  search_string: searchEvent.searchTerm,
473
479
  content_category: "product",
474
480
  content_ids: searchEvent.content_ids || []
475
481
  };
476
482
  break;
477
- case "initiate_checkout" /* INITIATE_CHECKOUT */:
483
+ }
484
+ case "initiate_checkout" /* INITIATE_CHECKOUT */: {
478
485
  const checkoutEvent = event;
479
486
  eventName = this.getEventName(adapterParams, "InitiateCheckout");
480
487
  baseParams = {
481
- content_type: "product",
488
+ event_source_url: checkoutEvent.event_source_url,
489
+ content_type: checkoutEvent.content_type || "product",
482
490
  currency: checkoutEvent.currency || "INR",
483
491
  value: checkoutEvent.cartValue,
484
492
  num_items: checkoutEvent.itemCount || checkoutEvent.items?.length || 0,
@@ -489,25 +497,27 @@ var MultiPixelAdapter = class extends BaseAdapter {
489
497
  })) || []
490
498
  };
491
499
  break;
492
- case "purchase" /* PURCHASE */:
500
+ }
501
+ case "purchase" /* PURCHASE */: {
493
502
  const purchaseEvent = event;
494
503
  eventName = this.getEventName(adapterParams, "Purchase");
495
504
  baseParams = {
505
+ event_source_url: purchaseEvent.event_source_url,
496
506
  content_type: purchaseEvent.content_type || "product",
497
- content_ids: purchaseEvent.content_ids || [],
507
+ contents: purchaseEvent.contents || [],
498
508
  currency: purchaseEvent.currency || "INR",
499
- value: purchaseEvent.value,
500
509
  num_items: purchaseEvent.num_items || purchaseEvent.contents?.length || 0,
501
- contents: purchaseEvent.contents || []
510
+ value: purchaseEvent.value,
511
+ order_id: purchaseEvent.order_id
502
512
  };
503
513
  break;
504
- default:
514
+ }
515
+ default: {
505
516
  this.logger.warn(`Skipping unknown event type: ${event.type}`);
506
517
  return { eventName: "", enhancedParams: {} };
518
+ }
507
519
  }
508
- const affiliateParams = this.enhanceWithAffiliateParams(baseParams);
509
- const experimentParams = this.enhanceWithExperimentParams(affiliateParams);
510
- const enhancedParams = this.mergeEventData(experimentParams, adapterParams);
520
+ const enhancedParams = this.mergeEventData(baseParams, adapterParams);
511
521
  return { eventName, enhancedParams };
512
522
  }
513
523
  /**
@@ -1474,4 +1484,4 @@ export {
1474
1484
  PostHogAdapter,
1475
1485
  ShopifyAdapter
1476
1486
  };
1477
- //# sourceMappingURL=chunk-YJE5NOFF.mjs.map
1487
+ //# sourceMappingURL=chunk-FS3XAQFM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/adapters/base-adapter.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"],"sourcesContent":["/**\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","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","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"],"mappings":"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","names":["DEFAULT_CURRENCY"]}
@@ -49,13 +49,21 @@ function getFacebookBrowserId() {
49
49
  return void 0;
50
50
  }
51
51
  function getClientIpAddress(request) {
52
- if (!request) {
53
- return void 0;
52
+ const h = request.headers;
53
+ const candidates = [
54
+ h.get("cf-connecting-ip"),
55
+ h.get("true-client-ip"),
56
+ h.get("x-vercel-forwarded-for"),
57
+ // Vercel specific
58
+ h.get("x-forwarded-for"),
59
+ h.get("x-real-ip")
60
+ ].filter(Boolean);
61
+ if (candidates.length === 0) {
62
+ return "";
54
63
  }
55
- const forwarded = request.headers.get("x-forwarded-for");
56
- const realIp = request.headers.get("x-real-ip");
57
- const cfConnectingIp = request.headers.get("cf-connecting-ip");
58
- return forwarded?.split(",")[0] || realIp || cfConnectingIp || void 0;
64
+ const first = candidates[0].split(",")[0].trim();
65
+ const ip = first.startsWith("::ffff:") ? first.replace("::ffff:", "") : first;
66
+ return ip || "";
59
67
  }
60
68
 
61
69
  export {
@@ -63,4 +71,4 @@ export {
63
71
  getBrowserInfo,
64
72
  getClientIpAddress
65
73
  };
66
- //# sourceMappingURL=chunk-UFDN3A6M.mjs.map
74
+ //# sourceMappingURL=chunk-WPCXFATR.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/event-id.ts"],"sourcesContent":["/**\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 (this will be handled server-side)\n */\nexport function getClientIpAddress(request?: Request): string | undefined {\n if (!request) {\n return undefined;\n }\n\n // Try different headers for IP address\n const forwarded = request.headers.get(\"x-forwarded-for\");\n const realIp = request.headers.get(\"x-real-ip\");\n const cfConnectingIp = request.headers.get(\"cf-connecting-ip\");\n\n return forwarded?.split(\",\")[0] || realIp || cfConnectingIp || undefined;\n}\n"],"mappings":";AAIO,SAAS,gBAAgB,WAA2B;AACzD,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AAC9D,SAAO,GAAG,SAAS,IAAI,YAAY,IAAI,SAAS;AAClD;AAKO,SAAS,iBAId;AACA,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,UAAU;AAG5B,QAAM,MAAM,mBAAmB;AAC/B,QAAM,MAAM,qBAAqB;AAEjC,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,qBAAyC;AAChD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAKA,QAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,QAAM,SAAS,UAAU,IAAI,QAAQ;AAErC,MAAI,QAAQ;AAGV,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,uBAA2C;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,mBAAmB,SAAuC;AACxE,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,QAAQ,QAAQ,IAAI,iBAAiB;AACvD,QAAM,SAAS,QAAQ,QAAQ,IAAI,WAAW;AAC9C,QAAM,iBAAiB,QAAQ,QAAQ,IAAI,kBAAkB;AAE7D,SAAO,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,UAAU,kBAAkB;AACjE;","names":[]}
1
+ {"version":3,"sources":["../src/utils/event-id.ts"],"sourcesContent":["/**\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"],"mappings":";AAIO,SAAS,gBAAgB,WAA2B;AACzD,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AAC9D,SAAO,GAAG,SAAS,IAAI,YAAY,IAAI,SAAS;AAClD;AAKO,SAAS,iBAId;AACA,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,UAAU;AAG5B,QAAM,MAAM,mBAAmB;AAC/B,QAAM,MAAM,qBAAqB;AAEjC,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,qBAAyC;AAChD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAKA,QAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,QAAM,SAAS,UAAU,IAAI,QAAQ;AAErC,MAAI,QAAQ;AAGV,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,uBAA2C;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,mBAAmB,SAA2B;AAE5D,QAAM,IAAI,QAAQ;AAElB,QAAM,aAAa;AAAA,IACjB,EAAE,IAAI,kBAAkB;AAAA,IACxB,EAAE,IAAI,gBAAgB;AAAA,IACtB,EAAE,IAAI,wBAAwB;AAAA;AAAA,IAC9B,EAAE,IAAI,iBAAiB;AAAA,IACvB,EAAE,IAAI,WAAW;AAAA,EACnB,EAAE,OAAO,OAAO;AAEhB,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,EACT;AAGA,QAAM,QAAQ,WAAW,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK;AAG/C,QAAM,KAAK,MAAM,WAAW,SAAS,IAAI,MAAM,QAAQ,WAAW,EAAE,IAAI;AAExE,SAAO,MAAM;AACf;","names":[]}
@@ -718,10 +718,12 @@ var MultiPixelAdapter = class extends BaseAdapter {
718
718
  if (this.shouldSkipEvent(event.type)) {
719
719
  return;
720
720
  }
721
+ const timestamp = Date.now();
721
722
  const transformEvent = {
722
723
  ...event,
723
724
  eventId: event.eventId || generateEventId(event.type),
724
- timestamp: Date.now()
725
+ timestamp: event.timestamp || timestamp,
726
+ event_source_url: event.event_source_url || !(typeof window === "undefined") ? window.location.href : ""
725
727
  };
726
728
  await this.trackClientSide(transformEvent, adapterParams);
727
729
  if (this.pixels.some((pixel) => pixel.config.enableCAPI)) {
@@ -750,9 +752,12 @@ var MultiPixelAdapter = class extends BaseAdapter {
750
752
  if (!eventName) {
751
753
  return;
752
754
  }
755
+ const browserInfo = getBrowserInfo();
753
756
  try {
754
757
  window.fbq("track", eventName, enhancedParams, {
755
- eventID: event.eventId
758
+ eventID: event.eventId,
759
+ fbc: browserInfo.fbc,
760
+ fbp: browserInfo.fbp
756
761
  });
757
762
  } catch (error) {
758
763
  console.error("Facebook Pixel tracking error:", error);
@@ -802,55 +807,58 @@ var MultiPixelAdapter = class extends BaseAdapter {
802
807
  let baseParams = {};
803
808
  let eventName = "";
804
809
  switch (event.type) {
805
- case "page_view" /* PAGE_VIEW */:
810
+ case "page_view" /* PAGE_VIEW */: {
806
811
  const pageViewEvent = event;
807
812
  eventName = this.getEventName(adapterParams, "PageView");
808
813
  baseParams = {
809
- content_name: pageViewEvent.page_title || pageViewEvent.title,
810
- content_category: pageViewEvent.event_category,
811
- page_location: pageViewEvent.page_location || pageViewEvent.path,
812
- page_title: pageViewEvent.page_title || pageViewEvent.title,
813
- page_referrer: pageViewEvent.page_referrer || pageViewEvent.referrer,
814
- page_path: pageViewEvent.page_path || pageViewEvent.path
814
+ event_source_url: pageViewEvent.event_source_url
815
815
  };
816
816
  break;
817
- case "view_content" /* VIEW_CONTENT */:
817
+ }
818
+ case "view_content" /* VIEW_CONTENT */: {
818
819
  const viewContentEvent = event;
819
820
  eventName = this.getEventName(adapterParams, "ViewContent");
820
821
  baseParams = {
822
+ event_source_url: viewContentEvent.event_source_url,
821
823
  content_type: viewContentEvent.content_type || "product",
822
824
  content_ids: viewContentEvent.content_ids || [],
823
- content_name: viewContentEvent.content_name || "",
824
- content_category: viewContentEvent.content_category || "",
825
+ content_name: viewContentEvent.content_name,
826
+ content_category: viewContentEvent.content_category || "product",
825
827
  value: viewContentEvent.value || 0,
826
828
  currency: viewContentEvent.currency || "INR"
827
829
  };
828
830
  break;
829
- case "add_to_cart" /* ADD_TO_CART */:
831
+ }
832
+ case "add_to_cart" /* ADD_TO_CART */: {
830
833
  const cartEvent = event;
831
834
  eventName = this.getEventName(adapterParams, "AddToCart");
832
835
  baseParams = {
833
- content_type: "product_group",
836
+ event_source_url: cartEvent.event_source_url,
837
+ content_type: cartEvent.content_type || "product",
834
838
  content_ids: [cartEvent.productId],
835
839
  content_name: cartEvent.productName,
836
840
  value: cartEvent.price,
837
841
  currency: cartEvent.currency || "INR"
838
842
  };
839
843
  break;
840
- case "search" /* SEARCH */:
844
+ }
845
+ case "search" /* SEARCH */: {
841
846
  const searchEvent = event;
842
847
  eventName = this.getEventName(adapterParams, "Search");
843
848
  baseParams = {
849
+ event_source_url: searchEvent.event_source_url,
844
850
  search_string: searchEvent.searchTerm,
845
851
  content_category: "product",
846
852
  content_ids: searchEvent.content_ids || []
847
853
  };
848
854
  break;
849
- case "initiate_checkout" /* INITIATE_CHECKOUT */:
855
+ }
856
+ case "initiate_checkout" /* INITIATE_CHECKOUT */: {
850
857
  const checkoutEvent = event;
851
858
  eventName = this.getEventName(adapterParams, "InitiateCheckout");
852
859
  baseParams = {
853
- content_type: "product",
860
+ event_source_url: checkoutEvent.event_source_url,
861
+ content_type: checkoutEvent.content_type || "product",
854
862
  currency: checkoutEvent.currency || "INR",
855
863
  value: checkoutEvent.cartValue,
856
864
  num_items: checkoutEvent.itemCount || checkoutEvent.items?.length || 0,
@@ -861,25 +869,27 @@ var MultiPixelAdapter = class extends BaseAdapter {
861
869
  })) || []
862
870
  };
863
871
  break;
864
- case "purchase" /* PURCHASE */:
872
+ }
873
+ case "purchase" /* PURCHASE */: {
865
874
  const purchaseEvent = event;
866
875
  eventName = this.getEventName(adapterParams, "Purchase");
867
876
  baseParams = {
877
+ event_source_url: purchaseEvent.event_source_url,
868
878
  content_type: purchaseEvent.content_type || "product",
869
- content_ids: purchaseEvent.content_ids || [],
879
+ contents: purchaseEvent.contents || [],
870
880
  currency: purchaseEvent.currency || "INR",
871
- value: purchaseEvent.value,
872
881
  num_items: purchaseEvent.num_items || purchaseEvent.contents?.length || 0,
873
- contents: purchaseEvent.contents || []
882
+ value: purchaseEvent.value,
883
+ order_id: purchaseEvent.order_id
874
884
  };
875
885
  break;
876
- default:
886
+ }
887
+ default: {
877
888
  this.logger.warn(`Skipping unknown event type: ${event.type}`);
878
889
  return { eventName: "", enhancedParams: {} };
890
+ }
879
891
  }
880
- const affiliateParams = this.enhanceWithAffiliateParams(baseParams);
881
- const experimentParams = this.enhanceWithExperimentParams(affiliateParams);
882
- const enhancedParams = this.mergeEventData(experimentParams, adapterParams);
892
+ const enhancedParams = this.mergeEventData(baseParams, adapterParams);
883
893
  return { eventName, enhancedParams };
884
894
  }
885
895
  /**