@walkeros/web-destination-snowplow 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.d.mts +22 -773
- package/dist/dev.d.ts +22 -773
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.d.mts +14 -766
- package/dist/examples/index.d.ts +14 -766
- package/dist/examples/index.js +172 -1325
- package/dist/examples/index.mjs +171 -1322
- package/dist/index.browser.js +1 -1
- package/dist/index.d.mts +16 -663
- package/dist/index.d.ts +16 -663
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +478 -1533
- package/package.json +3 -3
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/index.ts","../src/setup.ts","../src/push.ts","../src/adapter.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/events.ts","../src/examples/mapping.ts","../src/examples/walkeros-events.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';\nimport 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 official Snowplow entity types\nexport type {\n SelfDescribingJson,\n CommonEventProperties,\n Action,\n Product,\n Cart,\n SPTransaction,\n SPPromotion,\n CheckoutStep,\n Refund,\n TransactionError,\n User,\n Page,\n};\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 { DestinationWeb } from '@walkeros/web-core';\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?: DestinationWeb.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);\n const script = (document as Document).createElement('script');\n script.src = src;\n script.async = true;\n (document as Document).head.appendChild(script);\n loadedScripts.add(collectorUrl);\n}\n\n// Snowplow function interface\ninterface SnowplowFunction {\n (...args: unknown[]): void;\n q?: unknown[];\n}\n\nexport function setup(env?: DestinationWeb.Env): SnowplowFunction | undefined {\n const { window } = getEnv(env);\n const w = window as unknown as {\n snowplow?: SnowplowFunction;\n GlobalSnowplowNamespace?: string[];\n };\n\n // Setup snowplow function if not exists\n if (!w.snowplow) {\n const sp = function (...args: unknown[]): void {\n (sp.q = sp.q || []).push(args);\n } as SnowplowFunction;\n\n sp.q = [];\n w.snowplow = sp;\n w.GlobalSnowplowNamespace = ['snowplow'];\n }\n\n return w.snowplow;\n}\n","import type { WalkerOS, Logger, Mapping as MappingTypes } 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 as Record<string, unknown>).loop) &&\n ((data as Record<string, unknown>).loop as unknown[]).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): 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);\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 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 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 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(event, mapping.struct, adapter, logger);\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);\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);\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): 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\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 );\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(event, { map: contextDef.data });\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): Promise<void> {\n // Resolve required fields\n const category = await getMappingValue(event, struct.category);\n const action = await getMappingValue(event, struct.action);\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)\n : undefined;\n const property = struct.property\n ? await getMappingValue(event, struct.property)\n : undefined;\n const rawValue = struct.value\n ? await getMappingValue(event, struct.value)\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","export * as env from './env';\nexport * as events from './events';\nexport * as mapping from './mapping';\nexport * as walkerosEvents from './walkeros-events';\n","import type { Env } from '../types';\n\n/**\n * Example environment configurations for Snowplow destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring external dependencies.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\nexport const init: Env | undefined = {\n window: {\n snowplow: undefined as unknown as Env['window']['snowplow'],\n },\n document: {\n createElement: () => ({\n src: '',\n async: false,\n setAttribute: () => {},\n removeAttribute: () => {},\n }),\n head: { appendChild: () => {} },\n },\n};\n\nexport const push: Env = {\n window: {\n snowplow: Object.assign(noop, {\n q: [],\n }) as unknown as Env['window']['snowplow'],\n },\n document: {\n createElement: () => ({\n src: '',\n async: false,\n setAttribute: () => {},\n removeAttribute: () => {},\n }),\n head: { appendChild: () => {} },\n },\n};\n\nexport const simulation = [\n 'call:window.snowplow', // Track snowplow function calls\n];\n","/**\n * Example Snowplow function call outputs\n *\n * These represent the actual arguments passed to window.snowplow()\n * when different events are tracked using Snowplow's ecommerce schema.\n *\n * All ecommerce events use the self-describing event format with:\n * - Event action schema: snowplow_ecommerce_action/jsonschema/1-0-2\n * - Context entities with their respective schemas\n *\n * Reference: https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol/\n */\n\n/**\n * Page View Event\n * Uses built-in Snowplow page view tracking\n */\nexport function pageView(): unknown[] {\n return ['trackPageView'];\n}\n\n/**\n * Product View Event\n * walkerOS: elb('product view') - uses default getEvent data\n * Snowplow: product_view action with product context entity\n */\nexport function productView(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'product_view',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'ers',\n name: 'Everyday Ruck Snack',\n price: 420,\n currency: 'USD',\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Add to Cart Event\n * walkerOS: elb('product add', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 })\n * Snowplow: add_to_cart action with product, cart, page, and user context entities\n */\nexport function addToCart(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'add_to_cart',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/cart/jsonschema/1-0-0',\n data: {\n total_value: 999,\n currency: 'USD',\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/page/jsonschema/1-0-0',\n data: {\n type: 'product',\n language: 'en',\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/user/jsonschema/1-0-0',\n data: {\n id: 'U123',\n email: 'user@example.com',\n is_guest: true,\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Remove from Cart Event\n * walkerOS: elb('product remove', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 })\n * Snowplow: remove_from_cart action with product and cart context entities\n */\nexport function removeFromCart(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'remove_from_cart',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/cart/jsonschema/1-0-0',\n data: {\n total_value: 0,\n currency: 'USD',\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Transaction/Purchase Event\n * walkerOS: elb('order complete') - uses default getEvent data\n * Default: { id: '0rd3r1d', currency: 'EUR', shipping: 5.22, taxes: 73.76, total: 555 }\n * Snowplow: transaction action with transaction context entity\n *\n * Note: This is explicit mapping without auto-looping nested products.\n * For product contexts from nested array, use loop in mapping configuration.\n */\nexport function transaction(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'transaction',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/transaction/jsonschema/1-0-0',\n data: {\n transaction_id: '0rd3r1d',\n revenue: 555,\n currency: 'EUR', // From default getEvent data\n payment_method: 'credit_card', // Static value\n tax: 73.76,\n shipping: 5.22,\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Transaction with Multiple Products\n * walkerOS: elb('order complete', { id: 'ORD-456', revenue: 1498, tax: 120, shipping: 15 }, {\n * nested: [\n * { type: 'product', data: { id: 'P123', name: 'Laptop', price: 999, quantity: 1 } },\n * { type: 'product', data: { id: 'P456', name: 'Mouse', price: 49, quantity: 2 } }\n * ]\n * })\n * Snowplow: transaction action with multiple product entities\n */\nexport function transactionMultipleProducts(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'transaction',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/transaction/jsonschema/1-0-0',\n data: {\n transaction_id: 'ORD-456',\n revenue: 1097,\n currency: 'USD',\n payment_method: 'paypal',\n total_quantity: 3,\n tax: 120,\n shipping: 15,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P456',\n name: 'Mouse',\n category: 'Accessories',\n price: 49,\n currency: 'USD',\n quantity: 2,\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Refund Event\n * walkerOS: elb('order refund', { transaction_id: 'ORD-123', amount: 999, reason: 'defective' })\n * Snowplow: refund action with refund context entity\n */\nexport function refund(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'refund',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/refund/jsonschema/1-0-0',\n data: {\n transaction_id: 'ORD-123',\n refund_amount: 999,\n currency: 'USD',\n refund_reason: 'defective',\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Checkout Step Event\n * walkerOS: elb('checkout step', { step: 1, shipping_method: 'express' })\n * Snowplow: checkout_step action with checkout_step context entity\n */\nexport function checkoutStep(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'checkout_step',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/checkout_step/jsonschema/1-0-0',\n data: {\n step: 1,\n delivery_provider: 'express',\n },\n },\n ],\n },\n ];\n}\n\n/**\n * List View Event (Product Listing Page)\n * walkerOS: elb('product list', { category: 'Electronics' }, {\n * nested: [\n * { type: 'product', data: { id: 'P123', name: 'Laptop', price: 999 } },\n * { type: 'product', data: { id: 'P456', name: 'Mouse', price: 49 } }\n * ]\n * })\n * Snowplow: list_view action with multiple product context entities\n */\nexport function listView(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'list_view',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n position: 1,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'P456',\n name: 'Mouse',\n category: 'Electronics',\n price: 49,\n currency: 'USD',\n position: 2,\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Promotion View Event\n * walkerOS: elb('promo view', { id: 'SUMMER2024', name: 'Summer Sale', creative: 'banner_top' })\n * Snowplow: promo_view action with promotion context entity\n */\nexport function promoView(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'promo_view',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/promotion/jsonschema/1-0-0',\n data: {\n id: 'SUMMER2024',\n name: 'Summer Sale',\n creative_id: 'banner_top',\n },\n },\n ],\n },\n ];\n}\n\n/**\n * Custom Self-Describing Event (Non-Ecommerce)\n * Example of a custom event that doesn't use the ecommerce schema\n * walkerOS: elb('custom action', { ... })\n */\nexport function customSelfDescribingEvent(): unknown[] {\n return [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema: 'iglu:com.example/custom_action/jsonschema/1-0-0',\n data: {\n action_type: 'button_click',\n button_id: 'cta_signup',\n location: 'header',\n },\n },\n },\n ];\n}\n\n/**\n * Legacy: Alias for transaction (for backward compatibility with tests)\n */\nexport const purchase = transaction;\n\n/**\n * Legacy: Alias for customSelfDescribingEvent (for backward compatibility with tests)\n */\nexport const selfDescribingEvent = customSelfDescribingEvent;\n\n/**\n * Legacy: Structured Event (deprecated)\n * Old structured event format with 5 fields\n * This format is deprecated in favor of self-describing events\n */\nexport function structuredEvent(): unknown[] {\n return ['trackStructEvent', 'entity', 'action', undefined, undefined, 1];\n}\n","import type { DestinationSnowplow } from '..';\nimport { ACTIONS, SCHEMAS, WEB_SCHEMAS, MEDIA_SCHEMAS } from '../types';\n\n/**\n * Snowplow Ecommerce Mapping Examples\n *\n * Fully explicit mapping - no auto-detection or magic.\n * - `name` at rule level specifies the Snowplow action type\n * - `settings.context` defines context entities with schema and data mapping\n *\n * Pattern: name = action type, settings.context = [{ schema, data }]\n */\n\n/**\n * Page View Mapping\n *\n * Page views use Snowplow's built-in trackPageView method.\n * No custom mapping needed - just pass through.\n */\nexport const pageView: DestinationSnowplow.Rule = {\n // Page view doesn't need action type - uses trackPageView()\n};\n\n/**\n * Product View Mapping\n *\n * walkerOS: elb('product view', { id: 'P123', name: 'Laptop', category: 'Electronics', price: 999 })\n * Snowplow: product_view action with product context entity\n */\nexport const productView: DestinationSnowplow.Rule = {\n name: ACTIONS.PRODUCT_VIEW,\n settings: {\n context: [\n {\n schema: SCHEMAS.PRODUCT,\n data: {\n id: 'data.id',\n name: 'data.name',\n category: 'data.category',\n price: 'data.price',\n currency: { key: 'data.currency', value: 'USD' },\n brand: 'data.brand',\n variant: 'data.variant',\n },\n },\n ],\n },\n};\n\n/**\n * Add to Cart Mapping\n *\n * walkerOS: elb('product add', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 })\n * Snowplow: add_to_cart action with product, cart, page, and user context entities\n *\n * Expects:\n * - data: product properties (id, name, category, price, currency, quantity)\n * - globals: cart_value, cart_currency, page_type, language\n * - user: id, email\n */\nexport const addToCart: DestinationSnowplow.Rule = {\n name: ACTIONS.ADD_TO_CART,\n settings: {\n context: [\n // Product entity\n {\n schema: SCHEMAS.PRODUCT,\n data: {\n id: 'data.id',\n name: 'data.name',\n category: 'data.category',\n price: 'data.price',\n currency: { key: 'data.currency', value: 'USD' },\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n // Cart entity\n {\n schema: SCHEMAS.CART,\n data: {\n total_value: 'globals.cart_value',\n currency: { key: 'globals.cart_currency', value: 'USD' },\n },\n },\n // Page entity\n {\n schema: SCHEMAS.PAGE,\n data: {\n type: 'globals.page_type',\n language: 'globals.language',\n },\n },\n // User entity - is_guest: true when user.id exists\n {\n schema: SCHEMAS.USER,\n data: {\n id: 'user.id',\n email: 'user.email',\n is_guest: {\n fn: (event) =>\n (event as { user?: { id?: string } }).user?.id ? true : undefined,\n },\n },\n },\n ],\n },\n};\n\n/**\n * Remove from Cart Mapping\n *\n * walkerOS: elb('product remove', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 })\n * Snowplow: remove_from_cart action with product context entity\n */\nexport const removeFromCart: DestinationSnowplow.Rule = {\n name: ACTIONS.REMOVE_FROM_CART,\n settings: {\n context: [\n {\n schema: SCHEMAS.PRODUCT,\n data: {\n id: 'data.id',\n name: 'data.name',\n category: 'data.category',\n price: 'data.price',\n currency: { key: 'data.currency', value: 'USD' },\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n};\n\n/**\n * Transaction/Purchase Mapping\n *\n * walkerOS: elb('order complete') - uses default getEvent data\n * Default has: { id, currency, shipping, taxes, total } + nested products\n * Snowplow: transaction action with transaction context entity\n *\n * Note: For product contexts from nested, use loop in data.map\n */\nexport const transaction: DestinationSnowplow.Rule = {\n name: ACTIONS.TRANSACTION,\n settings: {\n context: [\n {\n schema: SCHEMAS.TRANSACTION,\n data: {\n transaction_id: 'data.id',\n revenue: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n payment_method: { value: 'credit_card' },\n tax: 'data.taxes',\n shipping: 'data.shipping',\n },\n },\n ],\n },\n};\n\n/**\n * Refund Mapping\n *\n * walkerOS: elb('order refund', {\n * transaction_id: 'ORD-123', refund_amount: 999, refund_reason: 'defective'\n * })\n * Snowplow: refund action with refund context entity\n */\nexport const refund: DestinationSnowplow.Rule = {\n name: ACTIONS.REFUND,\n settings: {\n context: [\n {\n schema: SCHEMAS.REFUND,\n data: {\n transaction_id: 'data.transaction_id',\n refund_amount: 'data.refund_amount',\n currency: { key: 'data.currency', value: 'USD' },\n refund_reason: 'data.refund_reason',\n refund_method: 'data.refund_method',\n },\n },\n ],\n },\n};\n\n/**\n * Checkout Step Mapping\n *\n * walkerOS: elb('checkout step', { step: 1, delivery_provider: 'express' })\n * Snowplow: checkout_step action with checkout_step context entity\n */\nexport const checkoutStep: DestinationSnowplow.Rule = {\n name: ACTIONS.CHECKOUT_STEP,\n settings: {\n context: [\n {\n schema: SCHEMAS.CHECKOUT_STEP,\n data: {\n step: 'data.step',\n shipping_postcode: 'data.shipping_postcode',\n billing_postcode: 'data.billing_postcode',\n delivery_provider: 'data.delivery_provider',\n delivery_method: 'data.delivery_method',\n payment_method: 'data.payment_method',\n marketing_opt_in: 'data.marketing_opt_in',\n },\n },\n ],\n },\n};\n\n/**\n * Product List View Mapping\n *\n * walkerOS: elb('product list', { category: 'Electronics' })\n * Snowplow: list_view action\n *\n * Note: For multiple products from nested, use loop in data.map\n */\nexport const listView: DestinationSnowplow.Rule = {\n name: ACTIONS.LIST_VIEW,\n // No context needed for list_view without products\n // Use data.map with loop for product contexts\n};\n\n/**\n * Promotion View Mapping\n *\n * walkerOS: elb('promo view', { id: 'SUMMER2024', name: 'Summer Sale', creative_id: 'banner_top' })\n * Snowplow: promo_view action with promotion context entity\n */\nexport const promoView: DestinationSnowplow.Rule = {\n name: ACTIONS.PROMO_VIEW,\n settings: {\n context: [\n {\n schema: SCHEMAS.PROMOTION,\n data: {\n id: 'data.id',\n name: 'data.name',\n creative_id: 'data.creative_id',\n type: 'data.type',\n position: 'data.position',\n slot: 'data.slot',\n },\n },\n ],\n },\n};\n\n/**\n * Promotion Click Mapping\n *\n * walkerOS: elb('promo click', { id: 'SUMMER2024', name: 'Summer Sale' })\n * Snowplow: promo_click action with promotion context entity\n */\nexport const promoClick: DestinationSnowplow.Rule = {\n name: ACTIONS.PROMO_CLICK,\n settings: {\n context: [\n {\n schema: SCHEMAS.PROMOTION,\n data: {\n id: 'data.id',\n name: 'data.name',\n creative_id: 'data.creative_id',\n type: 'data.type',\n position: 'data.position',\n slot: 'data.slot',\n },\n },\n ],\n },\n};\n\n// ============================================================================\n// WEB EVENT MAPPINGS\n// ============================================================================\n\n/**\n * Link Click Mapping (Self-Describing Event)\n *\n * walkerOS: elb('link click', { url: 'https://example.com', text: 'Learn more', id: 'cta-main' })\n * Snowplow: link_click self-describing event\n *\n * Note: Uses self-describing event with custom schema, not ecommerce action\n */\nexport const linkClick: DestinationSnowplow.Rule = {\n name: 'link_click', // Custom action name (not ecommerce)\n settings: {\n snowplow: {\n actionSchema: WEB_SCHEMAS.LINK_CLICK,\n },\n context: [], // No additional contexts needed\n },\n // For link_click, data is passed directly to the schema\n data: {\n map: {\n targetUrl: 'data.url',\n elementId: 'data.id',\n elementClasses: 'data.classes',\n elementContent: 'data.text',\n elementTarget: 'data.target',\n },\n },\n};\n\n/**\n * Form Submit Mapping (Self-Describing Event)\n *\n * walkerOS: elb('form submit', { form_id: 'contact-form', form_classes: ['main-form'] })\n * Snowplow: submit_form self-describing event\n */\nexport const formSubmit: DestinationSnowplow.Rule = {\n name: 'submit_form',\n settings: {\n snowplow: {\n actionSchema: WEB_SCHEMAS.SUBMIT_FORM,\n },\n context: [],\n },\n data: {\n map: {\n formId: 'data.form_id',\n formClasses: 'data.form_classes',\n elements: 'data.elements',\n },\n },\n};\n\n/**\n * Site Search Mapping (Self-Describing Event)\n *\n * walkerOS: elb('search submit', { terms: 'laptop', filters: { category: 'Electronics' }, total_results: 42 })\n * Snowplow: site_search self-describing event\n */\nexport const siteSearch: DestinationSnowplow.Rule = {\n name: 'site_search',\n settings: {\n snowplow: {\n actionSchema: WEB_SCHEMAS.SITE_SEARCH,\n },\n context: [],\n },\n data: {\n map: {\n terms: 'data.terms',\n filters: 'data.filters',\n totalResults: 'data.total_results',\n pageResults: 'data.page_results',\n },\n },\n};\n\n/**\n * Social Share Mapping (Self-Describing Event)\n *\n * walkerOS: elb('social share', { network: 'twitter', action: 'share', target: 'https://example.com/article' })\n * Snowplow: social_interaction self-describing event\n */\nexport const socialShare: DestinationSnowplow.Rule = {\n name: 'social_interaction',\n settings: {\n snowplow: {\n actionSchema: WEB_SCHEMAS.SOCIAL,\n },\n context: [],\n },\n data: {\n map: {\n network: 'data.network',\n action: 'data.action',\n target: 'data.target',\n },\n },\n};\n\n// ============================================================================\n// STRUCTURED EVENT MAPPINGS\n// ============================================================================\n\n/**\n * Button Click (Structured Event)\n *\n * walkerOS: elb('button click', { button_name: 'submit', section: 'header', position: 1 })\n * Snowplow: trackStructEvent (category='ui', action='click', label, property, value)\n *\n * Use structured events for simple interactions that don't need full schemas.\n * No schema validation - just category, action, label, property, value.\n */\nexport const buttonClick: DestinationSnowplow.Rule = {\n settings: {\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 },\n};\n\n/**\n * Navigation Event (Structured Event)\n *\n * walkerOS: elb('navigation click', { menu: 'main', item: 'products', depth: 2 })\n * Snowplow: trackStructEvent (category='navigation', action='click')\n */\nexport const navigationClick: DestinationSnowplow.Rule = {\n settings: {\n struct: {\n category: { value: 'navigation' },\n action: { value: 'click' },\n label: 'data.menu',\n property: 'data.item',\n value: 'data.depth',\n },\n },\n};\n\n/**\n * Video Interaction (Structured Event)\n *\n * walkerOS: elb('video play', { video_id: 'intro-video', video_title: 'Welcome', progress: 25 })\n * Snowplow: trackStructEvent (category='video', action='play')\n *\n * For simple video tracking. Use media schemas for full video analytics.\n */\nexport const videoPlay: DestinationSnowplow.Rule = {\n settings: {\n struct: {\n category: { value: 'video' },\n action: { value: 'play' },\n label: 'data.video_title',\n property: 'data.video_id',\n value: 'data.progress',\n },\n },\n};\n\n/**\n * CTA Interaction (Structured Event)\n *\n * walkerOS: elb('cta click', { cta_id: 'hero-signup', cta_text: 'Get Started', variant: 'A' })\n * Snowplow: trackStructEvent (category='cta', action='click')\n */\nexport const ctaClick: DestinationSnowplow.Rule = {\n settings: {\n struct: {\n category: { value: 'cta' },\n action: { value: 'click' },\n label: 'data.cta_text',\n property: 'data.cta_id',\n },\n },\n};\n\n/**\n * Generic Interaction (Structured Event with Dynamic Category/Action)\n *\n * walkerOS: elb('interaction track', { event_category: 'engagement', event_action: 'scroll', depth: 50 })\n * Snowplow: trackStructEvent with dynamic category/action from event data\n *\n * Useful for flexible event tracking where category/action come from the event itself.\n */\nexport const genericInteraction: DestinationSnowplow.Rule = {\n settings: {\n struct: {\n category: 'data.event_category',\n action: 'data.event_action',\n label: 'data.event_label',\n property: 'data.event_property',\n value: 'data.event_value',\n },\n },\n};\n\n// ============================================================================\n// MEDIA TRACKING MAPPINGS\n// ============================================================================\n\n/**\n * Media Play Event Mapping\n *\n * walkerOS: elb('video play', {\n * current_time: 0, duration: 300, paused: false,\n * volume: 80, muted: false, video_id: 'intro-video', title: 'Welcome'\n * })\n * Snowplow: play_event with media_player and session contexts\n *\n * Use for HTML5 video/audio or custom media players.\n * The media_player context contains current playback state.\n */\nexport const mediaPlay: DestinationSnowplow.Rule = {\n name: 'media_play',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.PLAY,\n },\n context: [\n // Media player state context (required for all media events)\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n playbackRate: { key: 'data.playback_rate', value: 1 },\n loop: { key: 'data.loop', value: false },\n },\n },\n // Media session context (optional - for session-level analytics)\n {\n schema: MEDIA_SCHEMAS.SESSION,\n data: {\n mediaSessionId: 'data.session_id',\n startedAt: 'data.session_started',\n pingInterval: { value: 30 },\n },\n },\n ],\n },\n};\n\n/**\n * Media Pause Event Mapping\n *\n * walkerOS: elb('video pause', {\n * current_time: 45.2, duration: 300, paused: true, volume: 80\n * })\n * Snowplow: pause_event with media_player context\n */\nexport const mediaPause: DestinationSnowplow.Rule = {\n name: 'media_pause',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.PAUSE,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: { value: true },\n muted: 'data.muted',\n volume: 'data.volume',\n playbackRate: { key: 'data.playback_rate', value: 1 },\n },\n },\n ],\n },\n};\n\n/**\n * Media End Event Mapping\n *\n * walkerOS: elb('video end', {\n * current_time: 300, duration: 300, video_id: 'intro-video'\n * })\n * Snowplow: end_event with media_player context\n */\nexport const mediaEnd: DestinationSnowplow.Rule = {\n name: 'media_end',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.END,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: true },\n paused: { value: true },\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n};\n\n/**\n * Media Seek Event Mapping\n *\n * walkerOS: elb('video seek', {\n * current_time: 120, duration: 300, seek_from: 45, seek_to: 120\n * })\n * Snowplow: seek_end_event with media_player context\n *\n * Track when user seeks (jumps) to a different position in the media.\n */\nexport const mediaSeek: DestinationSnowplow.Rule = {\n name: 'media_seek',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.SEEK_END,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n // Additional data for the seek event itself\n data: {\n map: {\n previousTime: 'data.seek_from',\n },\n },\n};\n\n/**\n * Media Progress Event Mapping (Percent Progress)\n *\n * walkerOS: elb('video progress', {\n * current_time: 75, duration: 300, percent: 25\n * })\n * Snowplow: percent_progress_event with media_player context\n *\n * Fires at progress milestones (e.g., 25%, 50%, 75%, 100%).\n */\nexport const mediaProgress: DestinationSnowplow.Rule = {\n name: 'media_progress',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.PERCENT_PROGRESS,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n // The percent progress milestone\n data: {\n map: {\n percentProgress: 'data.percent',\n },\n },\n};\n\n/**\n * Media Buffer Event Mapping\n *\n * walkerOS: elb('video buffer', {\n * current_time: 45.2, duration: 300, buffering: true\n * })\n * Snowplow: buffer_start_event with media_player context\n *\n * Track buffering events for quality of experience analysis.\n */\nexport const mediaBuffer: DestinationSnowplow.Rule = {\n name: 'media_buffer',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.BUFFER_START,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n};\n\n/**\n * Media Quality Change Event Mapping\n *\n * walkerOS: elb('video quality', {\n * current_time: 45.2, previous_quality: '720p', new_quality: '1080p', auto: false\n * })\n * Snowplow: quality_change_event with media_player context\n */\nexport const mediaQualityChange: DestinationSnowplow.Rule = {\n name: 'media_quality_change',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.QUALITY_CHANGE,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n data: {\n map: {\n previousQuality: 'data.previous_quality',\n newQuality: 'data.new_quality',\n bitrate: 'data.bitrate',\n framesPerSecond: 'data.fps',\n automatic: 'data.auto',\n },\n },\n};\n\n/**\n * Media Fullscreen Change Event Mapping\n *\n * walkerOS: elb('video fullscreen', {\n * current_time: 45.2, fullscreen: true\n * })\n * Snowplow: fullscreen_change_event with media_player context\n */\nexport const mediaFullscreen: DestinationSnowplow.Rule = {\n name: 'media_fullscreen',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.FULLSCREEN_CHANGE,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n data: {\n map: {\n fullscreen: 'data.fullscreen',\n },\n },\n};\n\n/**\n * Media Error Event Mapping\n *\n * walkerOS: elb('video error', {\n * current_time: 45.2, error_code: 'MEDIA_ERR_NETWORK', error_message: 'Network error'\n * })\n * Snowplow: error_event with media_player context\n */\nexport const mediaError: DestinationSnowplow.Rule = {\n name: 'media_error',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.ERROR,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: { value: true },\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n ],\n },\n data: {\n map: {\n errorCode: 'data.error_code',\n errorName: 'data.error_name',\n errorDescription: 'data.error_message',\n },\n },\n};\n\n// ============================================================================\n// AD TRACKING MAPPINGS (for video ads)\n// ============================================================================\n\n/**\n * Ad Break Start Event Mapping\n *\n * walkerOS: elb('ad break_start', {\n * current_time: 0, ad_break_type: 'preroll', ad_break_id: 'preroll-1'\n * })\n * Snowplow: ad_break_start_event with media_player and ad_break contexts\n */\nexport const adBreakStart: DestinationSnowplow.Rule = {\n name: 'ad_break_start',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.AD_BREAK_START,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: 'data.paused',\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n {\n schema: MEDIA_SCHEMAS.AD_BREAK,\n data: {\n breakId: 'data.ad_break_id',\n name: 'data.ad_break_name',\n breakType: 'data.ad_break_type', // 'preroll', 'midroll', 'postroll'\n podSize: 'data.pod_size',\n },\n },\n ],\n },\n};\n\n/**\n * Ad Start Event Mapping\n *\n * walkerOS: elb('ad start', {\n * current_time: 0, ad_id: 'ad-123', creative_id: 'creative-456',\n * advertiser: 'Acme Corp', duration: 30, skippable: true\n * })\n * Snowplow: ad_start_event with media_player and ad contexts\n */\nexport const adStart: DestinationSnowplow.Rule = {\n name: 'ad_start',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.AD_START,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: { value: false },\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n {\n schema: MEDIA_SCHEMAS.AD,\n data: {\n adId: 'data.ad_id',\n name: 'data.ad_name',\n creativeId: 'data.creative_id',\n duration: 'data.ad_duration',\n skippable: 'data.skippable',\n podPosition: 'data.pod_position',\n },\n },\n ],\n },\n};\n\n/**\n * Ad Complete Event Mapping\n *\n * walkerOS: elb('ad complete', {\n * current_time: 30, ad_id: 'ad-123'\n * })\n * Snowplow: ad_complete_event with media_player and ad contexts\n */\nexport const adComplete: DestinationSnowplow.Rule = {\n name: 'ad_complete',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.AD_COMPLETE,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: { value: false },\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n {\n schema: MEDIA_SCHEMAS.AD,\n data: {\n adId: 'data.ad_id',\n name: 'data.ad_name',\n creativeId: 'data.creative_id',\n },\n },\n ],\n },\n};\n\n/**\n * Ad Skip Event Mapping\n *\n * walkerOS: elb('ad skip', {\n * current_time: 5, ad_id: 'ad-123', time_skipped_at: 5\n * })\n * Snowplow: ad_skip_event with media_player and ad contexts\n */\nexport const adSkip: DestinationSnowplow.Rule = {\n name: 'ad_skip',\n settings: {\n snowplow: {\n actionSchema: MEDIA_SCHEMAS.AD_SKIP,\n },\n context: [\n {\n schema: MEDIA_SCHEMAS.MEDIA_PLAYER,\n data: {\n currentTime: 'data.current_time',\n duration: 'data.duration',\n ended: { value: false },\n paused: { value: false },\n muted: 'data.muted',\n volume: 'data.volume',\n },\n },\n {\n schema: MEDIA_SCHEMAS.AD,\n data: {\n adId: 'data.ad_id',\n name: 'data.ad_name',\n creativeId: 'data.creative_id',\n },\n },\n ],\n },\n data: {\n map: {\n percentProgress: 'data.percent_at_skip',\n },\n },\n};\n\n/**\n * Complete Mapping Configuration\n *\n * Maps walkerOS event names to Snowplow ecommerce actions.\n * Fully explicit - no auto-detection or magic.\n */\nexport const config = {\n page: { view: pageView },\n product: {\n view: productView,\n add: addToCart,\n remove: removeFromCart,\n list: listView,\n },\n order: {\n complete: transaction,\n refund: refund,\n },\n checkout: {\n step: checkoutStep,\n },\n promo: {\n view: promoView,\n click: promoClick,\n },\n} satisfies DestinationSnowplow.Rules;\n\n/**\n * Web Analytics Mapping Configuration\n *\n * Maps walkerOS event names to Snowplow web analytics events.\n * Includes both self-describing events and structured events.\n */\nexport const webConfig = {\n link: { click: linkClick },\n form: { submit: formSubmit },\n search: { submit: siteSearch },\n social: { share: socialShare },\n button: { click: buttonClick },\n navigation: { click: navigationClick },\n video: { play: videoPlay },\n cta: { click: ctaClick },\n interaction: { track: genericInteraction },\n} satisfies DestinationSnowplow.Rules;\n\n/**\n * Media Tracking Mapping Configuration\n *\n * Maps walkerOS event names to Snowplow media tracking events.\n * Includes video playback, progress, and ad tracking.\n *\n * For automatic media tracking, consider using Snowplow's\n * @snowplow/browser-plugin-media-tracking plugin instead.\n */\nexport const mediaConfig = {\n video: {\n play: mediaPlay,\n pause: mediaPause,\n end: mediaEnd,\n seek: mediaSeek,\n progress: mediaProgress,\n buffer: mediaBuffer,\n quality: mediaQualityChange,\n fullscreen: mediaFullscreen,\n error: mediaError,\n },\n ad: {\n break_start: adBreakStart,\n start: adStart,\n complete: adComplete,\n skip: adSkip,\n },\n} satisfies DestinationSnowplow.Rules;\n","import type { WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * Example walkerOS events that would generate Snowplow ecommerce events\n *\n * These represent the actual walkerOS events (with their data and nested entities)\n * that would be transformed into Snowplow ecommerce schema format.\n *\n * Pattern: walkerOS event → Snowplow self-describing event with context entities\n */\n\n/**\n * Page View Event\n * walkerOS: elb('page view', { id: '/products', title: 'Product Listing' })\n * Generated when a user views a page\n */\nexport function pageView(): WalkerOS.Event {\n return getEvent('page view', {\n data: {\n id: '/products',\n title: 'Product Listing',\n domain: 'shop.example.com',\n referrer: 'https://google.com',\n },\n });\n}\n\n/**\n * Product View Event\n * walkerOS: elb('product view', { id: 'P123', name: 'Laptop', category: 'Electronics', price: 999 })\n * Generated when viewing a product detail page\n */\nexport function productView(): WalkerOS.Event {\n return getEvent('product view', {\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n brand: 'TechBrand',\n variant: 'Space Gray',\n },\n context: { shopping: ['detail', 0] },\n globals: { pagegroup: 'shop' },\n });\n}\n\n/**\n * Add to Cart Event\n * walkerOS: elb('product add', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 }, {\n * globals: { cart_value: 999, cart_currency: 'USD', page_type: 'product', language: 'en' },\n * user: { id: 'U123', email: 'user@example.com' }\n * })\n * Generated when adding a product to cart\n */\nexport function addToCart(): WalkerOS.Event {\n return getEvent('product add', {\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n globals: {\n cart_value: 999,\n cart_currency: 'USD',\n page_type: 'product',\n language: 'en',\n pagegroup: 'shop',\n },\n user: {\n id: 'U123',\n email: 'user@example.com',\n },\n context: { shopping: ['cart', 0] },\n });\n}\n\n/**\n * Remove from Cart Event\n * walkerOS: elb('product remove', { id: 'P123', name: 'Laptop', price: 999, quantity: 1 }, {\n * globals: { cart_total: 0, cart_currency: 'USD' }\n * })\n * Generated when removing a product from cart\n */\nexport function removeFromCart(): WalkerOS.Event {\n return getEvent('product remove', {\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n globals: {\n cart_total: 0,\n cart_currency: 'USD',\n pagegroup: 'shop',\n },\n context: { shopping: ['cart', 0] },\n });\n}\n\n/**\n * Transaction/Purchase Event (Single Product)\n * walkerOS: elb('order complete', {\n * id: 'ORD-123',\n * revenue: 999,\n * tax: 80,\n * shipping: 10,\n * currency: 'USD',\n * payment_method: 'credit_card'\n * }, {\n * nested: [\n * { type: 'product', data: { id: 'P123', name: 'Laptop', category: 'Electronics', price: 999, quantity: 1 } }\n * ]\n * })\n * Generated when order is completed\n */\nexport function transaction(): WalkerOS.Event {\n return getEvent('order complete', {\n data: {\n id: 'ORD-123',\n revenue: 999,\n currency: 'USD',\n payment_method: 'credit_card',\n total_quantity: 1,\n tax: 80,\n shipping: 10,\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n nested: [],\n },\n ],\n context: { shopping: ['complete', 0] },\n globals: { pagegroup: 'shop' },\n });\n}\n\n/**\n * Transaction with Multiple Products\n * walkerOS: elb('order complete', {\n * id: 'ORD-456',\n * revenue: 1097,\n * tax: 120,\n * shipping: 15,\n * currency: 'USD',\n * payment_method: 'paypal'\n * }, {\n * nested: [\n * { type: 'product', data: { id: 'P123', name: 'Laptop', price: 999, quantity: 1 } },\n * { type: 'product', data: { id: 'P456', name: 'Mouse', price: 49, quantity: 2 } }\n * ]\n * })\n * Generated when order with multiple products is completed\n */\nexport function transactionMultipleProducts(): WalkerOS.Event {\n return getEvent('order complete', {\n data: {\n id: 'ORD-456',\n revenue: 1097,\n currency: 'USD',\n payment_method: 'paypal',\n total_quantity: 3,\n tax: 120,\n shipping: 15,\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n quantity: 1,\n },\n nested: [],\n },\n {\n entity: 'product',\n data: {\n id: 'P456',\n name: 'Mouse',\n category: 'Accessories',\n price: 49,\n currency: 'USD',\n quantity: 2,\n },\n nested: [],\n },\n ],\n context: { shopping: ['complete', 0] },\n globals: { pagegroup: 'shop' },\n });\n}\n\n/**\n * Refund Event\n * walkerOS: elb('order refund', {\n * transaction_id: 'ORD-123',\n * refund_amount: 999,\n * currency: 'USD',\n * refund_reason: 'defective'\n * })\n * Generated when processing a refund\n */\nexport function refund(): WalkerOS.Event {\n return getEvent('order refund', {\n data: {\n transaction_id: 'ORD-123',\n refund_amount: 999,\n currency: 'USD',\n refund_reason: 'defective',\n },\n context: { shopping: ['refund', 0] },\n globals: { pagegroup: 'account' },\n });\n}\n\n/**\n * Checkout Step Event\n * walkerOS: elb('checkout step', { step: 1, delivery_provider: 'express' })\n * Generated when progressing through checkout\n */\nexport function checkoutStep(): WalkerOS.Event {\n return getEvent('checkout step', {\n data: {\n step: 1,\n delivery_provider: 'express',\n shipping_tier: 'next_day',\n },\n context: { shopping: ['checkout', 0] },\n globals: { pagegroup: 'shop' },\n });\n}\n\n/**\n * List View Event (Product Listing Page)\n * walkerOS: elb('product list', { category: 'Electronics', list_name: 'Search Results' }, {\n * nested: [\n * { type: 'product', data: { id: 'P123', name: 'Laptop', price: 999, position: 1 } },\n * { type: 'product', data: { id: 'P456', name: 'Mouse', price: 49, position: 2 } }\n * ]\n * })\n * Generated when viewing a product listing page (search, category, etc.)\n */\nexport function listView(): WalkerOS.Event {\n return getEvent('product list', {\n data: {\n category: 'Electronics',\n list_name: 'Search Results',\n query: 'laptop',\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'P123',\n name: 'Laptop',\n category: 'Electronics',\n price: 999,\n currency: 'USD',\n position: 1,\n },\n nested: [],\n },\n {\n entity: 'product',\n data: {\n id: 'P456',\n name: 'Mouse',\n category: 'Electronics',\n price: 49,\n currency: 'USD',\n position: 2,\n },\n nested: [],\n },\n ],\n context: { shopping: ['browse', 0] },\n globals: { pagegroup: 'shop' },\n });\n}\n\n/**\n * Promotion View Event\n * walkerOS: elb('promo view', {\n * id: 'SUMMER2024',\n * name: 'Summer Sale',\n * creative_id: 'banner_top',\n * position: 'hero'\n * })\n * Generated when a promotion is displayed to the user\n */\nexport function promoView(): WalkerOS.Event {\n return getEvent('promo view', {\n data: {\n id: 'SUMMER2024',\n name: 'Summer Sale',\n creative_id: 'banner_top',\n position: 'hero',\n discount: '20%',\n },\n context: { promotion: ['display', 0] },\n globals: { pagegroup: 'homepage' },\n });\n}\n\n/**\n * Custom Event (Non-Ecommerce)\n * walkerOS: elb('custom action', { action_type: 'button_click', button_id: 'cta_signup' })\n * Example of a custom event that doesn't use ecommerce schema\n */\nexport function customEvent(): WalkerOS.Event {\n return getEvent('custom action', {\n data: {\n action_type: 'button_click',\n button_id: 'cta_signup',\n location: 'header',\n },\n context: { interaction: ['engagement', 0] },\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';\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// Examples (for testing)\nexport * as examples from './examples';\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 = {} as Partial<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 }) {\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 );\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' || !context.data) return;\n\n const consent = context.data as WalkerOS.Consent;\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":["document","window","config","config","addToCart","checkoutStep","listView","pageView","productView","promoView","refund","removeFromCart","transaction","pageView","productView","addToCart","removeFromCart","transaction","refund","checkoutStep","listView","promoView","addToCart","checkoutStep","listView","pageView","productView","promoView","refund","removeFromCart","transaction","transactionMultipleProducts","pageView","productView","addToCart","removeFromCart","transaction","transactionMultipleProducts","refund","checkoutStep","listView","promoView","config"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/index.ts","../src/setup.ts","../src/push.ts","../src/adapter.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.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';\nimport 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 official Snowplow entity types\nexport type {\n SelfDescribingJson,\n CommonEventProperties,\n Action,\n Product,\n Cart,\n SPTransaction,\n SPPromotion,\n CheckoutStep,\n Refund,\n TransactionError,\n User,\n Page,\n};\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 { DestinationWeb } from '@walkeros/web-core';\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?: DestinationWeb.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);\n const script = (document as Document).createElement('script');\n script.src = src;\n script.async = true;\n (document as Document).head.appendChild(script);\n loadedScripts.add(collectorUrl);\n}\n\n// Snowplow function interface\ninterface SnowplowFunction {\n (...args: unknown[]): void;\n q?: unknown[];\n}\n\nexport function setup(env?: DestinationWeb.Env): SnowplowFunction | undefined {\n const { window } = getEnv(env);\n const w = window as unknown as {\n snowplow?: SnowplowFunction;\n GlobalSnowplowNamespace?: string[];\n };\n\n // Setup snowplow function if not exists\n if (!w.snowplow) {\n const sp = function (...args: unknown[]): void {\n (sp.q = sp.q || []).push(args);\n } as SnowplowFunction;\n\n sp.q = [];\n w.snowplow = sp;\n w.GlobalSnowplowNamespace = ['snowplow'];\n }\n\n return w.snowplow;\n}\n","import type { WalkerOS, Logger, Mapping as MappingTypes } 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 as Record<string, unknown>).loop) &&\n ((data as Record<string, unknown>).loop as unknown[]).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): 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);\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 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 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 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(event, mapping.struct, adapter, logger);\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);\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);\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): 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\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 );\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(event, { map: contextDef.data });\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): Promise<void> {\n // Resolve required fields\n const category = await getMappingValue(event, struct.category);\n const action = await getMappingValue(event, struct.action);\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)\n : undefined;\n const property = struct.property\n ? await getMappingValue(event, struct.property)\n : undefined;\n const rawValue = struct.value\n ? await getMappingValue(event, struct.value)\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","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\n\n/**\n * Example environment configurations for Snowplow destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring external dependencies.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\nexport const init: Env | undefined = {\n window: {\n snowplow: undefined as unknown as Env['window']['snowplow'],\n },\n document: {\n createElement: () => ({\n src: '',\n async: false,\n setAttribute: () => {},\n removeAttribute: () => {},\n }),\n head: { appendChild: () => {} },\n },\n};\n\nexport const push: Env = {\n window: {\n snowplow: Object.assign(noop, {\n q: [],\n }) as unknown as Env['window']['snowplow'],\n },\n document: {\n createElement: () => ({\n src: '',\n async: false,\n setAttribute: () => {},\n removeAttribute: () => {},\n }),\n head: { appendChild: () => {} },\n },\n};\n\nexport const simulation = [\n 'call:window.snowplow', // Track snowplow function calls\n];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport { ACTIONS, SCHEMAS } from '../types';\n\nexport const productView: Flow.StepExample = {\n in: getEvent('product view', { timestamp: 1700000400 }),\n mapping: {\n name: ACTIONS.PRODUCT_VIEW,\n settings: {\n context: [\n {\n schema: SCHEMAS.PRODUCT,\n data: {\n id: 'data.id',\n name: 'data.name',\n category: 'data.category',\n price: 'data.price',\n currency: { key: 'data.currency', value: 'USD' },\n brand: 'data.brand',\n variant: 'data.variant',\n },\n },\n ],\n },\n },\n out: [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'product_view',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'ers',\n name: 'Everyday Ruck Snack',\n price: 420,\n currency: 'USD',\n },\n },\n ],\n },\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n in: getEvent('product add', { timestamp: 1700000401 }),\n mapping: {\n name: ACTIONS.ADD_TO_CART,\n settings: {\n context: [\n {\n schema: SCHEMAS.PRODUCT,\n data: {\n id: 'data.id',\n name: 'data.name',\n category: 'data.category',\n price: 'data.price',\n currency: { key: 'data.currency', value: 'USD' },\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n {\n schema: SCHEMAS.CART,\n data: {\n total_value: 'globals.cart_value',\n currency: { key: 'globals.cart_currency', value: 'USD' },\n },\n },\n {\n schema: SCHEMAS.PAGE,\n data: {\n type: 'globals.page_type',\n language: 'globals.language',\n },\n },\n {\n schema: SCHEMAS.USER,\n data: {\n id: 'user.id',\n email: 'user.email',\n is_guest: {\n fn: (event: unknown) =>\n (event as { user?: { id?: string } }).user?.id\n ? true\n : undefined,\n },\n },\n },\n ],\n },\n },\n out: [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'add_to_cart',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/product/jsonschema/1-0-0',\n data: {\n id: 'ers',\n name: 'Everyday Ruck Snack',\n price: 420,\n currency: 'USD',\n quantity: 1,\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/cart/jsonschema/1-0-0',\n data: {\n currency: 'USD',\n },\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/page/jsonschema/1-0-0',\n data: {},\n },\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/user/jsonschema/1-0-0',\n data: {\n id: 'us3r',\n is_guest: true,\n },\n },\n ],\n },\n ],\n};\n\nexport const transaction: Flow.StepExample = {\n in: getEvent('order complete', { timestamp: 1700000402 }),\n mapping: {\n name: ACTIONS.TRANSACTION,\n settings: {\n context: [\n {\n schema: SCHEMAS.TRANSACTION,\n data: {\n transaction_id: 'data.id',\n revenue: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n payment_method: { value: 'credit_card' },\n tax: 'data.taxes',\n shipping: 'data.shipping',\n },\n },\n ],\n },\n },\n out: [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'transaction',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/transaction/jsonschema/1-0-0',\n data: {\n transaction_id: '0rd3r1d',\n revenue: 555,\n currency: 'EUR',\n payment_method: 'credit_card',\n tax: 73.76,\n shipping: 5.22,\n },\n },\n ],\n },\n ],\n};\n\nexport const promoView: Flow.StepExample = {\n in: getEvent('promotion visible', { timestamp: 1700000403 }),\n mapping: {\n name: ACTIONS.PROMO_VIEW,\n settings: {\n context: [\n {\n schema: SCHEMAS.PROMOTION,\n data: {\n id: 'data.id',\n name: 'data.name',\n creative_id: 'data.creative_id',\n type: 'data.type',\n position: 'data.position',\n slot: 'data.slot',\n },\n },\n ],\n },\n },\n out: [\n 'trackSelfDescribingEvent',\n {\n event: {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/snowplow_ecommerce_action/jsonschema/1-0-2',\n data: {\n type: 'promo_view',\n },\n },\n context: [\n {\n schema:\n 'iglu:com.snowplowanalytics.snowplow.ecommerce/promotion/jsonschema/1-0-0',\n data: {\n name: 'Setting up tracking easily',\n position: 'hero',\n },\n },\n ],\n },\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n in: getEvent('page view', { timestamp: 1700000404 }),\n mapping: undefined,\n out: ['trackPageView'],\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';\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// Examples (for testing)\nexport * as examples from './examples';\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 = {} as Partial<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 }) {\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 );\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' || !context.data) return;\n\n const consent = context.data as WalkerOS.Consent;\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":["document","window"]}
|