{"version":3,"sources":["../src/types/index.ts","../src/setup.ts","../src/push.ts","../src/adapter.ts","../src/index.ts"],"sourcesContent":["import type {\n  Mapping as WalkerOSMapping,\n  WalkerOS,\n  Destination as CoreDestination,\n  Mapping as CoreMapping,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\n// Official Snowplow types\nimport type {\n  SelfDescribingJson,\n  CommonEventProperties,\n} from '@snowplow/tracker-core';\nimport type {\n  BrowserPlugin,\n  ActivityTrackingConfiguration,\n} from '@snowplow/browser-tracker-core';\n// Action is used in a type position below (Action['type']), so it must stay\n// imported. The other entity types are only re-exported.\nimport type { Action } from '@snowplow/browser-plugin-snowplow-ecommerce';\n\n// Re-export official Snowplow entity types\nexport type { SelfDescribingJson, CommonEventProperties };\nexport type {\n  Action,\n  Product,\n  Cart,\n  SPTransaction,\n  SPPromotion,\n  CheckoutStep,\n  Refund,\n  TransactionError,\n  User,\n  Page,\n} from '@snowplow/browser-plugin-snowplow-ecommerce';\n\n// Re-export Snowplow tracker core types\nexport type { BrowserPlugin, ActivityTrackingConfiguration };\n\ndeclare global {\n  interface Window {\n    snowplow?: SnowplowFunction;\n    GlobalSnowplowNamespace?: string[];\n  }\n}\n\n// Snowplow tracker queue function type (similar to gtag or fbq)\nexport interface SnowplowFunction {\n  (...args: unknown[]): void;\n  q?: unknown[];\n}\n\n/**\n * Tracker factory function type (from @snowplow/browser-tracker)\n *\n * This is the `newTracker` function signature. When provided via `settings.code`,\n * the destination uses this directly instead of loading sp.js.\n */\nexport type TrackerFactory = (\n  trackerId: string,\n  endpoint: string,\n  configuration?: Record<string, unknown>,\n) => void;\n\n/**\n * Browser-tracker module functions passed via $code: for npm mode\n *\n * These are the individual tracking functions imported from @snowplow/browser-tracker\n * that replace the sp.js command queue approach.\n */\nexport interface TrackerFunctions {\n  /** Initialize tracker - always required */\n  newTracker: TrackerFactory;\n  /** Track self-describing events - required for event tracking */\n  trackSelfDescribingEvent: (\n    event: SelfDescribingEvent,\n    trackers?: string[],\n  ) => void;\n  /** Track page views */\n  trackPageView?: (\n    event?: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Track structured events */\n  trackStructEvent?: (\n    event: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Set user ID */\n  setUserId?: (userId?: string | null, trackers?: string[]) => void;\n  /** Enable activity tracking */\n  enableActivityTracking?: (\n    config: ActivityTrackingConfiguration,\n    trackers?: string[],\n  ) => void;\n  /** Add plugin */\n  addPlugin?: (config: { plugin: BrowserPlugin }, trackers?: string[]) => void;\n  /** Add global contexts */\n  addGlobalContexts?: (contexts: unknown[], trackers?: string[]) => void;\n  /** Clear user data */\n  clearUserData?: (\n    config?: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Enable anonymous tracking */\n  enableAnonymousTracking?: (\n    config?: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Disable anonymous tracking */\n  disableAnonymousTracking?: (\n    config?: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Consent tracking - from Enhanced Consent plugin */\n  trackConsentAllow?: (\n    params: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  trackConsentDeny?: (\n    params: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  trackConsentSelected?: (\n    params: Record<string, unknown>,\n    trackers?: string[],\n  ) => void;\n  /** Set page context - from Snowplow Ecommerce plugin */\n  setPageType?: (\n    page: { type: string; language?: string; locale?: string },\n    trackers?: string[],\n  ) => void;\n}\n\n/**\n * Unified adapter interface for Snowplow tracking\n *\n * Provides a consistent API regardless of whether using sp.js command queue\n * or @snowplow/browser-tracker module functions.\n */\nexport interface SnowplowAdapter {\n  trackPageView(event?: Record<string, unknown>): void;\n  trackSelfDescribingEvent(event: SelfDescribingEvent): void;\n  trackStructEvent(event: Record<string, unknown>): void;\n  setUserId(userId?: string | null): void;\n  enableActivityTracking(config: ActivityTrackingConfiguration): void;\n  addPlugin(\n    config: { plugin: BrowserPlugin } | [string, [string, string]],\n  ): void;\n  addGlobalContexts(contexts: unknown[]): void;\n  clearUserData(config?: Record<string, unknown>): void;\n  enableAnonymousTracking(config?: Record<string, unknown>): void;\n  disableAnonymousTracking(config?: Record<string, unknown>): void;\n  trackConsentAllow(params: Record<string, unknown>): void;\n  trackConsentDeny(params: Record<string, unknown>): void;\n  trackConsentSelected(params: Record<string, unknown>): void;\n  /** Set page context - from Snowplow Ecommerce plugin */\n  setPageType(page: { type: string; language?: string; locale?: string }): void;\n  /** For URL-based plugins that need enable methods */\n  call(method: string, ...args: unknown[]): void;\n}\n\n/**\n * Complete self-describing event structure\n * This is the full parameter passed to window.snowplow('trackSelfDescribingEvent', ...)\n */\nexport type SelfDescribingEvent<T = WalkerOS.Properties> = {\n  event: SelfDescribingJson<T>;\n} & CommonEventProperties<T>;\n\n/**\n * Page context settings for setPageType\n *\n * Each field is resolved via getMappingValue, allowing dynamic values\n * from event data or static values.\n *\n * @example\n * // Dynamic values from globals\n * page: {\n *   type: 'globals.page_type',\n *   language: 'globals.language',\n *   locale: 'globals.locale'\n * }\n *\n * // Mixed static and dynamic\n * page: {\n *   type: 'globals.page_type',\n *   language: { value: 'en' },\n *   locale: { value: 'en-US' }\n * }\n */\nexport interface PageSettings {\n  /** Page type (required) */\n  type: CoreMapping.Value;\n  /** Page language (optional) */\n  language?: CoreMapping.Value;\n  /** Page locale (optional) */\n  locale?: CoreMapping.Value;\n}\n\n/**\n * URL-based plugin configuration (for sp.js JavaScript tracker)\n */\nexport interface UrlBasedPlugin {\n  /** CDN or self-hosted URL to the plugin script */\n  url: string;\n  /** [globalName, constructorName] for the plugin */\n  name: [string, string];\n  /** Optional override for enable method (derived by convention if omitted) */\n  enableMethod?: string;\n  /** Options passed to the enable method */\n  options?: Record<string, unknown>;\n}\n\n/**\n * Code-based plugin configuration (for @snowplow/browser-tracker npm approach)\n *\n * Use when the plugin is imported via packages.imports and passed via $code:\n */\nexport interface CodeBasedPlugin {\n  /** The plugin factory function passed via $code: */\n  code: BrowserPlugin | ((...args: unknown[]) => BrowserPlugin);\n  /** Configuration options passed to the plugin factory */\n  config?: Record<string, unknown>;\n}\n\n/**\n * Union type for all supported plugin forms\n */\nexport type SnowplowPlugin = BrowserPlugin | UrlBasedPlugin | CodeBasedPlugin;\n\n/**\n * Built-in context entity types for tracker initialization\n */\nexport interface TrackerContexts {\n  /** Web page context (default: true) */\n  webPage?: boolean;\n  /** Client session context - enables client_session schema */\n  session?: boolean;\n  /** Browser context - device info, viewport, language, etc. */\n  browser?: boolean;\n  /** Performance timing context */\n  performanceTiming?: boolean;\n  /** Geolocation context */\n  geolocation?: boolean;\n}\n\n/**\n * Anonymous tracking configuration\n *\n * When enabled, the tracker will not set any user identifiers (domain_userid, network_userid).\n * This is useful for privacy-focused tracking or when user consent has not been given.\n */\nexport interface AnonymousTrackingConfig {\n  /**\n   * Request server-side anonymisation\n   *\n   * When true, the collector will anonymise the user's IP address\n   * and not set the network_userid cookie.\n   */\n  withServerAnonymisation?: boolean;\n  /**\n   * Continue session tracking in anonymous mode\n   *\n   * When true, session context will still be attached to events\n   * even when anonymous tracking is enabled.\n   */\n  withSessionTracking?: boolean;\n}\n\n/**\n * Basis for processing under GDPR\n */\nexport type BasisForProcessing =\n  | 'consent'\n  | 'contract'\n  | 'legal_obligation'\n  | 'vital_interests'\n  | 'public_task'\n  | 'legitimate_interests';\n\n/**\n * Consent tracking configuration\n *\n * Enables consent event tracking via the Snowplow Enhanced Consent plugin.\n * When configured, walkerOS consent events are translated to Snowplow\n * trackConsentAllow/Deny/Selected calls via the `on('consent')` handler.\n *\n * Requires @snowplow/browser-plugin-enhanced-consent to be loaded.\n *\n * @example\n * consent: {\n *   required: ['analytics', 'marketing'],\n *   basisForProcessing: 'consent',\n *   consentUrl: 'https://example.com/privacy',\n *   consentVersion: '2.0',\n *   domainsApplied: ['example.com'],\n *   gdprApplies: true,\n * }\n */\nexport interface ConsentConfig {\n  /**\n   * walkerOS consent groups to check\n   *\n   * If not specified, all consent groups from the event are used.\n   * Use this to filter which consent groups are relevant for Snowplow.\n   *\n   * @example ['analytics', 'marketing']\n   */\n  required?: string[];\n\n  /**\n   * Legal basis for processing under GDPR\n   *\n   * @default 'consent'\n   */\n  basisForProcessing?: BasisForProcessing;\n\n  /**\n   * URL to the privacy policy or consent document\n   */\n  consentUrl?: string;\n\n  /**\n   * Version of the consent document/policy\n   */\n  consentVersion?: string;\n\n  /**\n   * Domains where this consent applies\n   *\n   * @example ['example.com', 'shop.example.com']\n   */\n  domainsApplied?: string[];\n\n  /**\n   * Whether GDPR applies to this user/region\n   */\n  gdprApplies?: boolean;\n}\n\n/**\n * walkerOS mapping-based global context\n */\nexport interface MappedGlobalContext {\n  /** Iglu schema URI */\n  schema: string;\n  /** Data mapping using walkerOS syntax */\n  data: WalkerOSMapping.Map;\n  /** Discriminator flag */\n  __mapped: true;\n}\n\n/**\n * Static global context (same for all events)\n */\nexport interface StaticGlobalContext {\n  schema: string;\n  data: Record<string, unknown>;\n}\n\n/**\n * Dynamic global context generator function\n */\nexport type GlobalContextGenerator = () => StaticGlobalContext | null;\n\n/**\n * Union type for all global context forms\n */\nexport type GlobalContext =\n  | StaticGlobalContext\n  | GlobalContextGenerator\n  | MappedGlobalContext;\n\n/**\n * Internal runtime state for the destination\n *\n * This state is instance-scoped and managed by the destination,\n * not configured by users. It solves SSR/serverless state leakage.\n */\nexport interface RuntimeState {\n  /** JSON stringified page object for setPageType change detection */\n  page?: string;\n  /** Whether setUserId has been called for this instance */\n  userIdSet?: boolean;\n  /** The initialized adapter instance */\n  adapter?: SnowplowAdapter;\n}\n\n/**\n * Configuration settings for Snowplow destination\n */\nexport interface Settings {\n  /**\n   * Snowplow collector endpoint URL\n   *\n   * Required. The URL of your Snowplow collector.\n   *\n   * @example \"https://collector.example.com\"\n   */\n  collectorUrl?: string;\n\n  /**\n   * URL to the Snowplow JavaScript tracker script\n   *\n   * Used when `loadScript: true`. If not provided, defaults to the jsdelivr CDN\n   * with `@latest` version tag.\n   *\n   * **Security Recommendation:** Always pin to a specific version in production.\n   *\n   * @example 'https://cdn.jsdelivr.net/npm/@snowplow/javascript-tracker@3.24.0/dist/sp.js'\n   * @default 'https://cdn.jsdelivr.net/npm/@snowplow/javascript-tracker@latest/dist/sp.js'\n   */\n  scriptUrl?: string;\n\n  /**\n   * Tracker functions for bundled browser-tracker mode\n   *\n   * When provided, the destination uses these functions directly instead of\n   * loading sp.js via script tag. Use with flow.json `$code:` syntax:\n   *\n   * @example\n   * ```json\n   * {\n   *   \"packages\": {\n   *     \"@snowplow/browser-tracker\": {\n   *       \"imports\": [\"newTracker\", \"trackSelfDescribingEvent\", \"trackPageView\"]\n   *     }\n   *   },\n   *   \"settings\": {\n   *     \"tracker\": {\n   *       \"newTracker\": \"$code:newTracker\",\n   *       \"trackSelfDescribingEvent\": \"$code:trackSelfDescribingEvent\",\n   *       \"trackPageView\": \"$code:trackPageView\"\n   *     },\n   *     \"collectorUrl\": \"https://collector.example.com\"\n   *   }\n   * }\n   * ```\n   */\n  tracker?: TrackerFunctions;\n\n  /**\n   * Application ID\n   *\n   * Identifier for your application in Snowplow.\n   *\n   * @default undefined\n   */\n  appId?: string;\n\n  /**\n   * Tracker instance name\n   *\n   * Name for the tracker instance. Useful when running multiple trackers.\n   *\n   * @default \"sp\"\n   */\n  trackerName?: string;\n\n  /**\n   * Platform identifier\n   *\n   * Platform the tracker is running on.\n   *\n   * @default \"web\"\n   */\n  platform?: string;\n\n  /**\n   * Enable automatic page view tracking\n   *\n   * If true, page view events will be tracked automatically.\n   *\n   * @default false\n   */\n  pageViewTracking?: boolean;\n\n  /**\n   * Track page view on tracker initialization\n   *\n   * When true, calls `trackPageView()` immediately after tracker init.\n   * This uses Snowplow's built-in page view tracking.\n   *\n   * @default false\n   */\n  trackPageView?: boolean;\n\n  /**\n   * Event name that triggers trackPageView\n   *\n   * When a walkerOS event matches this name, `trackPageView()` is called\n   * instead of `trackSelfDescribingEvent()`.\n   *\n   * @example 'page view'\n   * @example 'pageview'\n   * @example 'screen view'\n   */\n  pageViewEvent?: string;\n\n  /**\n   * Snowplow-specific ecommerce configuration\n   */\n  snowplow?: SnowplowSettings;\n\n  /**\n   * Global page context (calls setPageType)\n   *\n   * Each field is resolved via getMappingValue. When the resolved page object\n   * changes, setPageType is called to update the global Page context.\n   *\n   * @example\n   * // Dynamic from globals\n   * page: {\n   *   type: 'globals.page_type',\n   *   language: 'globals.language'\n   * }\n   *\n   * // Static values\n   * page: {\n   *   type: { value: 'product' },\n   *   language: { value: 'en' },\n   *   locale: { value: 'en-US' }\n   * }\n   */\n  page?: PageSettings;\n\n  /**\n   * User ID for Snowplow's cross-session user stitching\n   *\n   * Called once via setUserId() on the first event where the value resolves.\n   * Subsequent events automatically include this user_id.\n   *\n   * @example\n   * // From walkerOS user object (recommended)\n   * userId: 'user.id'\n   *\n   * // From globals\n   * userId: 'globals.user_id'\n   */\n  userId?: CoreMapping.Value;\n\n  /**\n   * Discover and set the root domain for cookies\n   * @default true\n   */\n  discoverRootDomain?: boolean;\n\n  /**\n   * SameSite attribute for cookies\n   * @default undefined (browser default)\n   */\n  cookieSameSite?: 'Strict' | 'Lax' | 'None';\n\n  /**\n   * Application version string\n   */\n  appVersion?: string;\n\n  /**\n   * Built-in context entities to attach to events\n   */\n  contexts?: TrackerContexts;\n\n  /**\n   * Enable anonymous tracking\n   *\n   * When enabled, the tracker will not set user identifiers.\n   * Can be a boolean (true enables basic anonymous tracking) or\n   * a configuration object for fine-grained control.\n   *\n   * @example\n   * // Basic anonymous tracking\n   * anonymousTracking: true\n   *\n   * @example\n   * // With server-side anonymisation\n   * anonymousTracking: {\n   *   withServerAnonymisation: true,\n   *   withSessionTracking: true\n   * }\n   */\n  anonymousTracking?: boolean | AnonymousTrackingConfig;\n\n  /**\n   * Snowplow plugins to load (BrowserPlugin or URL-based)\n   */\n  plugins?: SnowplowPlugin[];\n\n  /**\n   * Activity tracking configuration (page pings)\n   */\n  activityTracking?: ActivityTrackingConfiguration;\n\n  /**\n   * Global context entities attached to all events\n   */\n  globalContexts?: GlobalContext[];\n\n  /**\n   * Consent tracking configuration\n   *\n   * When configured, enables consent event tracking via the `on('consent')` handler.\n   * Requires @snowplow/browser-plugin-enhanced-consent to be loaded.\n   *\n   * @example\n   * consent: {\n   *   required: ['analytics', 'marketing'],\n   *   basisForProcessing: 'consent',\n   *   consentUrl: 'https://example.com/privacy',\n   *   consentVersion: '2.0',\n   * }\n   */\n  consent?: ConsentConfig;\n\n  /**\n   * Internal runtime state (managed by destination, not user-configured)\n   * @internal\n   */\n  _state?: RuntimeState;\n}\n\n/**\n * Snowplow-specific settings (similar to GA4Settings in gtag)\n */\nexport interface SnowplowSettings {\n  /**\n   * Ecommerce action schema URI\n   *\n   * Schema used for all ecommerce action events.\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2\"\n   */\n  actionSchema?: string;\n\n  /**\n   * Product entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0\"\n   */\n  productSchema?: string;\n\n  /**\n   * Cart entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/cart/jsonschema/1-0-0\"\n   */\n  cartSchema?: string;\n\n  /**\n   * Transaction entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/transaction/jsonschema/1-0-0\"\n   */\n  transactionSchema?: string;\n\n  /**\n   * Refund entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/refund/jsonschema/1-0-0\"\n   */\n  refundSchema?: string;\n\n  /**\n   * Checkout step entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/checkout_step/jsonschema/1-0-0\"\n   */\n  checkoutStepSchema?: string;\n\n  /**\n   * Promotion entity schema URI\n   *\n   * @default \"iglu:com.snowplowanalytics.snowplow.ecommerce/promotion/jsonschema/1-0-0\"\n   */\n  promotionSchema?: string;\n\n  /**\n   * User entity schema URI (optional)\n   *\n   * @example \"iglu:com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-0\"\n   */\n  userSchema?: string;\n\n  /**\n   * Custom entity schemas\n   *\n   * Define schemas for custom context entities.\n   *\n   * @example { custom_entity: \"iglu:com.example/custom/jsonschema/1-0-0\" }\n   */\n  customSchemas?: {\n    [entityType: string]: string;\n  };\n\n  /**\n   * Default currency code (ISO 4217)\n   *\n   * Used as fallback when currency is not specified in event data.\n   *\n   * @example \"USD\", \"EUR\", \"GBP\"\n   * @default \"USD\"\n   */\n  currency?: string;\n\n  /**\n   * Data mapping at destination level\n   *\n   * Global data transformation applied to all events.\n   */\n  data?: WalkerOSMapping.Value | WalkerOSMapping.Values;\n}\n\n/**\n * Context entity definition for Snowplow\n *\n * Each context entity has a schema URI and data mapping.\n */\nexport interface ContextEntity {\n  /**\n   * Iglu schema URI for this context entity\n   *\n   * @example SCHEMAS.PRODUCT, SCHEMAS.TRANSACTION\n   */\n  schema: string;\n\n  /**\n   * Data mapping for this context entity\n   *\n   * Uses standard walkerOS mapping syntax.\n   *\n   * @example { id: 'data.id', name: 'data.name', price: 'data.price' }\n   */\n  data: WalkerOSMapping.Map;\n}\n\n/**\n * Structured event mapping for Snowplow's trackStructEvent\n *\n * When configured, bypasses self-describing events entirely\n * and calls trackStructEvent with the resolved values.\n *\n * @example\n * struct: {\n *   category: { value: 'ui' },\n *   action: { value: 'click' },\n *   label: 'data.button_name',\n *   property: 'data.section',\n *   value: 'data.position',\n * }\n */\nexport interface StructuredEventMapping {\n  /** Event category (required) */\n  category: CoreMapping.Value;\n  /** Event action (required) */\n  action: CoreMapping.Value;\n  /** Event label (optional) */\n  label?: CoreMapping.Value;\n  /** Event property (optional) */\n  property?: CoreMapping.Value;\n  /** Event value - must resolve to a number (optional) */\n  value?: CoreMapping.Value;\n}\n\n/**\n * Custom mapping parameters for Snowplow events\n *\n * Uses standard `name` field for action type.\n * The `name` from the mapping rule becomes Snowplow's event.data.type.\n */\nexport interface Mapping {\n  /**\n   * Context entities to attach to this event\n   *\n   * Each entry defines a schema and data mapping.\n   * Explicit - no auto-detection.\n   *\n   * @example\n   * context: [\n   *   { schema: SCHEMAS.PRODUCT, data: { id: 'data.id', name: 'data.name' } }\n   * ]\n   */\n  context?: ContextEntity[];\n\n  /**\n   * Snowplow-specific settings override\n   */\n  snowplow?: SnowplowMappingSettings;\n\n  /**\n   * Custom data mapping for self-describing event payload\n   *\n   * When specified with a `map` property, the mapped values are used\n   * as the event data instead of the default ecommerce pattern.\n   * Useful for media events (percent_progress) and custom schemas.\n   *\n   * @example\n   * data: { map: { percentProgress: 'data.progress' } }\n   */\n  data?: WalkerOSMapping.Value;\n\n  /**\n   * Structured event mapping (bypasses self-describing events)\n   *\n   * When configured, calls trackStructEvent instead of trackSelfDescribingEvent.\n   * No schema is used - this completely bypasses the self-describing event path.\n   *\n   * @example\n   * struct: {\n   *   category: { value: 'ui' },\n   *   action: { value: 'click' },\n   *   label: 'data.button_name',\n   * }\n   */\n  struct?: StructuredEventMapping;\n}\n\n/**\n * Per-event Snowplow settings override\n */\nexport interface SnowplowMappingSettings {\n  /**\n   * Override action schema for this specific event\n   */\n  actionSchema?: string;\n}\n\n/**\n * Environment dependencies for Snowplow destination\n */\nexport interface Env extends DestinationWeb.Env {\n  window: {\n    snowplow?: SnowplowFunction;\n  };\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\nexport type Param = WalkerOSMapping.Value;\n\n/**\n * Snowplow Ecommerce Schema URIs\n * Based on Snowplow Analytics official ecommerce schema\n */\nexport const SCHEMAS = {\n  ACTION:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n  PRODUCT:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n  CART: 'iglu:com.snowplowanalytics.snowplow.ecommerce/cart/jsonschema/1-0-0',\n  TRANSACTION:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/transaction/jsonschema/1-0-0',\n  REFUND:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/refund/jsonschema/1-0-0',\n  CHECKOUT_STEP:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/checkout_step/jsonschema/1-0-0',\n  PROMOTION:\n    'iglu:com.snowplowanalytics.snowplow.ecommerce/promotion/jsonschema/1-0-0',\n  PAGE: 'iglu:com.snowplowanalytics.snowplow.ecommerce/page/jsonschema/1-0-0',\n  USER: 'iglu:com.snowplowanalytics.snowplow.ecommerce/user/jsonschema/1-0-0',\n} as const;\n\n/**\n * Snowplow ecommerce action types\n * Type-safe values matching official Action['type']\n */\nexport const ACTIONS = {\n  PRODUCT_VIEW: 'product_view',\n  LIST_VIEW: 'list_view',\n  LIST_CLICK: 'list_click',\n  ADD_TO_CART: 'add_to_cart',\n  REMOVE_FROM_CART: 'remove_from_cart',\n  CHECKOUT_STEP: 'checkout_step',\n  TRANSACTION: 'transaction',\n  REFUND: 'refund',\n  PROMO_VIEW: 'promo_view',\n  PROMO_CLICK: 'promo_click',\n  TRANSACTION_ERROR: 'trns_error',\n} as const satisfies Record<string, Action['type']>;\n\n/**\n * Snowplow Web Schema URIs\n * Events and contexts for web analytics tracking\n */\nexport const WEB_SCHEMAS = {\n  // Events\n  LINK_CLICK: 'iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1',\n  CHANGE_FORM:\n    'iglu:com.snowplowanalytics.snowplow/change_form/jsonschema/1-0-0',\n  FOCUS_FORM: 'iglu:com.snowplowanalytics.snowplow/focus_form/jsonschema/1-0-0',\n  SUBMIT_FORM:\n    'iglu:com.snowplowanalytics.snowplow/submit_form/jsonschema/1-0-0',\n  SITE_SEARCH:\n    'iglu:com.snowplowanalytics.snowplow/site_search/jsonschema/1-0-0',\n  SOCIAL:\n    'iglu:com.snowplowanalytics.snowplow/social_interaction/jsonschema/1-0-0',\n  TIMING: 'iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0',\n  WEB_VITALS: 'iglu:com.snowplowanalytics.snowplow/web_vitals/jsonschema/1-0-0',\n  // Contexts\n  WEB_PAGE: 'iglu:com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0',\n  BROWSER:\n    'iglu:com.snowplowanalytics.snowplow/browser_context/jsonschema/2-0-0',\n  CLIENT_SESSION:\n    'iglu:com.snowplowanalytics.snowplow/client_session/jsonschema/1-0-2',\n  GEOLOCATION:\n    'iglu:com.snowplowanalytics.snowplow/geolocation_context/jsonschema/1-1-0',\n} as const;\n\n/**\n * Snowplow Consent Schema URIs\n * For Enhanced Consent plugin events and contexts\n */\nexport const CONSENT_SCHEMAS = {\n  // Events (fired by Enhanced Consent plugin)\n  PREFERENCES:\n    'iglu:com.snowplowanalytics.snowplow/consent_preferences/jsonschema/1-0-0',\n  CMP_VISIBLE:\n    'iglu:com.snowplowanalytics.snowplow/cmp_visible/jsonschema/1-0-0',\n  // Contexts\n  DOCUMENT:\n    'iglu:com.snowplowanalytics.snowplow/consent_document/jsonschema/1-0-0',\n  GDPR: 'iglu:com.snowplowanalytics.snowplow/gdpr/jsonschema/1-0-0',\n} as const;\n\n/**\n * Snowplow Media Schema URIs\n * Events and contexts for media (video/audio) tracking\n *\n * Requires @snowplow/browser-plugin-media-tracking for automatic tracking\n * or can be used manually with trackSelfDescribingEvent\n *\n * @see https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/web-tracker/tracking-events/media/\n */\nexport const MEDIA_SCHEMAS = {\n  // Core playback events\n  PLAY: 'iglu:com.snowplowanalytics.snowplow.media/play_event/jsonschema/1-0-0',\n  PAUSE:\n    'iglu:com.snowplowanalytics.snowplow.media/pause_event/jsonschema/1-0-0',\n  END: 'iglu:com.snowplowanalytics.snowplow.media/end_event/jsonschema/1-0-0',\n  READY:\n    'iglu:com.snowplowanalytics.snowplow.media/ready_event/jsonschema/1-0-0',\n\n  // Seek events\n  SEEK_START:\n    'iglu:com.snowplowanalytics.snowplow.media/seek_start_event/jsonschema/1-0-0',\n  SEEK_END:\n    'iglu:com.snowplowanalytics.snowplow.media/seek_end_event/jsonschema/1-0-0',\n\n  // Buffer events\n  BUFFER_START:\n    'iglu:com.snowplowanalytics.snowplow.media/buffer_start_event/jsonschema/1-0-0',\n  BUFFER_END:\n    'iglu:com.snowplowanalytics.snowplow.media/buffer_end_event/jsonschema/1-0-0',\n\n  // Player state change events\n  QUALITY_CHANGE:\n    'iglu:com.snowplowanalytics.snowplow.media/quality_change_event/jsonschema/1-0-0',\n  FULLSCREEN_CHANGE:\n    'iglu:com.snowplowanalytics.snowplow.media/fullscreen_change_event/jsonschema/1-0-0',\n  VOLUME_CHANGE:\n    'iglu:com.snowplowanalytics.snowplow.media/volume_change_event/jsonschema/1-0-0',\n  PLAYBACK_RATE_CHANGE:\n    'iglu:com.snowplowanalytics.snowplow.media/playback_rate_change_event/jsonschema/1-0-0',\n  PIP_CHANGE:\n    'iglu:com.snowplowanalytics.snowplow.media/picture_in_picture_change_event/jsonschema/1-0-0',\n\n  // Progress events\n  PING: 'iglu:com.snowplowanalytics.snowplow.media/ping_event/jsonschema/1-0-0',\n  PERCENT_PROGRESS:\n    'iglu:com.snowplowanalytics.snowplow.media/percent_progress_event/jsonschema/1-0-0',\n\n  // Error event\n  ERROR:\n    'iglu:com.snowplowanalytics.snowplow.media/error_event/jsonschema/1-0-0',\n\n  // Ad events\n  AD_BREAK_START:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_break_start_event/jsonschema/1-0-0',\n  AD_BREAK_END:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_break_end_event/jsonschema/1-0-0',\n  AD_START:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_start_event/jsonschema/1-0-0',\n  AD_COMPLETE:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_complete_event/jsonschema/1-0-0',\n  AD_SKIP:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_skip_event/jsonschema/1-0-0',\n  AD_CLICK:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_click_event/jsonschema/1-0-0',\n  AD_PAUSE:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_pause_event/jsonschema/1-0-0',\n  AD_RESUME:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_resume_event/jsonschema/1-0-0',\n  AD_QUARTILE:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_quartile_event/jsonschema/1-0-0',\n\n  // Contexts (attached to media events)\n  MEDIA_PLAYER:\n    'iglu:com.snowplowanalytics.snowplow/media_player/jsonschema/1-0-0',\n  SESSION: 'iglu:com.snowplowanalytics.snowplow.media/session/jsonschema/1-0-0',\n  AD: 'iglu:com.snowplowanalytics.snowplow.media/ad/jsonschema/1-0-0',\n  AD_BREAK:\n    'iglu:com.snowplowanalytics.snowplow.media/ad_break/jsonschema/1-0-0',\n} as const;\n\n/**\n * Media action types for event mapping\n * Use with mapping.name to specify the action type\n */\nexport const MEDIA_ACTIONS = {\n  PLAY: 'play',\n  PAUSE: 'pause',\n  END: 'end',\n  READY: 'ready',\n  SEEK_START: 'seek_start',\n  SEEK_END: 'seek_end',\n  BUFFER_START: 'buffer_start',\n  BUFFER_END: 'buffer_end',\n  QUALITY_CHANGE: 'quality_change',\n  FULLSCREEN_CHANGE: 'fullscreen_change',\n  VOLUME_CHANGE: 'volume_change',\n  PLAYBACK_RATE_CHANGE: 'playback_rate_change',\n  PIP_CHANGE: 'pip_change',\n  PING: 'ping',\n  PERCENT_PROGRESS: 'percent_progress',\n  ERROR: 'error',\n  AD_BREAK_START: 'ad_break_start',\n  AD_BREAK_END: 'ad_break_end',\n  AD_START: 'ad_start',\n  AD_COMPLETE: 'ad_complete',\n  AD_SKIP: 'ad_skip',\n  AD_CLICK: 'ad_click',\n  AD_PAUSE: 'ad_pause',\n  AD_RESUME: 'ad_resume',\n  AD_QUARTILE: 'ad_quartile',\n} as const;\n\n/**\n * Type guard for URL-based plugins\n */\nexport function isUrlBasedPlugin(\n  plugin: SnowplowPlugin,\n): plugin is UrlBasedPlugin {\n  return typeof plugin === 'object' && 'url' in plugin && 'name' in plugin;\n}\n\n/**\n * Type guard for code-based plugins\n */\nexport function isCodeBasedPlugin(\n  plugin: SnowplowPlugin,\n): plugin is CodeBasedPlugin {\n  return typeof plugin === 'object' && 'code' in plugin && !('url' in plugin);\n}\n\n/**\n * Type guard for mapped global contexts\n */\nexport function isMappedGlobalContext(\n  ctx: GlobalContext,\n): ctx is MappedGlobalContext {\n  return typeof ctx === 'object' && ctx !== null && '__mapped' in ctx;\n}\n\n/**\n * Derive enable method from plugin constructor name\n * 'LinkClickTrackingPlugin' -> 'enableLinkClickTracking'\n */\nexport function deriveEnableMethod(constructorName: string): string {\n  return 'enable' + constructorName.replace('Plugin', '');\n}\n","import type { Env, SnowplowFunction } from './types';\nimport { getEnv } from '@walkeros/web-core';\n\n/**\n * Default Snowplow tracker script URL\n *\n * WARNING: Using @latest in production is not recommended.\n * Always pin to a specific version for production deployments.\n */\nexport const DEFAULT_SCRIPT_URL =\n  'https://cdn.jsdelivr.net/npm/@snowplow/javascript-tracker@latest/dist/sp.js';\n\nconst loadedScripts = new Set<string>();\n\n// For testing: allow resetting loaded scripts\nexport function resetLoadedScripts(): void {\n  loadedScripts.clear();\n}\n\nexport function addScript(\n  collectorUrl: string,\n  env?: Env,\n  src = DEFAULT_SCRIPT_URL,\n): void {\n  // Prevent loading the same script multiple times\n  if (loadedScripts.has(collectorUrl)) return;\n\n  const { document } = getEnv<Env>(env);\n  const script = document.createElement('script');\n  script.src = src;\n  script.async = true;\n  document.head.appendChild(script);\n  loadedScripts.add(collectorUrl);\n}\n\nexport function setup(env?: Env): SnowplowFunction | undefined {\n  const { window } = getEnv<Env>(env);\n\n  // Setup snowplow function if not exists\n  if (!window.snowplow) {\n    const sp: SnowplowFunction = function (...args: unknown[]): void {\n      (sp.q = sp.q || []).push(args);\n    };\n\n    sp.q = [];\n    window.snowplow = sp;\n    window.GlobalSnowplowNamespace = ['snowplow'];\n  }\n\n  return window.snowplow;\n}\n","import type {\n  Collector,\n  WalkerOS,\n  Logger,\n  Mapping as MappingTypes,\n} from '@walkeros/core';\nimport type {\n  SnowplowAdapter,\n  SelfDescribingJson,\n  Mapping,\n  StructuredEventMapping,\n  Config,\n} from './types';\nimport {\n  isObject,\n  isArray,\n  getMappingValue,\n  isString,\n  isNumber,\n} from '@walkeros/core';\nimport { SCHEMAS } from './types';\n\n/**\n * Check if context data definition contains a loop\n *\n * Loop format: { loop: [scope, itemMapping] }\n */\nfunction isLoopContextData(\n  data: unknown,\n): data is { loop: [unknown, unknown] } {\n  return (\n    isObject(data) &&\n    'loop' in data &&\n    isArray(data.loop) &&\n    data.loop.length === 2\n  );\n}\n\n/**\n * Push event to Snowplow\n *\n * Processes mapping.context to build Snowplow context entities.\n * Each context entry has a schema and data mapping that is applied to the event.\n *\n * @param actionName - Action type from rule.name (e.g., ACTIONS.ADD_TO_CART)\n */\nexport async function pushSnowplowEvent(\n  event: WalkerOS.Event,\n  mapping: Mapping,\n  data: WalkerOS.AnyObject,\n  actionName?: string,\n  config?: Config,\n  logger?: Logger.Instance,\n  collector?: Collector.Instance,\n): Promise<void> {\n  const settings = config?.settings;\n  const adapter = settings?._state?.adapter;\n\n  if (!adapter) {\n    logger?.throw('Tracker not initialized');\n    return;\n  }\n  const runtimeState = settings?._state;\n\n  // Set userId once on first event where value is available\n  if (settings?.userId && !runtimeState?.userIdSet) {\n    const userId = await getMappingValue(event, settings.userId, { collector });\n    if (userId && isString(userId)) {\n      adapter.setUserId(userId);\n      if (runtimeState) runtimeState.userIdSet = true;\n    }\n  }\n\n  // Set page context when configured (calls setPageType from ecommerce plugin)\n  if (settings?.page) {\n    const pageType = await getMappingValue(event, settings.page.type, {\n      collector,\n    });\n    if (pageType && isString(pageType)) {\n      const page: { type: string; language?: string; locale?: string } = {\n        type: pageType,\n      };\n\n      // Add optional language if configured and resolves to string\n      if (settings.page.language) {\n        const language = await getMappingValue(event, settings.page.language, {\n          collector,\n        });\n        if (language && isString(language)) {\n          page.language = language;\n        }\n      }\n\n      // Add optional locale if configured and resolves to string\n      if (settings.page.locale) {\n        const locale = await getMappingValue(event, settings.page.locale, {\n          collector,\n        });\n        if (locale && isString(locale)) {\n          page.locale = locale;\n        }\n      }\n\n      // Only call setPageType if page changed (dedupe based on JSON string)\n      const pageJson = JSON.stringify(page);\n      if (runtimeState?.page !== pageJson) {\n        adapter.setPageType(page);\n        if (runtimeState) runtimeState.page = pageJson;\n      }\n    }\n  }\n\n  // Handle structured events (bypasses self-describing events)\n  if (mapping.struct) {\n    await handleStructuredEvent(\n      event,\n      mapping.struct,\n      adapter,\n      logger,\n      collector,\n    );\n    return;\n  }\n\n  // Handle page view events (only when explicitly configured)\n  if (settings?.pageViewEvent && event.name === settings.pageViewEvent) {\n    adapter.trackPageView();\n    return;\n  }\n\n  // Handle self-describing events\n  if (actionName) {\n    const actionSchema =\n      mapping.snowplow?.actionSchema ||\n      settings?.snowplow?.actionSchema ||\n      SCHEMAS.ACTION;\n\n    const context = await buildContext(event, mapping, collector);\n\n    // Build event data based on schema type\n    let eventData: WalkerOS.AnyObject = {};\n\n    if (isObject(mapping.data) && 'map' in mapping.data) {\n      // Use mapped data for self-describing events (e.g., percent_progress)\n      const mapped = await getMappingValue(event, mapping.data, { collector });\n      if (isObject(mapped)) eventData = mapped as WalkerOS.AnyObject;\n    } else if (actionSchema === SCHEMAS.ACTION) {\n      // Ecommerce pattern: include type field\n      eventData = { type: actionName };\n    }\n    // else: empty data {} for marker events (media play/pause/etc.)\n\n    adapter.trackSelfDescribingEvent({\n      event: { schema: actionSchema, data: eventData as WalkerOS.Properties },\n      context: context.length > 0 ? context : undefined,\n    });\n  } else {\n    logger?.info('Event skipped: no action name in mapping', {\n      event: event.name,\n      hasContext: !!mapping.context?.length,\n    });\n  }\n}\n\n/**\n * Build Snowplow context array from mapping.context definitions\n *\n * Applies data mappings to each context entity.\n * Supports loop expansion: when contextDef.data contains a loop definition,\n * creates multiple context entities (one per array item).\n */\nasync function buildContext(\n  event: WalkerOS.Event,\n  mapping: Mapping,\n  collector?: Collector.Instance,\n): Promise<SelfDescribingJson<WalkerOS.Properties>[]> {\n  const contexts: SelfDescribingJson<WalkerOS.Properties>[] = [];\n\n  if (!isArray(mapping.context)) {\n    return contexts;\n  }\n\n  for (const contextDef of mapping.context) {\n    if (!isObject(contextDef) || !contextDef.schema) {\n      continue;\n    }\n\n    // Check if this is a loop expansion\n    if (isLoopContextData(contextDef.data)) {\n      const [scope, itemMapping] = contextDef.data.loop;\n\n      // Get the source array using getMappingValue with the scope\n      const sourceArray = await getMappingValue(event, scope as string, {\n        collector,\n      });\n\n      if (isArray(sourceArray)) {\n        // Apply the item mapping to each element and create a context entity for each\n        for (const item of sourceArray) {\n          const mappedData = await getMappingValue(\n            item,\n            itemMapping as MappingTypes.Data,\n            { collector },\n          );\n\n          if (isObject(mappedData)) {\n            contexts.push({\n              schema: contextDef.schema,\n              data: mappedData as WalkerOS.Properties,\n            });\n          }\n        }\n      }\n    } else {\n      // Original behavior: single context entity\n      const mappedData = await getMappingValue(\n        event,\n        { map: contextDef.data },\n        { collector },\n      );\n\n      if (isObject(mappedData)) {\n        contexts.push({\n          schema: contextDef.schema,\n          data: mappedData as WalkerOS.Properties,\n        });\n      }\n    }\n  }\n\n  return contexts;\n}\n\n/**\n * Handle structured events via trackStructEvent\n *\n * Bypasses self-describing events entirely. Resolves mapping values\n * and calls Snowplow's trackStructEvent with category, action, label,\n * property, and value.\n */\nasync function handleStructuredEvent(\n  event: WalkerOS.Event,\n  struct: StructuredEventMapping,\n  adapter: SnowplowAdapter,\n  logger?: Logger.Instance,\n  collector?: Collector.Instance,\n): Promise<void> {\n  // Resolve required fields\n  const category = await getMappingValue(event, struct.category, { collector });\n  const action = await getMappingValue(event, struct.action, { collector });\n\n  // Category and action are required - skip with warning if not present\n  if (!category || !isString(category)) {\n    logger?.info('Struct event skipped: invalid category', {\n      event: event.name,\n      category,\n      reason: !category ? 'missing' : 'not a string',\n    });\n    return;\n  }\n  if (!action || !isString(action)) {\n    logger?.info('Struct event skipped: invalid action', {\n      event: event.name,\n      action,\n      reason: !action ? 'missing' : 'not a string',\n    });\n    return;\n  }\n\n  // Resolve optional fields\n  const label = struct.label\n    ? await getMappingValue(event, struct.label, { collector })\n    : undefined;\n  const property = struct.property\n    ? await getMappingValue(event, struct.property, { collector })\n    : undefined;\n  const rawValue = struct.value\n    ? await getMappingValue(event, struct.value, { collector })\n    : undefined;\n\n  // Convert value to number if present\n  const value = rawValue !== undefined ? Number(rawValue) : undefined;\n\n  adapter.trackStructEvent({\n    category,\n    action,\n    ...(label && isString(label) && { label }),\n    ...(property && isString(property) && { property }),\n    ...(value !== undefined && isNumber(value) && !isNaN(value) && { value }),\n  });\n}\n","import type {\n  SnowplowAdapter,\n  SnowplowFunction,\n  TrackerFunctions,\n  SelfDescribingEvent,\n} from './types';\nimport type {\n  ActivityTrackingConfiguration,\n  BrowserPlugin,\n} from '@snowplow/browser-tracker-core';\n\n/**\n * Create adapter from sp.js command queue (window.snowplow)\n *\n * Wraps the command queue pattern to match SnowplowAdapter interface.\n */\nexport function createQueueAdapter(\n  snowplow: SnowplowFunction,\n): SnowplowAdapter {\n  return {\n    trackPageView(event?: Record<string, unknown>) {\n      if (event) {\n        snowplow('trackPageView', event);\n      } else {\n        snowplow('trackPageView');\n      }\n    },\n    trackSelfDescribingEvent(event: SelfDescribingEvent) {\n      snowplow('trackSelfDescribingEvent', event);\n    },\n    trackStructEvent(event: Record<string, unknown>) {\n      snowplow('trackStructEvent', event);\n    },\n    setUserId(userId?: string | null) {\n      snowplow('setUserId', userId);\n    },\n    enableActivityTracking(config: ActivityTrackingConfiguration) {\n      snowplow('enableActivityTracking', config);\n    },\n    addPlugin(config: { plugin: BrowserPlugin } | [string, [string, string]]) {\n      if (Array.isArray(config)) {\n        // URL-based plugin: [url, [namespace, constructor]]\n        snowplow('addPlugin', config[0], config[1]);\n      } else {\n        // Code-based plugin: { plugin: BrowserPlugin }\n        snowplow('addPlugin', config);\n      }\n    },\n    addGlobalContexts(contexts: unknown[]) {\n      snowplow('addGlobalContexts', contexts);\n    },\n    clearUserData(config?: Record<string, unknown>) {\n      if (config) {\n        snowplow('clearUserData', config);\n      } else {\n        snowplow('clearUserData');\n      }\n    },\n    enableAnonymousTracking(config?: Record<string, unknown>) {\n      if (config) {\n        snowplow('enableAnonymousTracking', config);\n      } else {\n        snowplow('enableAnonymousTracking');\n      }\n    },\n    disableAnonymousTracking(config?: Record<string, unknown>) {\n      if (config) {\n        snowplow('disableAnonymousTracking', config);\n      } else {\n        snowplow('disableAnonymousTracking');\n      }\n    },\n    trackConsentAllow(params: Record<string, unknown>) {\n      snowplow('trackConsentAllow', params);\n    },\n    trackConsentDeny(params: Record<string, unknown>) {\n      snowplow('trackConsentDeny', params);\n    },\n    trackConsentSelected(params: Record<string, unknown>) {\n      snowplow('trackConsentSelected', params);\n    },\n    setPageType(page: { type: string; language?: string; locale?: string }) {\n      snowplow('setPageType', page);\n    },\n    call(method: string, ...args: unknown[]) {\n      snowplow(method, ...args);\n    },\n  };\n}\n\n/**\n * Create adapter from browser-tracker module functions\n *\n * Wraps individual imported functions to match SnowplowAdapter interface.\n * Functions are passed via settings.tracker with $code: references.\n */\nexport function createBrowserTrackerAdapter(\n  functions: TrackerFunctions,\n): SnowplowAdapter {\n  return {\n    trackPageView(event?: Record<string, unknown>) {\n      if (functions.trackPageView) {\n        functions.trackPageView(event);\n      }\n    },\n    trackSelfDescribingEvent(event: SelfDescribingEvent) {\n      functions.trackSelfDescribingEvent(event);\n    },\n    trackStructEvent(event: Record<string, unknown>) {\n      if (functions.trackStructEvent) {\n        functions.trackStructEvent(event);\n      }\n    },\n    setUserId(userId?: string | null) {\n      if (functions.setUserId) {\n        functions.setUserId(userId);\n      }\n    },\n    enableActivityTracking(config: ActivityTrackingConfiguration) {\n      if (functions.enableActivityTracking) {\n        functions.enableActivityTracking(config);\n      }\n    },\n    addPlugin(config: { plugin: BrowserPlugin } | [string, [string, string]]) {\n      if (functions.addPlugin && !Array.isArray(config)) {\n        functions.addPlugin(config);\n      }\n      // URL-based plugins not supported in browser-tracker mode\n    },\n    addGlobalContexts(contexts: unknown[]) {\n      if (functions.addGlobalContexts) {\n        functions.addGlobalContexts(contexts);\n      }\n    },\n    clearUserData(config?: Record<string, unknown>) {\n      if (functions.clearUserData) {\n        functions.clearUserData(config);\n      }\n    },\n    enableAnonymousTracking(config?: Record<string, unknown>) {\n      if (functions.enableAnonymousTracking) {\n        functions.enableAnonymousTracking(config);\n      }\n    },\n    disableAnonymousTracking(config?: Record<string, unknown>) {\n      if (functions.disableAnonymousTracking) {\n        functions.disableAnonymousTracking(config);\n      }\n    },\n    trackConsentAllow(params: Record<string, unknown>) {\n      if (functions.trackConsentAllow) {\n        functions.trackConsentAllow(params);\n      }\n    },\n    trackConsentDeny(params: Record<string, unknown>) {\n      if (functions.trackConsentDeny) {\n        functions.trackConsentDeny(params);\n      }\n    },\n    trackConsentSelected(params: Record<string, unknown>) {\n      if (functions.trackConsentSelected) {\n        functions.trackConsentSelected(params);\n      }\n    },\n    setPageType(page: { type: string; language?: string; locale?: string }) {\n      if (functions.setPageType) {\n        functions.setPageType(page);\n      }\n    },\n    call(method: string, ...args: unknown[]) {\n      // In browser-tracker mode, arbitrary method calls are not supported\n      // URL-based plugins that need enable methods won't work here\n    },\n  };\n}\n","import type { WalkerOS, Logger } from '@walkeros/core';\nimport type {\n  Settings,\n  Destination,\n  Mapping,\n  Env,\n  RuntimeState,\n  SnowplowAdapter,\n} from './types';\nimport type { BrowserPlugin } from '@snowplow/browser-tracker-core';\nimport {\n  isUrlBasedPlugin,\n  isCodeBasedPlugin,\n  deriveEnableMethod,\n} from './types';\nimport { addScript, setup } from './setup';\nimport { pushSnowplowEvent } from './push';\nimport { createQueueAdapter, createBrowserTrackerAdapter } from './adapter';\nimport { isObject } from '@walkeros/core';\n\n// Types\nexport * as DestinationSnowplow from './types';\n\n// Schema constants for user convenience\nexport {\n  SCHEMAS,\n  ACTIONS,\n  WEB_SCHEMAS,\n  CONSENT_SCHEMAS,\n  MEDIA_SCHEMAS,\n  MEDIA_ACTIONS,\n} from './types';\n\n/**\n * Get the Snowplow function from the environment\n *\n * @param env - Optional environment override\n * @returns The Snowplow function or undefined if not available\n */\nfunction getSnowplow(env?: Env) {\n  return (\n    env?.window?.snowplow ??\n    (typeof window !== 'undefined' ? window.snowplow : undefined)\n  );\n}\n\n/**\n * Clear all user data (cookies and local storage)\n *\n * Call this when a user withdraws consent or logs out to remove\n * all Snowplow identifiers (domain_userid, session cookies, etc.).\n *\n * @param env - Optional environment override for testing\n *\n * @example\n * ```typescript\n * import { clearUserData } from '@walkeros/web-destination-snowplow';\n *\n * // When user withdraws consent\n * clearUserData();\n * ```\n */\nexport function clearUserData(env?: Env): void {\n  const snowplow = getSnowplow(env);\n  if (snowplow) {\n    snowplow('clearUserData');\n  }\n}\n\n/**\n * Enable anonymous tracking mode\n *\n * Call this to start anonymous tracking after initialization.\n * Useful when consent state changes during the session.\n *\n * @param options - Optional configuration for anonymous tracking\n * @param env - Optional environment override for testing\n *\n * @example\n * ```typescript\n * import { enableAnonymousTracking } from '@walkeros/web-destination-snowplow';\n *\n * // Enable with server anonymisation\n * enableAnonymousTracking({ withServerAnonymisation: true });\n * ```\n */\nexport function enableAnonymousTracking(\n  options?: {\n    withServerAnonymisation?: boolean;\n    withSessionTracking?: boolean;\n  },\n  env?: Env,\n): void {\n  const snowplow = getSnowplow(env);\n  if (snowplow) {\n    if (options) {\n      snowplow('enableAnonymousTracking', options);\n    } else {\n      snowplow('enableAnonymousTracking');\n    }\n  }\n}\n\n/**\n * Disable anonymous tracking mode\n *\n * Call this to resume normal tracking after anonymous mode.\n * Useful when a user grants consent during the session.\n *\n * @param stateStorageStrategy - Optional storage strategy for state\n * @param env - Optional environment override for testing\n *\n * @example\n * ```typescript\n * import { disableAnonymousTracking } from '@walkeros/web-destination-snowplow';\n *\n * // Resume normal tracking\n * disableAnonymousTracking();\n * ```\n */\nexport function disableAnonymousTracking(\n  stateStorageStrategy?:\n    | 'cookieAndLocalStorage'\n    | 'cookie'\n    | 'localStorage'\n    | 'none',\n  env?: Env,\n): void {\n  const snowplow = getSnowplow(env);\n  if (snowplow) {\n    if (stateStorageStrategy) {\n      snowplow('disableAnonymousTracking', { stateStorageStrategy });\n    } else {\n      snowplow('disableAnonymousTracking');\n    }\n  }\n}\n\n/**\n * Snowplow destination for walkerOS\n *\n * Sends events to Snowplow Analytics using the browser tracker.\n *\n * @example\n * Basic usage\n * ```typescript\n * import { destinationSnowplow } from '@walkeros/web-destination-snowplow';\n *\n * elb('walker destination', destinationSnowplow, {\n *   settings: {\n *     collectorUrl: 'https://collector.example.com',\n *     appId: 'my-app'\n *   }\n * });\n * ```\n *\n * @example\n * With custom tracker name\n * ```typescript\n * elb('walker destination', destinationSnowplow, {\n *   settings: {\n *     collectorUrl: 'https://collector.example.com',\n *     appId: 'my-app',\n *     trackerName: 'myTracker'\n *   }\n * });\n * ```\n */\nexport const destinationSnowplow: Destination = {\n  type: 'snowplow',\n\n  config: {},\n\n  /**\n   * Initialize the Snowplow tracker\n   *\n   * Creates a new tracker instance with the provided configuration.\n   * Supports two modes:\n   * - `tracker`: Browser-tracker mode with imported functions (npm packages)\n   * - Script-based: Load sp.js script and use command queue (JavaScript tag)\n   *\n   * @param context - Initialization context\n   * @returns Updated configuration\n   */\n  init({ config, env, logger }) {\n    const { settings = {}, loadScript } = config;\n    const { collectorUrl, tracker: trackerFunctions } = settings;\n\n    // Required collector URL\n    if (!collectorUrl) logger.throw('Config settings collectorUrl missing');\n\n    let adapter: SnowplowAdapter | undefined;\n\n    if (trackerFunctions) {\n      // Browser-tracker mode: use imported functions directly\n      if (!trackerFunctions.newTracker) {\n        logger.throw('tracker.newTracker is required for browser-tracker mode');\n        return false;\n      }\n      if (!trackerFunctions.trackSelfDescribingEvent) {\n        logger.throw(\n          'tracker.trackSelfDescribingEvent is required for browser-tracker mode',\n        );\n        return false;\n      }\n\n      // Initialize tracker\n      trackerFunctions.newTracker(settings.trackerName || 'sp', collectorUrl!, {\n        appId: settings.appId || 'walkerOS',\n        platform: settings.platform || 'web',\n        discoverRootDomain: settings.discoverRootDomain,\n        cookieSameSite: settings.cookieSameSite,\n        appVersion: settings.appVersion,\n        contexts: settings.contexts,\n        anonymousTracking: settings.anonymousTracking,\n      });\n\n      // Create adapter from functions\n      adapter = createBrowserTrackerAdapter(trackerFunctions);\n    } else {\n      // URL-based mode: load sp.js script\n      if (loadScript) {\n        addScript(collectorUrl!, env, settings.scriptUrl);\n      }\n\n      const snowplow = setup(env);\n      if (!snowplow) return false;\n\n      // Initialize tracker via queue\n      snowplow('newTracker', settings.trackerName || 'sp', collectorUrl!, {\n        appId: settings.appId || 'walkerOS',\n        platform: settings.platform || 'web',\n        discoverRootDomain: settings.discoverRootDomain,\n        cookieSameSite: settings.cookieSameSite,\n        appVersion: settings.appVersion,\n        contexts: settings.contexts,\n        anonymousTracking: settings.anonymousTracking,\n      });\n\n      adapter = createQueueAdapter(snowplow);\n    }\n\n    if (!adapter) return false;\n\n    // Enable activity tracking if configured\n    if (settings.activityTracking) {\n      adapter.enableActivityTracking(settings.activityTracking);\n    }\n\n    // Load plugins\n    if (settings.plugins) {\n      for (const plugin of settings.plugins) {\n        if (isCodeBasedPlugin(plugin)) {\n          // Code-based plugin: use directly or call factory with config\n          const pluginInstance =\n            typeof plugin.code === 'function' && plugin.config\n              ? (plugin.code as (...args: unknown[]) => BrowserPlugin)(\n                  plugin.config,\n                )\n              : plugin.code;\n          adapter.addPlugin({ plugin: pluginInstance as BrowserPlugin });\n        } else if (isUrlBasedPlugin(plugin)) {\n          // URL-based plugin (sp.js approach only)\n          adapter.addPlugin([plugin.url, plugin.name]);\n          const enableMethod =\n            plugin.enableMethod ?? deriveEnableMethod(plugin.name[1]);\n          if (plugin.options) {\n            adapter.call(enableMethod, plugin.options);\n          } else {\n            adapter.call(enableMethod);\n          }\n        } else {\n          // BrowserPlugin instance\n          adapter.addPlugin({ plugin: plugin as BrowserPlugin });\n        }\n      }\n    }\n\n    // Register global contexts\n    if (settings.globalContexts && settings.globalContexts.length > 0) {\n      adapter.addGlobalContexts(settings.globalContexts);\n    }\n\n    // Track page view on init if configured\n    if (settings.trackPageView) {\n      adapter.trackPageView();\n    }\n\n    // Store adapter in runtime state\n    const updatedSettings = {\n      ...settings,\n      _state: { adapter } as RuntimeState,\n    };\n\n    return { ...config, settings: updatedSettings };\n  },\n\n  /**\n   * Process and send an event to Snowplow\n   *\n   * Transforms the walkerOS event using the mapping configuration and\n   * sends it as a Snowplow ecommerce self-describing event.\n   *\n   * @param event - The walkerOS event to process\n   * @param context - Push context with config, data, rule, and env\n   */\n  async push(event, { config, data = {}, rule = {}, logger, collector }) {\n    const eventMapping = rule.settings || {};\n    await pushSnowplowEvent(\n      event,\n      eventMapping,\n      data as WalkerOS.AnyObject,\n      rule.name,\n      config,\n      logger,\n      collector,\n    );\n  },\n\n  /**\n   * Handle lifecycle events (consent, session, ready, run)\n   *\n   * Primarily used for consent tracking via the Enhanced Consent plugin.\n   * Reacts to walkerOS consent events and calls Snowplow's trackConsentAllow,\n   * trackConsentDeny, or trackConsentSelected methods.\n   *\n   * @param type - The event type ('consent', 'session', 'ready', 'run')\n   * @param context - The destination context with config, data, env, logger\n   */\n  on(type, context) {\n    // Only handle consent events\n    if (type !== 'consent' || !isObject(context.data)) return;\n\n    const consent = context.data;\n    // `on` runs with the runtime (non-generic) context, so config.settings and\n    // env surface as the loose base types. Narrowing them to the destination's\n    // own Settings/Env needs a core-types change to make `on` generic over\n    // Types; tracked as a follow-up. These two `as` casts are that boundary.\n    const settings = (context.config?.settings || {}) as Partial<Settings>;\n    const consentConfig = settings.consent;\n\n    // Skip if consent tracking is not configured\n    if (!consentConfig) return;\n\n    const snowplow = getSnowplow(context.env as Env);\n    if (!snowplow) return;\n\n    // Determine which consent scopes to check\n    const required = consentConfig.required || Object.keys(consent);\n\n    // Calculate consent state based on configured required scopes\n    const allGranted = required.every((scope) => consent[scope] === true);\n    const allDenied = required.every((scope) => !consent[scope]);\n    const grantedScopes = required.filter((scope) => consent[scope] === true);\n\n    // Build Enhanced Consent plugin parameters\n    // For deny events, use required scopes (being denied); for allow/selected, use granted scopes\n    const baseParams: Record<string, unknown> = {\n      basisForProcessing: consentConfig.basisForProcessing || 'consent',\n    };\n\n    // Add optional parameters if configured\n    if (consentConfig.consentUrl)\n      baseParams.consentUrl = consentConfig.consentUrl;\n    if (consentConfig.consentVersion)\n      baseParams.consentVersion = consentConfig.consentVersion;\n    if (consentConfig.domainsApplied)\n      baseParams.domainsApplied = consentConfig.domainsApplied;\n    if (consentConfig.gdprApplies !== undefined)\n      baseParams.gdprApplies = consentConfig.gdprApplies;\n\n    // Call the appropriate Enhanced Consent plugin method\n    if (allDenied) {\n      // For deny, use required scopes (the ones being denied)\n      snowplow('trackConsentDeny', { ...baseParams, consentScopes: required });\n    } else if (allGranted) {\n      snowplow('trackConsentAllow', {\n        ...baseParams,\n        consentScopes: grantedScopes,\n      });\n    } else {\n      snowplow('trackConsentSelected', {\n        ...baseParams,\n        consentScopes: grantedScopes,\n      });\n    }\n  },\n};\n\nexport default destinationSnowplow;\n"],"mappings":"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","names":["window","isObject"]}