@bluenath/engage 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -39
- package/dist/core/Analytics.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +47 -6
- package/dist/types/index.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
# @bluenath/engage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official analytics and attribution SDK for [EngagePro](https://engagepro.bluenath.com). Production-ready event capture for campaign ROI measurement and creator attribution.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Developed by the [Bluenath](https://bluenath.com) team.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
---
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`@bluenath/engage` is a high-performance analytics SDK designed to bridge the gap between user interactions and campaign attribution. It captures critical web events, enriches intent signals, and securely transmits batched payloads to EngagePro's ingestion servers for real-time ROI analysis.
|
|
12
|
+
|
|
13
|
+
## Key Features
|
|
14
|
+
|
|
15
|
+
- **Automated Event Capture**: Seamlessly tracks high-value interactions including page views, commerce events, form submissions, and friction signals (e.g., rage-clicks).
|
|
16
|
+
- **Manual Business Events**: Flexible API for tracking custom conversions with support for value, currency, and campaign metadata.
|
|
17
|
+
- **Resilient Delivery**: Robust offline queueing mechanism with exponential backoff and retry logic.
|
|
18
|
+
- **Framework Integration**: Includes a lightweight React Provider and custom hooks for modern web architectures.
|
|
19
|
+
- **Data Security**: Built-in protection for sensitive input fields and secure handling of attribution identifiers.
|
|
14
20
|
|
|
15
21
|
## Installation
|
|
16
22
|
|
|
23
|
+
Install the package via your preferred package manager:
|
|
24
|
+
|
|
17
25
|
```bash
|
|
18
26
|
npm install @bluenath/engage
|
|
19
27
|
```
|
|
20
28
|
|
|
21
29
|
## Quick Start (React)
|
|
22
30
|
|
|
31
|
+
Initialize the SDK at the root of your application using the `EngageProProvider`.
|
|
32
|
+
|
|
23
33
|
```tsx
|
|
24
34
|
import React from "react";
|
|
25
35
|
import ReactDOM from "react-dom/client";
|
|
@@ -40,60 +50,62 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
|
40
50
|
);
|
|
41
51
|
```
|
|
42
52
|
|
|
43
|
-
## Manual Tracking
|
|
53
|
+
## Manual Event Tracking
|
|
54
|
+
|
|
55
|
+
Use the `useAnalytics` hook to capture specific business outcomes.
|
|
44
56
|
|
|
45
57
|
```tsx
|
|
46
58
|
import { useAnalytics } from "@bluenath/engage";
|
|
47
59
|
|
|
48
|
-
export function
|
|
60
|
+
export function PurchaseConfirmation() {
|
|
49
61
|
const analytics = useAnalytics();
|
|
50
62
|
|
|
51
|
-
const
|
|
63
|
+
const handlePurchase = () => {
|
|
52
64
|
analytics.track("PURCHASE", {
|
|
53
|
-
orderId: "ORD-
|
|
54
|
-
amount:
|
|
65
|
+
orderId: "ORD-1029",
|
|
66
|
+
amount: 4999,
|
|
55
67
|
currency: "INR",
|
|
56
68
|
ref: "camp_<campaignId>_cr_<creatorId>",
|
|
57
69
|
});
|
|
58
70
|
};
|
|
59
71
|
|
|
60
|
-
return <button onClick={
|
|
72
|
+
return <button onClick={handlePurchase}>Confirm Payout</button>;
|
|
61
73
|
}
|
|
62
74
|
```
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
### Attribution Reference Format
|
|
65
77
|
|
|
66
|
-
For campaign
|
|
67
|
-
|
|
68
|
-
```text
|
|
69
|
-
camp_<campaignId>_cr_<creatorId>
|
|
70
|
-
```
|
|
78
|
+
For accurate campaign attribution, ensure the `ref` field follows the standard EngagePro format:
|
|
79
|
+
`camp_<campaignId>_cr_<creatorId>`
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
## API Reference
|
|
73
82
|
|
|
74
|
-
|
|
83
|
+
### Provider Configuration
|
|
75
84
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
| Property | Type | Required | Description |
|
|
86
|
+
| :--- | :--- | :--- | :--- |
|
|
87
|
+
| `writeKey` | `string` | **Yes** | Your public brand write key from the [EngagePro Dashboard](https://engagepro.bluenath.com/app/integration). |
|
|
88
|
+
| `apiHost` | `string` | No | Local development override (restricted to `localhost` or `127.0.0.1`). |
|
|
89
|
+
| `tracking.autoTrack` | `boolean` | **Yes** | Enables automated DOM interaction capture. |
|
|
90
|
+
| `tracking.useCookies`| `boolean` | **Yes** | Persists anonymous identifiers across sessions. |
|
|
91
|
+
| `tracking.fingerprint`| `boolean` | **Yes** | Includes device context for fraud prevention and unique visit tracking. |
|
|
92
|
+
| `debug` | `boolean` | No | Enables console logging for integration testing. |
|
|
79
93
|
|
|
80
|
-
##
|
|
94
|
+
## Network & Security Policies
|
|
81
95
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| `tracking.fingerprint` | `boolean` | Yes | Include device fingerprint context |
|
|
89
|
-
| `debug` | `boolean` | No | Log payloads in console for integration testing |
|
|
96
|
+
- **Endpoint Isolation**: Production data is exclusively routed to EngagePro's managed infrastructure.
|
|
97
|
+
- **Local Development**: The `apiHost` parameter is strictly limited to local environments for testing. External host overrides are rejected for security compliance.
|
|
98
|
+
- **Security Best Practices**:
|
|
99
|
+
- Never expose internal service keys in client-side code.
|
|
100
|
+
- Rotate write keys immediately if leakage is suspected.
|
|
101
|
+
- Use hashed or anonymous identifiers; do not transmit raw PII (Personally Identifiable Information).
|
|
90
102
|
|
|
91
|
-
##
|
|
103
|
+
## Resources
|
|
92
104
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
105
|
+
- [Official Documentation](https://engagepro.bluenath.com/docs)
|
|
106
|
+
- [EngagePro Platform](https://engagepro.bluenath.com)
|
|
107
|
+
- [Bluenath Creator OS](https://bluenath.com)
|
|
96
108
|
|
|
97
109
|
## License
|
|
98
110
|
|
|
99
|
-
MIT
|
|
111
|
+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
|
package/dist/core/Analytics.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare class EngagePro {
|
|
|
9
9
|
identify: (userId: string, traits?: Record<string, unknown>) => void;
|
|
10
10
|
page: (name?: string, properties?: Record<string, unknown>) => void;
|
|
11
11
|
track: (eventName: string, properties?: Record<string, unknown>, intelligence?: Partial<AnalyticsEvent>) => void;
|
|
12
|
-
trackRevenue: (
|
|
12
|
+
trackRevenue: (amount: number | string, properties?: Record<string, unknown>, intelligence?: Partial<AnalyticsEvent>) => void;
|
|
13
13
|
private parseRef;
|
|
14
14
|
private processEvent;
|
|
15
15
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);Object.defineProperties(exports,{t:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("react/jsx-runtime"),i=require("react");let s;const r=new Uint8Array(16);function o(){if(!s&&(s="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!s))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return s(r)}const a=[];for(let E=0;E<256;++E)a.push((E+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,n){if(c.randomUUID&&!t)return c.randomUUID();const i=(t=t||{}).random||(t.rng||o)();return i[6]=15&i[6]|64,i[8]=63&i[8]|128,function(t,e=0){return a[t[e+0]]+a[t[e+1]]+a[t[e+2]]+a[t[e+3]]+"-"+a[t[e+4]]+a[t[e+5]]+"-"+a[t[e+6]]+a[t[e+7]]+"-"+a[t[e+8]]+a[t[e+9]]+"-"+a[t[e+10]]+a[t[e+11]]+a[t[e+12]]+a[t[e+13]]+a[t[e+14]]+a[t[e+15]]}(i)}const h=t=>{let e=2166136261;const n=t.length;for(let i=0;i<n;i++)e^=t.charCodeAt(i),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return("0000000"+(e>>>0).toString(16)).substr(-8)};class l{constructor(t="local"){e(this,"memoryStore",{}),e(this,"keyPrefix","engage_"),e(this,"domain"),this.type=t,this.domain=this.getCookieDomain()}getItem(t){const e=this.keyPrefix+t;if(this.memoryStore.hasOwnProperty(e))return this.memoryStore[e];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(e);if("cookie"===this.type&&this.isBrowser())return this.getCookie(e)}catch(n){return null}return null}setItem(t,e){const n=this.keyPrefix+t;this.memoryStore[n]=e;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(n,e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(n,e,365)}catch(i){this.isQuotaError(i)&&(this.type="memory")}}removeItem(t){const e=this.keyPrefix+t;delete this.memoryStore[e];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(e,"",-1)}catch(n){}}getCookie(t){const e=t+"=",n=document.cookie.split(";");for(let i=0;i<n.length;i++){let t=n[i];for(;" "===t.charAt(0);)t=t.substring(1,t.length);if(0===t.indexOf(e))return decodeURIComponent(t.substring(e.length,t.length))}return null}setCookie(t,e,n){let i="";if(n){const t=new Date;t.setTime(t.getTime()+24*n*60*60*1e3),i="; expires="+t.toUTCString()}document.cookie=`${t}=${encodeURIComponent(e)}${i}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const t=window.location.hostname,e=t.split(".");return 1===e.length||"localhost"===t?"":e.length>2?"."+e.slice(-2).join("."):"."+t}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(t){return!1}}isQuotaError(t){return t instanceof DOMException&&(22===t.code||1014===t.code||"QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)}}class u{constructor(t){e(this,"storage"),e(this,"SESSION_TIMEOUT",18e5),e(this,"deviceId"),e(this,"sessionId"),e(this,"userId",null),e(this,"currentUrl"),e(this,"referrer"),this.storage=new l(t.persistence),this.deviceId=this.getOrSetDeviceId(),this.sessionId="",this.manageSession(),"undefined"!=typeof window?(this.currentUrl=window.location.href,this.referrer=document.referrer,this.listenToHistory()):(this.currentUrl="",this.referrer="")}getOrSetDeviceId(){const t=this.storage.getItem("device_id");if(t)return t;const e=(()=>{if("undefined"==typeof window)return"server-side-id";const t=navigator,e=window.screen,n={userAgent:t.userAgent||"",screenRes:`${e.width}x${e.height}`,colorDepth:e.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:t.language||"en-US",platform:t.platform||"unknown",hardwareConcurrency:t.hardwareConcurrency||1,deviceMemory:t.deviceMemory||0},i=[n.platform,n.language,n.screenRes,n.colorDepth,n.timezone,n.hardwareConcurrency,n.deviceMemory].join("|");return`${h(i)}-${h(n.userAgent)}`})();return this.storage.setItem("device_id",e),e}manageSession(){const t=Date.now(),e=this.storage.getItem("session_id"),n=parseInt(this.storage.getItem("last_activity")||"0");if(!e||t-n>this.SESSION_TIMEOUT?(this.sessionId=`sess_${t}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=e,this.storage.setItem("last_activity",t.toString()),"undefined"!=typeof window){const t=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",t),window.addEventListener("scroll",t)}}listenToHistory(){const t=history.pushState;history.pushState=(...e)=>{t.apply(history,e),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const t=window.location.href;t!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=t)}getPayload(){var t;return{library:{name:"@engagepro/analytics",version:"2.0.0"},user:{anonymousId:this.deviceId,id:this.userId},session:{id:this.sessionId,startTime:parseInt(this.sessionId.split("_")[1]||Date.now().toString())},page:{path:"undefined"!=typeof window?window.location.pathname:"",referrer:this.referrer,title:"undefined"!=typeof document?document.title:"",search:"undefined"!=typeof window?window.location.search:"",url:this.currentUrl},network:{online:"undefined"==typeof navigator||navigator.onLine,downlink:null==(t=navigator.connection)?void 0:t.downlink},screen:{width:"undefined"!=typeof screen?screen.width:0,height:"undefined"!=typeof screen?screen.height:0,density:"undefined"!=typeof window?window.devicePixelRatio:1},device:{fingerprint:this.deviceId,type:this.getDeviceType(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"server"},locale:"undefined"!=typeof navigator?navigator.language:"en-US",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone}}getDeviceType(){if("undefined"==typeof navigator)return"desktop";const t=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(t)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(t)?"mobile":"desktop"}}class f{constructor(t){e(this,"queue",[]),e(this,"storage"),e(this,"transport"),e(this,"STORAGE_KEY","engage_queue_v1"),e(this,"isFlushing",!1),e(this,"flushInterval"),e(this,"retryCount",0),this.transport=t,this.storage=new l("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.retryCount=0,this.flush()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flush()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval);const t=3e3*Math.pow(2,this.retryCount);this.flushInterval=setInterval(()=>{this.flush()},Math.min(t,3e4))}enqueue(t){this.queue.push(t),this.save(),(this.queue.length>=10||"PURCHASE"===t.standardEvent)&&this.flush()}save(){this.storage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}load(){const t=this.storage.getItem(this.STORAGE_KEY);if(t)try{this.queue=JSON.parse(t)}catch(e){this.queue=[]}}async flush(){if(0===this.queue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const t=[...this.queue];this.queue=[],this.save();try{if(!(await this.transport.send(t)))throw new Error("Server rejected batch");this.retryCount=0,this.startTimer()}catch(e){this.queue=[...t,...this.queue],this.save(),this.retryCount++,this.startTimer()}finally{this.isFlushing=!1}}}class p{constructor(t){this.apiEndpoint=t}async send(t){const e=JSON.stringify({batch:t,sentAt:(new Date).toISOString()});if("undefined"!=typeof navigator&&navigator.sendBeacon&&e.length<6e4){const t=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(this.apiEndpoint,t))return!0}try{return(await fetch(this.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:e,keepalive:!0})).ok}catch(n){return!1}}}const w="https://engage-api.bluenath.com/api/v1/tracking/ingest",y=new Set(["localhost","127.0.0.1"]);class v{constructor(t){e(this,"config"),e(this,"context"),e(this,"queue"),e(this,"transport"),e(this,"identify",(t,e)=>{this.context.userId=t,this.processEvent({event:"Identify",properties:{traits:e},standardEvent:"LOGIN",intent:"identity",confidence:1})}),e(this,"page",(t,e)=>{const n=this.context.getPayload().page;this.processEvent({event:t||n.title||"Unknown Page",properties:{path:n.path,referrer:n.referrer,title:n.title,...e},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1})}),e(this,"track",(t,e,n)=>{this.processEvent({event:t,properties:e||{},...n})}),e(this,"trackRevenue",(t,e,n)=>{this.track("PURCHASE",{...e||{},value:Math.round(t),valuePaise:Math.round(t)},{standardEvent:"PURCHASE",intent:"commerce",confidence:1,...n})}),this.config=t,this.transport=new p((t=>{if(!t)return w;try{const e=new URL(t);return e.hostname.endsWith("bluenath.com")||y.has(e.hostname)?(e.pathname="/api/v1/tracking/ingest",e.search="",e.hash="",e.toString()):w}catch{return w}})(t.apiHost)),this.context=new u({persistence:t.tracking.useCookies?"cookie":"local"}),this.queue=new f(this.transport)}parseRef(t){if(!t)return{};const e=t.match(/^camp_([^_]+)_cr_([^_]+)$/);return e?{campaignId:e[1],creatorId:e[2]}:{}}processEvent(t){const e=this.context.getPayload(),n=t.properties.ref,i=("string"==typeof n?n:void 0)||new URLSearchParams(e.page.search||"").get("ref")||void 0,s=this.parseRef(i),r=t.properties.valuePaise??t.properties.amountPaise??t.properties.value??t.properties.amount,o=Number(r),a=t.properties.campaignId,c=t.properties.creatorId,h=t.properties.currency,l={event:t.event,properties:t.properties,standardEvent:t.standardEvent,intent:t.intent,confidence:t.confidence,rawLabel:t.rawLabel,timestamp:(new Date).toISOString(),messageId:d(),writeKey:this.config.writeKey,ref:i,campaignId:("string"==typeof a?a:void 0)||s.campaignId,creatorId:("string"==typeof c?c:void 0)||s.creatorId,value:Number.isFinite(o)?Math.round(o):void 0,valuePaise:Number.isFinite(o)?Math.round(o):void 0,currency:("string"==typeof h?h:void 0)||"INR",userId:e.user.id||void 0,anonymousId:e.user.anonymousId,context:e};this.config.debug,this.queue.enqueue(l)}}class m{constructor(t){e(this,"analytics"),e(this,"metrics",{}),this.analytics=t,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(t=>{for(const e of t.getEntries()){const t=e;t.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+t.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries(),n=e[e.length-1];this.metrics.lcp=n.renderTime||n.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries()[0];e&&(this.metrics.fid=e.processingStart-e.startTime,this.logMetric("FID",this.metrics.fid))}).observe({type:"first-input",buffered:!0}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.metrics.cls&&this.logMetric("CLS",this.metrics.cls)})}catch(t){}}logMetric(t,e){e<0||this.analytics.track(`Core Web Vital: ${t}`,{metric:t,value:Math.round(e)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${t}: ${Math.round(e)}ms`})}}const g=i.createContext(null);let b=null;exports.EngageProProvider=({children:t,...e})=>{const s=i.useRef(null),r=i.useRef(null);s.current||(s.current=new v(e),"undefined"!=typeof window&&new m(s.current));const o=s.current;return i.useEffect(()=>{if(!e.tracking.autoTrack)return;const t=t=>{const e=t.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(e){const t=Date.now(),n=r.current;n&&n.el===e&&t-n.ts<500?(n.count++,n.ts=t,3===n.count&&(o.track("Rage Click detected",{element:e.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:e,count:1,ts:t};const i=(t=>{let e=(t.innerText||t.value||t.getAttribute("aria-label")||"").trim();if(!e){const n=t.querySelector("img");n&&n.alt&&(e=n.alt);const i=t.querySelector("title");i&&(e=i.textContent||"")}const n=e.slice(0,100),i=n.toLowerCase(),s=(t.id||"").toLowerCase(),r=t.href||"";return/add to (cart|bag)|buy now/.test(i)||s.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:n,confidence:.9}:/checkout|proceed/.test(i)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:n,confidence:.9}:/place order|pay now/.test(i)||s.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:n,confidence:.95}:/cancel order/.test(i)||s.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:n,confidence:.85}:/refund|return/.test(i)||s.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:n,confidence:.85}:/track package|shipping/.test(i)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:n,confidence:.8}:/write review/.test(i)||i.includes("star")&&/^[1-5]/.test(i)?{standard:"RATE_PRODUCT",intent:"engagement",label:n,confidence:.8}:i.includes("search")||s.includes("search")?{standard:"SEARCH",intent:"search",label:n,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:n,confidence:.5}})(e),s="A"===e.tagName;o.track("Interaction",{element:e.tagName.toLowerCase(),id:e.id,destination:s?e.href:void 0},{standardEvent:i.standard,intent:i.intent,rawLabel:i.label,confidence:i.confidence})}},n=t=>{const e=t.target;(t=>"password"===t.getAttribute("type")||"hidden"===t.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(t.getAttribute("name")||t.id||""))(e)||"focusin"!==t.type||e.dataset.tracked||(e.dataset.tracked="true",o.track("Form Start",{field:e.name||e.id},{standardEvent:"FORM_START",intent:"identity"}))},i=()=>{const t=new URLSearchParams(window.location.search);t.has("q")&&o.track("Search Query",{query:t.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>o.page())},s=history.pushState;return history.pushState=(...t)=>{s.apply(history,t),i()},window.addEventListener("popstate",i),window.addEventListener("click",t,!0),window.addEventListener("focusin",n,!0),i(),()=>{history.pushState=s,window.removeEventListener("popstate",i),window.removeEventListener("click",t,!0),window.removeEventListener("focusin",n,!0)}},[e.tracking.autoTrack]),n.jsx(g.Provider,{value:o,children:t})},exports.default=v,exports.init=t=>(b||(b=new v(t)),b),exports.useAnalytics=()=>{const t=i.useContext(g);if(!t)throw new Error("useAnalytics must be used within EngageProProvider");return t};
|
|
1
|
+
"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);Object.defineProperties(exports,{t:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("react/jsx-runtime"),i=require("react");let s;const r=new Uint8Array(16);function o(){if(!s&&(s="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!s))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return s(r)}const a=[];for(let S=0;S<256;++S)a.push((S+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,n){if(c.randomUUID&&!t)return c.randomUUID();const i=(t=t||{}).random||(t.rng||o)();return i[6]=15&i[6]|64,i[8]=63&i[8]|128,function(t,e=0){return a[t[e+0]]+a[t[e+1]]+a[t[e+2]]+a[t[e+3]]+"-"+a[t[e+4]]+a[t[e+5]]+"-"+a[t[e+6]]+a[t[e+7]]+"-"+a[t[e+8]]+a[t[e+9]]+"-"+a[t[e+10]]+a[t[e+11]]+a[t[e+12]]+a[t[e+13]]+a[t[e+14]]+a[t[e+15]]}(i)}const h=t=>{let e=2166136261;const n=t.length;for(let i=0;i<n;i++)e^=t.charCodeAt(i),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return("0000000"+(e>>>0).toString(16)).substr(-8)};class u{constructor(t="local"){e(this,"memoryStore",{}),e(this,"keyPrefix","engage_"),e(this,"domain"),this.type=t,this.domain=this.getCookieDomain()}getItem(t){const e=this.keyPrefix+t;if(this.memoryStore.hasOwnProperty(e))return this.memoryStore[e];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(e);if("cookie"===this.type&&this.isBrowser())return this.getCookie(e)}catch(n){return null}return null}setItem(t,e){const n=this.keyPrefix+t;this.memoryStore[n]=e;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(n,e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(n,e,365)}catch(i){this.isQuotaError(i)&&(this.type="memory")}}removeItem(t){const e=this.keyPrefix+t;delete this.memoryStore[e];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(e,"",-1)}catch(n){}}getCookie(t){const e=t+"=",n=document.cookie.split(";");for(let i=0;i<n.length;i++){let t=n[i];for(;" "===t.charAt(0);)t=t.substring(1,t.length);if(0===t.indexOf(e))return decodeURIComponent(t.substring(e.length,t.length))}return null}setCookie(t,e,n){let i="";if(n){const t=new Date;t.setTime(t.getTime()+24*n*60*60*1e3),i="; expires="+t.toUTCString()}document.cookie=`${t}=${encodeURIComponent(e)}${i}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const t=window.location.hostname,e=t.split(".");return 1===e.length||"localhost"===t?"":e.length>2?"."+e.slice(-2).join("."):"."+t}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(t){return!1}}isQuotaError(t){return t instanceof DOMException&&(22===t.code||1014===t.code||"QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)}}class l{constructor(t){e(this,"storage"),e(this,"SESSION_TIMEOUT",18e5),e(this,"deviceId"),e(this,"sessionId"),e(this,"userId",null),e(this,"currentUrl"),e(this,"referrer"),this.storage=new u(t.persistence),this.deviceId=this.getOrSetDeviceId(),this.sessionId="",this.manageSession(),"undefined"!=typeof window?(this.currentUrl=window.location.href,this.referrer=document.referrer,this.listenToHistory()):(this.currentUrl="",this.referrer="")}getOrSetDeviceId(){const t=this.storage.getItem("device_id");if(t)return t;const e=(()=>{if("undefined"==typeof window)return"server-side-id";const t=navigator,e=window.screen,n={userAgent:t.userAgent||"",screenRes:`${e.width}x${e.height}`,colorDepth:e.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:t.language||"en-US",platform:t.platform||"unknown",hardwareConcurrency:t.hardwareConcurrency||1,deviceMemory:t.deviceMemory||0},i=[n.platform,n.language,n.screenRes,n.colorDepth,n.timezone,n.hardwareConcurrency,n.deviceMemory].join("|");return`${h(i)}-${h(n.userAgent)}`})();return this.storage.setItem("device_id",e),e}manageSession(){const t=Date.now(),e=this.storage.getItem("session_id"),n=parseInt(this.storage.getItem("last_activity")||"0");if(!e||t-n>this.SESSION_TIMEOUT?(this.sessionId=`sess_${t}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=e,this.storage.setItem("last_activity",t.toString()),"undefined"!=typeof window){const t=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",t),window.addEventListener("scroll",t)}}listenToHistory(){const t=history.pushState;history.pushState=(...e)=>{t.apply(history,e),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const t=window.location.href;t!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=t)}getPayload(){var t;return{library:{name:"@engagepro/analytics",version:"2.0.0"},user:{anonymousId:this.deviceId,id:this.userId},session:{id:this.sessionId,startTime:parseInt(this.sessionId.split("_")[1]||Date.now().toString())},page:{path:"undefined"!=typeof window?window.location.pathname:"",referrer:this.referrer,title:"undefined"!=typeof document?document.title:"",search:"undefined"!=typeof window?window.location.search:"",url:this.currentUrl},network:{online:"undefined"==typeof navigator||navigator.onLine,downlink:null==(t=navigator.connection)?void 0:t.downlink},screen:{width:"undefined"!=typeof screen?screen.width:0,height:"undefined"!=typeof screen?screen.height:0,density:"undefined"!=typeof window?window.devicePixelRatio:1},device:{fingerprint:this.deviceId,type:this.getDeviceType(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"server"},locale:"undefined"!=typeof navigator?navigator.language:"en-US",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone}}getDeviceType(){if("undefined"==typeof navigator)return"desktop";const t=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(t)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(t)?"mobile":"desktop"}}class f{constructor(t){e(this,"queue",[]),e(this,"storage"),e(this,"transport"),e(this,"STORAGE_KEY","engage_queue_v1"),e(this,"isFlushing",!1),e(this,"flushInterval"),e(this,"retryCount",0),this.transport=t,this.storage=new u("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.retryCount=0,this.flush()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flush()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval);const t=3e3*Math.pow(2,this.retryCount);this.flushInterval=setInterval(()=>{this.flush()},Math.min(t,3e4))}enqueue(t){this.queue.push(t),this.save(),(this.queue.length>=10||"PURCHASE"===t.standardEvent)&&this.flush()}save(){this.storage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}load(){const t=this.storage.getItem(this.STORAGE_KEY);if(t)try{this.queue=JSON.parse(t)}catch(e){this.queue=[]}}async flush(){if(0===this.queue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const t=[...this.queue];this.queue=[],this.save();try{if(!(await this.transport.send(t)))throw new Error("Server rejected batch");this.retryCount=0,this.startTimer()}catch(e){this.queue=[...t,...this.queue],this.save(),this.retryCount++,this.startTimer()}finally{this.isFlushing=!1}}}class p{constructor(t){this.apiEndpoint=t}async send(t){const e=JSON.stringify({batch:t,sentAt:(new Date).toISOString()});if("undefined"!=typeof navigator&&navigator.sendBeacon&&e.length<6e4){const t=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(this.apiEndpoint,t))return!0}try{return(await fetch(this.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:e,keepalive:!0})).ok}catch(n){return!1}}}const w="https://engage-api.bluenath.com/api/v1/tracking/ingest",y=new Set(["localhost","127.0.0.1"]),v={$:"USD",US$:"USD",USD:"USD","₹":"INR",RS:"INR","RS.":"INR",INR:"INR","€":"EUR",EUR:"EUR","£":"GBP",GBP:"GBP","¥":"JPY",JPY:"JPY"},m=t=>{if("string"!=typeof t)return;const e=t.trim().toUpperCase();return e?v[e]?v[e]:e.includes("₹")||e.startsWith("RS")?"INR":e.includes("$")&&!e.includes("CAD")?"USD":e.includes("€")?"EUR":e.includes("£")?"GBP":e.includes("¥")?"JPY":/^[A-Z]{3}$/.test(e)?e:void 0:void 0};class g{constructor(t){e(this,"config"),e(this,"context"),e(this,"queue"),e(this,"transport"),e(this,"identify",(t,e)=>{this.context.userId=t,this.processEvent({event:"Identify",properties:{traits:e},standardEvent:"LOGIN",intent:"identity",confidence:1})}),e(this,"page",(t,e)=>{const n=this.context.getPayload().page;this.processEvent({event:t||n.title||"Unknown Page",properties:{path:n.path,referrer:n.referrer,title:n.title,...e},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1})}),e(this,"track",(t,e,n)=>{this.processEvent({event:t,properties:e||{},...n})}),e(this,"trackRevenue",(t,e,n)=>{const i=Math.max(0,(t=>{if("number"==typeof t)return Number.isFinite(t)?t:0;const e=t.trim().replace(/[^0-9.+-]/g,""),n=Number(e);return Number.isFinite(n)?n:0})(t)),s=m(null==e?void 0:e.currency)||m(null==e?void 0:e.currencyCode)||m(null==e?void 0:e.currencySymbol)||("string"==typeof t?m(t):void 0)||"USD";this.track("PURCHASE",{...e||{},value:i,amount:i,valuePaise:Math.round(100*i),amountPaise:Math.round(100*i),currency:s,currencyCode:s},{standardEvent:"PURCHASE",intent:"commerce",confidence:1,...n})}),this.config=t,this.transport=new p((t=>{if(!t)return w;try{const e=new URL(t);return e.hostname.endsWith("bluenath.com")||y.has(e.hostname)?(e.pathname="/api/v1/tracking/ingest",e.search="",e.hash="",e.toString()):w}catch{return w}})(t.apiHost)),this.context=new l({persistence:t.tracking.useCookies?"cookie":"local"}),this.queue=new f(this.transport)}parseRef(t){if(!t)return{};const e=t.match(/^camp_([^_]+)_cr_([^_]+)$/);return e?{campaignId:e[1],creatorId:e[2]}:{}}processEvent(t){const e=this.context.getPayload(),n=t.properties.ref,i=("string"==typeof n?n:void 0)||new URLSearchParams(e.page.search||"").get("ref")||void 0,s=this.parseRef(i),r=t.properties.value??t.properties.amount??t.properties.valuePaise??t.properties.amountPaise,o=Number(r),a=t.properties.campaignId,c=t.properties.creatorId,h=t.properties.currency,u={event:t.event,properties:t.properties,standardEvent:t.standardEvent,intent:t.intent,confidence:t.confidence,rawLabel:t.rawLabel,timestamp:(new Date).toISOString(),messageId:d(),writeKey:this.config.writeKey,ref:i,campaignId:("string"==typeof a?a:void 0)||s.campaignId,creatorId:("string"==typeof c?c:void 0)||s.creatorId,value:Number.isFinite(o)?Math.round(o):void 0,valuePaise:Number.isFinite(o)?Math.round(100*o):void 0,currency:("string"==typeof h?h:void 0)||"USD",userId:e.user.id||void 0,anonymousId:e.user.anonymousId,context:e};this.config.debug,this.queue.enqueue(u)}}class b{constructor(t){e(this,"analytics"),e(this,"metrics",{}),this.analytics=t,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(t=>{for(const e of t.getEntries()){const t=e;t.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+t.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries(),n=e[e.length-1];this.metrics.lcp=n.renderTime||n.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries()[0];e&&(this.metrics.fid=e.processingStart-e.startTime,this.logMetric("FID",this.metrics.fid))}).observe({type:"first-input",buffered:!0}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.metrics.cls&&this.logMetric("CLS",this.metrics.cls)})}catch(t){}}logMetric(t,e){e<0||this.analytics.track(`Core Web Vital: ${t}`,{metric:t,value:Math.round(e)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${t}: ${Math.round(e)}ms`})}}const E=i.createContext(null);let R=null;exports.EngageProProvider=({children:t,...e})=>{const s=i.useRef(null),r=i.useRef(null);s.current||(s.current=new g(e),"undefined"!=typeof window&&new b(s.current));const o=s.current;return i.useEffect(()=>{if(!e.tracking.autoTrack)return;const t=t=>{const e=t.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(e){const t=Date.now(),n=r.current;n&&n.el===e&&t-n.ts<500?(n.count++,n.ts=t,3===n.count&&(o.track("Rage Click detected",{element:e.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:e,count:1,ts:t};const i=(t=>{let e=(t.innerText||t.value||t.getAttribute("aria-label")||"").trim();if(!e){const n=t.querySelector("img");n&&n.alt&&(e=n.alt);const i=t.querySelector("title");i&&(e=i.textContent||"")}const n=e.slice(0,100),i=n.toLowerCase(),s=(t.id||"").toLowerCase(),r=t.href||"";return/add to (cart|bag)|buy now/.test(i)||s.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:n,confidence:.9}:/checkout|proceed/.test(i)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:n,confidence:.9}:/place order|pay now/.test(i)||s.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:n,confidence:.95}:/cancel order/.test(i)||s.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:n,confidence:.85}:/refund|return/.test(i)||s.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:n,confidence:.85}:/track package|shipping/.test(i)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:n,confidence:.8}:/write review/.test(i)||i.includes("star")&&/^[1-5]/.test(i)?{standard:"RATE_PRODUCT",intent:"engagement",label:n,confidence:.8}:i.includes("search")||s.includes("search")?{standard:"SEARCH",intent:"search",label:n,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:n,confidence:.5}})(e),s="A"===e.tagName;o.track("Interaction",{element:e.tagName.toLowerCase(),id:e.id,destination:s?e.href:void 0},{standardEvent:i.standard,intent:i.intent,rawLabel:i.label,confidence:i.confidence})}},n=t=>{const e=t.target;(t=>"password"===t.getAttribute("type")||"hidden"===t.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(t.getAttribute("name")||t.id||""))(e)||"focusin"!==t.type||e.dataset.tracked||(e.dataset.tracked="true",o.track("Form Start",{field:e.name||e.id},{standardEvent:"FORM_START",intent:"identity"}))},i=()=>{const t=new URLSearchParams(window.location.search);t.has("q")&&o.track("Search Query",{query:t.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>o.page())},s=history.pushState;return history.pushState=(...t)=>{s.apply(history,t),i()},window.addEventListener("popstate",i),window.addEventListener("click",t,!0),window.addEventListener("focusin",n,!0),i(),()=>{history.pushState=s,window.removeEventListener("popstate",i),window.removeEventListener("click",t,!0),window.removeEventListener("focusin",n,!0)}},[e.tracking.autoTrack]),n.jsx(E.Provider,{value:o,children:t})},exports.default=g,exports.init=t=>(R||(R=new g(t)),R),exports.useAnalytics=()=>{const t=i.useContext(E);if(!t)throw new Error("useAnalytics must be used within EngageProProvider");return t};
|
package/dist/index.js
CHANGED
|
@@ -408,6 +408,22 @@ class Transport {
|
|
|
408
408
|
const DEFAULT_INGEST_ENDPOINT = "https://engage-api.bluenath.com/api/v1/tracking/ingest";
|
|
409
409
|
const FIXED_INGEST_PATH = "/api/v1/tracking/ingest";
|
|
410
410
|
const ALLOWED_DEV_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
411
|
+
const DEFAULT_CURRENCY = "USD";
|
|
412
|
+
const SYMBOL_TO_CURRENCY = {
|
|
413
|
+
$: "USD",
|
|
414
|
+
US$: "USD",
|
|
415
|
+
USD: "USD",
|
|
416
|
+
"₹": "INR",
|
|
417
|
+
RS: "INR",
|
|
418
|
+
"RS.": "INR",
|
|
419
|
+
INR: "INR",
|
|
420
|
+
"€": "EUR",
|
|
421
|
+
EUR: "EUR",
|
|
422
|
+
"£": "GBP",
|
|
423
|
+
GBP: "GBP",
|
|
424
|
+
"¥": "JPY",
|
|
425
|
+
JPY: "JPY"
|
|
426
|
+
};
|
|
411
427
|
const resolveIngestEndpoint = (apiHost) => {
|
|
412
428
|
if (!apiHost) return DEFAULT_INGEST_ENDPOINT;
|
|
413
429
|
try {
|
|
@@ -427,6 +443,25 @@ const resolveIngestEndpoint = (apiHost) => {
|
|
|
427
443
|
return DEFAULT_INGEST_ENDPOINT;
|
|
428
444
|
}
|
|
429
445
|
};
|
|
446
|
+
const parseCurrencyToken = (value) => {
|
|
447
|
+
if (typeof value !== "string") return void 0;
|
|
448
|
+
const trimmed = value.trim().toUpperCase();
|
|
449
|
+
if (!trimmed) return void 0;
|
|
450
|
+
if (SYMBOL_TO_CURRENCY[trimmed]) return SYMBOL_TO_CURRENCY[trimmed];
|
|
451
|
+
if (trimmed.includes("₹") || trimmed.startsWith("RS")) return "INR";
|
|
452
|
+
if (trimmed.includes("$") && !trimmed.includes("CAD")) return "USD";
|
|
453
|
+
if (trimmed.includes("€")) return "EUR";
|
|
454
|
+
if (trimmed.includes("£")) return "GBP";
|
|
455
|
+
if (trimmed.includes("¥")) return "JPY";
|
|
456
|
+
return /^[A-Z]{3}$/.test(trimmed) ? trimmed : void 0;
|
|
457
|
+
};
|
|
458
|
+
const parseRevenueAmount = (value) => {
|
|
459
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : 0;
|
|
460
|
+
const normalized = value.trim();
|
|
461
|
+
const numeric = normalized.replace(/[^0-9.+-]/g, "");
|
|
462
|
+
const parsed = Number(numeric);
|
|
463
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
464
|
+
};
|
|
430
465
|
class EngagePro {
|
|
431
466
|
constructor(config) {
|
|
432
467
|
__publicField(this, "config");
|
|
@@ -469,13 +504,19 @@ class EngagePro {
|
|
|
469
504
|
...intelligence
|
|
470
505
|
});
|
|
471
506
|
});
|
|
472
|
-
__publicField(this, "trackRevenue", (
|
|
507
|
+
__publicField(this, "trackRevenue", (amount, properties, intelligence) => {
|
|
508
|
+
const parsedAmount = Math.max(0, parseRevenueAmount(amount));
|
|
509
|
+
const currency = parseCurrencyToken(properties == null ? void 0 : properties.currency) || parseCurrencyToken(properties == null ? void 0 : properties.currencyCode) || parseCurrencyToken(properties == null ? void 0 : properties.currencySymbol) || (typeof amount === "string" ? parseCurrencyToken(amount) : void 0) || DEFAULT_CURRENCY;
|
|
473
510
|
this.track(
|
|
474
511
|
"PURCHASE",
|
|
475
512
|
{
|
|
476
513
|
...properties || {},
|
|
477
|
-
value:
|
|
478
|
-
|
|
514
|
+
value: parsedAmount,
|
|
515
|
+
amount: parsedAmount,
|
|
516
|
+
valuePaise: Math.round(parsedAmount * 100),
|
|
517
|
+
amountPaise: Math.round(parsedAmount * 100),
|
|
518
|
+
currency,
|
|
519
|
+
currencyCode: currency
|
|
479
520
|
},
|
|
480
521
|
{
|
|
481
522
|
standardEvent: "PURCHASE",
|
|
@@ -504,7 +545,7 @@ class EngagePro {
|
|
|
504
545
|
const refValue = data.properties.ref;
|
|
505
546
|
const ref = (typeof refValue === "string" ? refValue : void 0) || new URLSearchParams(baseContext.page.search || "").get("ref") || void 0;
|
|
506
547
|
const refParts = this.parseRef(ref);
|
|
507
|
-
const valueCandidate = data.properties.
|
|
548
|
+
const valueCandidate = data.properties.value ?? data.properties.amount ?? data.properties.valuePaise ?? data.properties.amountPaise;
|
|
508
549
|
const value = Number(valueCandidate);
|
|
509
550
|
const campaignIdValue = data.properties.campaignId;
|
|
510
551
|
const creatorIdValue = data.properties.creatorId;
|
|
@@ -525,8 +566,8 @@ class EngagePro {
|
|
|
525
566
|
campaignId: (typeof campaignIdValue === "string" ? campaignIdValue : void 0) || refParts.campaignId,
|
|
526
567
|
creatorId: (typeof creatorIdValue === "string" ? creatorIdValue : void 0) || refParts.creatorId,
|
|
527
568
|
value: Number.isFinite(value) ? Math.round(value) : void 0,
|
|
528
|
-
valuePaise: Number.isFinite(value) ? Math.round(value) : void 0,
|
|
529
|
-
currency: (typeof currencyValue === "string" ? currencyValue : void 0) ||
|
|
569
|
+
valuePaise: Number.isFinite(value) ? Math.round(value * 100) : void 0,
|
|
570
|
+
currency: (typeof currencyValue === "string" ? currencyValue : void 0) || DEFAULT_CURRENCY,
|
|
530
571
|
// Identity
|
|
531
572
|
userId: baseContext.user.id || void 0,
|
|
532
573
|
anonymousId: baseContext.user.anonymousId,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -53,8 +53,13 @@ export interface AnalyticsEvent {
|
|
|
53
53
|
creatorId?: string;
|
|
54
54
|
ref?: string;
|
|
55
55
|
value?: number;
|
|
56
|
+
amount?: number;
|
|
56
57
|
valuePaise?: number;
|
|
58
|
+
amountPaise?: number;
|
|
57
59
|
currency?: string;
|
|
60
|
+
currencyCode?: string;
|
|
61
|
+
currencySymbol?: string;
|
|
62
|
+
baseCurrency?: string;
|
|
58
63
|
context?: Partial<AnalyticsContext>;
|
|
59
64
|
}
|
|
60
65
|
export interface EngageConfig {
|