@carter-rmn/cpix-js 1.0.7 → 1.0.8
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/common/bot-detection.d.ts +23 -0
- package/dist/common/browser.d.ts +7 -0
- package/dist/cpix.cjs +1 -1
- package/dist/cpix.iife.js +1 -1
- package/dist/cpix.js +215 -77
- package/dist/cpix.umd.cjs +1 -1
- package/dist/modules/carter-analytics.d.ts +1 -0
- package/dist/types/common.types.d.ts +28 -0
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bot detection utility to identify automated browsers and bots
|
|
3
|
+
*/
|
|
4
|
+
export default class BotDetection {
|
|
5
|
+
/**
|
|
6
|
+
* Known bot user agent patterns
|
|
7
|
+
*/
|
|
8
|
+
private static readonly BOT_USER_AGENTS;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if the current browser is a bot or automated browser
|
|
11
|
+
* @returns true if bot is detected, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
static isBot(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Checks for missing browser features that indicate automation
|
|
16
|
+
* This is a conservative check to avoid false positives
|
|
17
|
+
*/
|
|
18
|
+
private static hasMissingBrowserFeatures;
|
|
19
|
+
/**
|
|
20
|
+
* Checks for headless browser indicators
|
|
21
|
+
*/
|
|
22
|
+
private static isHeadlessBrowser;
|
|
23
|
+
}
|
package/dist/common/browser.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ import { DeviceNetworkParameters } from '../types/common.types';
|
|
|
2
2
|
|
|
3
3
|
export default class Browser {
|
|
4
4
|
static getBrowserInfo(): string;
|
|
5
|
+
static getBrowserName(): string;
|
|
6
|
+
static getBrowserVersion(): string;
|
|
7
|
+
static getScreenResolution(): string;
|
|
8
|
+
static getViewportSize(): string;
|
|
9
|
+
static getLanguage(): string;
|
|
10
|
+
static getOSVersion(): string;
|
|
11
|
+
static getUserAgent(): string;
|
|
5
12
|
static getDeviceCategory(): string;
|
|
6
13
|
static getDevicePlatform(): string;
|
|
7
14
|
static getDeviceManufacturer(): string;
|
package/dist/cpix.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var y=(l,e,t)=>e in l?w(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var u=(l,e,t)=>(y(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v="@carter-rmn/cpix-js",P="1.0.7",_="module",A=["dist"],T="dist/cpix.umd.cjs",R="dist/cpix.js",I="dist/cpix.d.ts",b={".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},x={dev:"vite",build:"tsc && vite build",preview:"vite preview"},M={picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},U={"vite-plugin-dts":"^3.8.1"},m={name:v,version:P,type:_,files:A,main:T,module:R,types:I,exports:b,scripts:x,devDependencies:M,dependencies:U},a={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:m.version,package:m.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},n={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},O=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const l=()=>a.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){l()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class C extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){o.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){o.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var s,c,p,f,g;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(s=e.match(/chrome\/(\d+)/i))==null?void 0:s[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(p=e.match(/version\/(\d+)/i))==null?void 0:p[1]):/edge/i.test(e)?(t="Edge",i=(f=e.match(/edge\/(\d+)/i))==null?void 0:f[1]):/trident/i.test(e)?(t="Internet Explorer",i=(g=e.match(/rv:(\d+)/i))==null?void 0:g[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${a.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${a.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:a.package,version:a.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return m.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class E{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&s.push(decodeURIComponent(c[2].replace(/\+/g," ")));return s.length>0?s:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class r{static prefix(){return`__${a.TRACKER_FUNC_NAME}__`}static get(e){const t=`${r.prefix()}${e}`,i=document.cookie.split("; ").find(s=>s.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const s=`${r.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${r.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(r.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!r.get(e)}static setUtms(){const e=O;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(h.isPresent(E.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let c=0;c<e.length;c++){const p=e[c];i=E.getParametersByName(p,window.location.href),s.push({[p]:encodeURIComponent(i)})}r.set(n.UTM,JSON.stringify(s),a.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=r.get(n.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!r.exists(n.SESSION))&&r.set(n.SESSION,h.guid(),a.SESSION_EXPIRY_DAYS*24*60),r.setUtms()}}class N{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new C({maxRetries:a.QUEUE_MAX_RETRIES,initialDelay:a.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,a.API_URL=this.instances[0].options.tracker_server_url,a.USER_PROPERTIES=this.instances[0].options.user_properties||{},a.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,a.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},r.exists(n.SESSION)||(r.createSession(),this.sessionCreated=!0);const t=r.get(n.SESSION);if(!r.exists(n.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=r.get(n.META_PARAMETERS);if(i)try{const s=JSON.parse(i);s.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=s}catch(s){o.error("Failed to parse meta parameters, regenerating:",s),this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(r.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");r.exists(n.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(n.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:a.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:a.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...s)=>{e.apply(history,s),i()},history.replaceState=(...s)=>{t.apply(history,s),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=r.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){r.delete(n.SESSION),r.delete(n.META_PARAMETERS),r.createSession(!0);const i=r.get(n.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(s=>{s.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),s.session=i),this.metaParameters=s,r.set(n.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:r.get(n.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),cpix_sdk_version:a.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...a.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=a.version);const t=await fetch(`${a.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.get(n.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(n.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const S=new N;typeof window<"u"&&(window.cpix=S);exports.CarterAnalytics=S;
|
|
1
|
+
"use strict";var v=Object.defineProperty;var y=(l,e,t)=>e in l?v(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var u=(l,e,t)=>(y(l,typeof e!="symbol"?e+"":e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b="@carter-rmn/cpix-js",P="1.0.8",A="module",_=["dist"],U="dist/cpix.umd.cjs",T="dist/cpix.js",x="dist/cpix.d.ts",R={".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},I={dev:"vite",build:"tsc && vite build",preview:"vite preview"},C={picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},M={"vite-plugin-dts":"^3.8.1"},f={name:b,version:P,type:A,files:_,main:U,module:T,types:x,exports:R,scripts:I,devDependencies:C,dependencies:M},a={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:f.version,package:f.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},o={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},k=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],n=function(){const l=()=>a.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){l()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class N extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(n.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){n.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){n.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){n.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){n.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){n.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){n.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var s,c,h,p,w;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(s=e.match(/chrome\/(\d+)/i))==null?void 0:s[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(h=e.match(/version\/(\d+)/i))==null?void 0:h[1]):/edge/i.test(e)?(t="Edge",i=(p=e.match(/edge\/(\d+)/i))==null?void 0:p[1]):/trident/i.test(e)?(t="Internet Explorer",i=(w=e.match(/rv:(\d+)/i))==null?void 0:w[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getBrowserName(){const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t="Chrome":/firefox/i.test(e)?t="Firefox":/safari/i.test(e)&&!/chrome/i.test(e)?t="Safari":/edge/i.test(e)?t="Edge":/trident/i.test(e)?t="Internet Explorer":t="Unknown",t}static getBrowserVersion(){var i,s,c,h,p;const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t=((i=e.match(/chrome\/(\d+)/i))==null?void 0:i[1])||"Unknown":/firefox/i.test(e)?t=((s=e.match(/firefox\/(\d+)/i))==null?void 0:s[1])||"Unknown":/safari/i.test(e)&&!/chrome/i.test(e)?t=((c=e.match(/version\/(\d+)/i))==null?void 0:c[1])||"Unknown":/edge/i.test(e)?t=((h=e.match(/edge\/(\d+)/i))==null?void 0:h[1])||"Unknown":/trident/i.test(e)?t=((p=e.match(/rv:(\d+)/i))==null?void 0:p[1])||"Unknown":t="Unknown",t}static getScreenResolution(){return typeof window>"u"||!window.screen?"Unknown":`${window.screen.width}x${window.screen.height}`}static getViewportSize(){return typeof window>"u"?"Unknown":`${window.innerWidth}x${window.innerHeight}`}static getLanguage(){var e;return typeof navigator>"u"?"Unknown":navigator.language||((e=navigator.languages)==null?void 0:e[0])||"Unknown"}static getOSVersion(){const e=navigator.userAgent||"";let t="Unknown";if(/iphone|ipad|ipod/i.test(e)){const i=e.match(/os (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}else if(/android/i.test(e)){const i=e.match(/android (\d+(\.\d+)?)/i);i&&(t=i[1])}else if(/windows/i.test(e))if(/windows nt 10.0/i.test(e))t="10";else if(/windows nt 6.3/i.test(e))t="8.1";else if(/windows nt 6.2/i.test(e))t="8";else if(/windows nt 6.1/i.test(e))t="7";else{const i=e.match(/windows nt (\d+\.\d+)/i);i&&(t=i[1])}else if(/mac|Macintosh/i.test(e)){const i=e.match(/mac os x (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}return t}static getUserAgent(){return typeof navigator>"u"||!navigator.userAgent?"Unknown":navigator.userAgent}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${a.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return n.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${a.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:a.package,version:a.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw n.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class g{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return f.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return g.isPresent(e)===!1?"":typeof e=="object"?g.optionalData(JSON.stringify(e)):typeof e=="function"?g.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class E{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&s.push(decodeURIComponent(c[2].replace(/\+/g," ")));return s.length>0?s:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class r{static prefix(){return`__${a.TRACKER_FUNC_NAME}__`}static get(e){const t=`${r.prefix()}${e}`,i=document.cookie.split("; ").find(s=>s.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const s=`${r.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${r.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(r.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!r.get(e)}static setUtms(){const e=k;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(g.isPresent(E.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let c=0;c<e.length;c++){const h=e[c];i=E.getParametersByName(h,window.location.href),s.push({[h]:encodeURIComponent(i)})}r.set(o.UTM,JSON.stringify(s),a.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=r.get(o.UTM);return g.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!r.exists(o.SESSION))&&r.set(o.SESSION,g.guid(),a.SESSION_EXPIRY_DAYS*24*60),r.setUtms()}}class m{static isBot(){var i;if(typeof window>"u"||typeof navigator>"u")return!1;if(navigator.webdriver===!0)return n.debug("[CPIX] Bot detected: navigator.webdriver is true"),!0;const e=((i=navigator.userAgent)==null?void 0:i.toLowerCase())||"";return this.BOT_USER_AGENTS.some(s=>e.includes(s.toLowerCase()))?(n.debug("[CPIX] Bot detected: User agent matches bot pattern"),!0):this.hasMissingBrowserFeatures()?(n.debug("[CPIX] Bot detected: Missing browser features"),!0):this.isHeadlessBrowser()?(n.debug("[CPIX] Bot detected: Headless browser indicators"),!0):!1}static hasMissingBrowserFeatures(){const e=typeof navigator.plugins>"u"||navigator.plugins.length===0,t=typeof navigator.languages>"u"||navigator.languages.length===0;return!!(e&&t)}static isHeadlessBrowser(){var e,t;return(e=navigator.userAgent)!=null&&e.includes("HeadlessChrome")||window.outerWidth===0&&window.outerHeight===0&&window.innerWidth===0&&window.innerHeight===0&&(screen.width===0||screen.height===0)?!0:(typeof navigator.permissions>"u"&&((t=navigator.userAgent)!=null&&t.includes("Chrome")),!1)}}u(m,"BOT_USER_AGENTS",["googlebot","bingbot","slurp","duckduckbot","baiduspider","yandexbot","sogou","exabot","facebot","ia_archiver","siteauditbot","semrushbot","ahrefsbot","mj12bot","dotbot","megaindex","blexbot","petalbot","applebot","crawler","spider","scraper","headless","phantom","selenium","webdriver","puppeteer","playwright","chromium","chrome-lighthouse"]);class O{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");u(this,"isBot",!1);if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new N({maxRetries:a.QUEUE_MAX_RETRIES,initialDelay:a.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.isBot=m.isBot(),this.isBot){n.debug("[CPIX] Bot detected - SDK will not track events for this session"),this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,this.initialized=!0;return}this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,a.API_URL=this.instances[0].options.tracker_server_url,a.USER_PROPERTIES=this.instances[0].options.user_properties||{},a.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,a.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},r.exists(o.SESSION)||(r.createSession(),this.sessionCreated=!0);const t=r.get(o.SESSION);if(!r.exists(o.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=r.get(o.META_PARAMETERS);if(i)try{const s=JSON.parse(i);s.session!==t?(n.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=s}catch(s){n.error("Failed to parse meta parameters, regenerating:",s),this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(r.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");r.exists(o.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(o.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,n.debug("CPIX Initialized"),n.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:a.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:a.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...s)=>{e.apply(history,s),i()},history.replaceState=(...s)=>{t.apply(history,s),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");if(this.isBot||m.isBot()){n.debug("[CPIX] Event publishing blocked - bot detected");return}const t={...e,...this.metaParameters};if(t.utm_params=r.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),n.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){r.delete(o.SESSION),r.delete(o.META_PARAMETERS),r.createSession(!0);const i=r.get(o.SESSION);if(!i){n.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(s=>{s.session!==i&&(n.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),s.session=i),this.metaParameters=s,r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:r.get(o.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),browser_name:d.getBrowserName(),browser_version:d.getBrowserVersion(),screen_resolution:d.getScreenResolution(),viewport_size:d.getViewportSize(),language:d.getLanguage(),os_version:d.getOSVersion(),user_agent:d.getUserAgent(),cpix_sdk_version:a.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...a.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=a.version);const t=await fetch(`${a.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.get(o.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(o.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");n.debug("Event published:",t.ok)}catch(t){throw n.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const S=new O;typeof window<"u"&&(window.cpix=S);exports.CarterAnalytics=S;
|
package/dist/cpix.iife.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var tracker=function(l){"use strict";var T=Object.defineProperty;var R=(l,h,p)=>h in l?T(l,h,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[h]=p;var u=(l,h,p)=>(R(l,typeof h!="symbol"?h+"":h,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.7",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,c,g,y,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(y=e.match(/edge\/(\d+)/i))==null?void 0:y[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class d{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return d.isPresent(e)===!1?"":typeof e=="object"?d.optionalData(JSON.stringify(e)):typeof e=="function"?d.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class S{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&r.push(decodeURIComponent(c[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(d.isPresent(S.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let c=0;c<e.length;c++){const g=e[c];i=S.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return d.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!s.exists(a.SESSION))&&s.set(a.SESSION,d.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class A{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0);const t=s.get(a.SESSION);if(!s.exists(a.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440);else{const i=s.get(a.META_PARAMETERS);if(i)try{const r=JSON.parse(i);r.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)):this.metaParameters=r}catch(r){o.error("Failed to parse meta parameters, regenerating:",r),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}else this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}if(s.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(!0);const i=s.get(a.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(r=>{r.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),r.session=i),this.metaParameters=r,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),1440),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const w=new A;return typeof window<"u"&&(window.cpix=w),l.CarterAnalytics=w,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
|
|
1
|
+
var tracker=function(l){"use strict";var U=Object.defineProperty;var T=(l,h,f)=>h in l?U(l,h,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[h]=f;var u=(l,h,f)=>(T(l,typeof h!="symbol"?h+"":h,f),f);const E={name:"@carter-rmn/cpix-js",version:"1.0.8",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},a={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},o={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],n=function(){const m=()=>a.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){m()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class A extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(n.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){n.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){n.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){n.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){n.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){n.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){n.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var s,c,g,w,b;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(s=e.match(/chrome\/(\d+)/i))==null?void 0:s[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(w=e.match(/edge\/(\d+)/i))==null?void 0:w[1]):/trident/i.test(e)?(t="Internet Explorer",i=(b=e.match(/rv:(\d+)/i))==null?void 0:b[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getBrowserName(){const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t="Chrome":/firefox/i.test(e)?t="Firefox":/safari/i.test(e)&&!/chrome/i.test(e)?t="Safari":/edge/i.test(e)?t="Edge":/trident/i.test(e)?t="Internet Explorer":t="Unknown",t}static getBrowserVersion(){var i,s,c,g,w;const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t=((i=e.match(/chrome\/(\d+)/i))==null?void 0:i[1])||"Unknown":/firefox/i.test(e)?t=((s=e.match(/firefox\/(\d+)/i))==null?void 0:s[1])||"Unknown":/safari/i.test(e)&&!/chrome/i.test(e)?t=((c=e.match(/version\/(\d+)/i))==null?void 0:c[1])||"Unknown":/edge/i.test(e)?t=((g=e.match(/edge\/(\d+)/i))==null?void 0:g[1])||"Unknown":/trident/i.test(e)?t=((w=e.match(/rv:(\d+)/i))==null?void 0:w[1])||"Unknown":t="Unknown",t}static getScreenResolution(){return typeof window>"u"||!window.screen?"Unknown":`${window.screen.width}x${window.screen.height}`}static getViewportSize(){return typeof window>"u"?"Unknown":`${window.innerWidth}x${window.innerHeight}`}static getLanguage(){var e;return typeof navigator>"u"?"Unknown":navigator.language||((e=navigator.languages)==null?void 0:e[0])||"Unknown"}static getOSVersion(){const e=navigator.userAgent||"";let t="Unknown";if(/iphone|ipad|ipod/i.test(e)){const i=e.match(/os (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}else if(/android/i.test(e)){const i=e.match(/android (\d+(\.\d+)?)/i);i&&(t=i[1])}else if(/windows/i.test(e))if(/windows nt 10.0/i.test(e))t="10";else if(/windows nt 6.3/i.test(e))t="8.1";else if(/windows nt 6.2/i.test(e))t="8";else if(/windows nt 6.1/i.test(e))t="7";else{const i=e.match(/windows nt (\d+\.\d+)/i);i&&(t=i[1])}else if(/mac|Macintosh/i.test(e)){const i=e.match(/mac os x (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}return t}static getUserAgent(){return typeof navigator>"u"||!navigator.userAgent?"Unknown":navigator.userAgent}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${a.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return n.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${a.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:a.package,version:a.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw n.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class p{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return p.isPresent(e)===!1?"":typeof e=="object"?p.optionalData(JSON.stringify(e)):typeof e=="function"?p.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class v{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&s.push(decodeURIComponent(c[2].replace(/\+/g," ")));return s.length>0?s:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class r{static prefix(){return`__${a.TRACKER_FUNC_NAME}__`}static get(e){const t=`${r.prefix()}${e}`,i=document.cookie.split("; ").find(s=>s.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const s=`${r.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${r.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(r.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!r.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(p.isPresent(v.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let c=0;c<e.length;c++){const g=e[c];i=v.getParametersByName(g,window.location.href),s.push({[g]:encodeURIComponent(i)})}r.set(o.UTM,JSON.stringify(s),a.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=r.get(o.UTM);return p.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!r.exists(o.SESSION))&&r.set(o.SESSION,p.guid(),a.SESSION_EXPIRY_DAYS*24*60),r.setUtms()}}class S{static isBot(){var i;if(typeof window>"u"||typeof navigator>"u")return!1;if(navigator.webdriver===!0)return n.debug("[CPIX] Bot detected: navigator.webdriver is true"),!0;const e=((i=navigator.userAgent)==null?void 0:i.toLowerCase())||"";return this.BOT_USER_AGENTS.some(s=>e.includes(s.toLowerCase()))?(n.debug("[CPIX] Bot detected: User agent matches bot pattern"),!0):this.hasMissingBrowserFeatures()?(n.debug("[CPIX] Bot detected: Missing browser features"),!0):this.isHeadlessBrowser()?(n.debug("[CPIX] Bot detected: Headless browser indicators"),!0):!1}static hasMissingBrowserFeatures(){const e=typeof navigator.plugins>"u"||navigator.plugins.length===0,t=typeof navigator.languages>"u"||navigator.languages.length===0;return!!(e&&t)}static isHeadlessBrowser(){var e,t;return(e=navigator.userAgent)!=null&&e.includes("HeadlessChrome")||window.outerWidth===0&&window.outerHeight===0&&window.innerWidth===0&&window.innerHeight===0&&(screen.width===0||screen.height===0)?!0:(typeof navigator.permissions>"u"&&((t=navigator.userAgent)!=null&&t.includes("Chrome")),!1)}}u(S,"BOT_USER_AGENTS",["googlebot","bingbot","slurp","duckduckbot","baiduspider","yandexbot","sogou","exabot","facebot","ia_archiver","siteauditbot","semrushbot","ahrefsbot","mj12bot","dotbot","megaindex","blexbot","petalbot","applebot","crawler","spider","scraper","headless","phantom","selenium","webdriver","puppeteer","playwright","chromium","chrome-lighthouse"]);class _{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");u(this,"isBot",!1);if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new A({maxRetries:a.QUEUE_MAX_RETRIES,initialDelay:a.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.isBot=S.isBot(),this.isBot){n.debug("[CPIX] Bot detected - SDK will not track events for this session"),this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,this.initialized=!0;return}this.instances=e,a.DEBUG=this.instances[0].options.debug===!0,a.API_URL=this.instances[0].options.tracker_server_url,a.USER_PROPERTIES=this.instances[0].options.user_properties||{},a.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,a.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},r.exists(o.SESSION)||(r.createSession(),this.sessionCreated=!0);const t=r.get(o.SESSION);if(!r.exists(o.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440);else{const i=r.get(o.META_PARAMETERS);if(i)try{const s=JSON.parse(i);s.session!==t?(n.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)):this.metaParameters=s}catch(s){n.error("Failed to parse meta parameters, regenerating:",s),this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}else this.metaParameters=await this.generateMetaParameters(),r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440)}if(r.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");r.exists(o.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(o.ACCESS_TOKEN,this.accessToken,240)),this.initialized=!0,n.debug("CPIX Initialized"),n.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:a.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:a.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...s)=>{e.apply(history,s),i()},history.replaceState=(...s)=>{t.apply(history,s),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");if(this.isBot||S.isBot()){n.debug("[CPIX] Event publishing blocked - bot detected");return}const t={...e,...this.metaParameters};if(t.utm_params=r.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),n.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){r.delete(o.SESSION),r.delete(o.META_PARAMETERS),r.createSession(!0);const i=r.get(o.SESSION);if(!i){n.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(s=>{s.session!==i&&(n.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),s.session=i),this.metaParameters=s,r.set(o.META_PARAMETERS,JSON.stringify(this.metaParameters),1440),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:r.get(o.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),browser_name:d.getBrowserName(),browser_version:d.getBrowserVersion(),screen_resolution:d.getScreenResolution(),viewport_size:d.getViewportSize(),language:d.getLanguage(),os_version:d.getOSVersion(),user_agent:d.getUserAgent(),cpix_sdk_version:a.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...a.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=a.version);const t=await fetch(`${a.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${r.get(o.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),r.set(o.ACCESS_TOKEN,this.accessToken,240)),new Error("[CPIX] Failed to publish event");n.debug("Event published:",t.ok)}catch(t){throw n.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new _;return typeof window<"u"&&(window.cpix=y),l.CarterAnalytics=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l}({});
|
package/dist/cpix.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var u = (l, e, t) => (
|
|
4
|
-
const y = "@carter-rmn/cpix-js",
|
|
1
|
+
var S = Object.defineProperty;
|
|
2
|
+
var v = (l, e, t) => e in l ? S(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
|
|
3
|
+
var u = (l, e, t) => (v(l, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
+
const y = "@carter-rmn/cpix-js", b = "1.0.8", A = "module", P = [
|
|
5
5
|
"dist"
|
|
6
|
-
],
|
|
6
|
+
], _ = "dist/cpix.umd.cjs", U = "dist/cpix.js", x = "dist/cpix.d.ts", R = {
|
|
7
7
|
".": {
|
|
8
8
|
import: "./dist/cpix.js",
|
|
9
9
|
require: "./dist/cpix.umd.cjs"
|
|
10
10
|
}
|
|
11
|
-
},
|
|
11
|
+
}, T = {
|
|
12
12
|
dev: "vite",
|
|
13
13
|
build: "tsc && vite build",
|
|
14
14
|
preview: "vite preview"
|
|
15
|
-
},
|
|
15
|
+
}, I = {
|
|
16
16
|
picocolors: "^1.0.0",
|
|
17
17
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
18
18
|
typescript: "^5.2.2",
|
|
19
19
|
vite: "^5.2.0",
|
|
20
20
|
"vite-plugin-progress": "^0.0.7"
|
|
21
|
-
},
|
|
21
|
+
}, C = {
|
|
22
22
|
"vite-plugin-dts": "^3.8.1"
|
|
23
|
-
},
|
|
23
|
+
}, f = {
|
|
24
24
|
name: y,
|
|
25
|
-
version:
|
|
26
|
-
type:
|
|
27
|
-
files:
|
|
28
|
-
main:
|
|
29
|
-
module:
|
|
30
|
-
types:
|
|
31
|
-
exports:
|
|
32
|
-
scripts:
|
|
33
|
-
devDependencies:
|
|
34
|
-
dependencies:
|
|
25
|
+
version: b,
|
|
26
|
+
type: A,
|
|
27
|
+
files: P,
|
|
28
|
+
main: _,
|
|
29
|
+
module: U,
|
|
30
|
+
types: x,
|
|
31
|
+
exports: R,
|
|
32
|
+
scripts: T,
|
|
33
|
+
devDependencies: I,
|
|
34
|
+
dependencies: C
|
|
35
35
|
}, a = {
|
|
36
36
|
DEBUG: !1,
|
|
37
37
|
TRACKER_FUNC_NAME: "cpix",
|
|
38
38
|
API_URL: "",
|
|
39
39
|
QUEUE_MAX_RETRIES: 3,
|
|
40
40
|
QUEUE_INITIAL_DELAY: 1e4,
|
|
41
|
-
version:
|
|
42
|
-
package:
|
|
41
|
+
version: f.version,
|
|
42
|
+
package: f.name,
|
|
43
43
|
USER_PROPERTIES: {},
|
|
44
44
|
SESSION_EXPIRY_DAYS: 14,
|
|
45
45
|
COMMON_PROPERTIES: {}
|
|
46
|
-
},
|
|
46
|
+
}, o = {
|
|
47
47
|
SESSION: "cpix_session",
|
|
48
48
|
META_PARAMETERS: "cpix_meta_parameters",
|
|
49
49
|
ACCESS_TOKEN: "cpix_access_token",
|
|
@@ -54,7 +54,7 @@ const y = "@carter-rmn/cpix-js", v = "1.0.7", P = "module", _ = [
|
|
|
54
54
|
"utm_term",
|
|
55
55
|
"utm_content",
|
|
56
56
|
"utm_campaign"
|
|
57
|
-
],
|
|
57
|
+
], n = /* @__PURE__ */ function() {
|
|
58
58
|
const l = () => a.DEBUG;
|
|
59
59
|
return {
|
|
60
60
|
info: function(...e) {
|
|
@@ -68,11 +68,11 @@ const y = "@carter-rmn/cpix-js", v = "1.0.7", P = "module", _ = [
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
}();
|
|
71
|
-
class
|
|
71
|
+
class k extends EventTarget {
|
|
72
72
|
constructor(t = {
|
|
73
73
|
maxRetries: 3,
|
|
74
74
|
initialDelay: 1e4,
|
|
75
|
-
consumerHandler: (i) => (
|
|
75
|
+
consumerHandler: (i) => (n.debug("Consuming event:", i), Promise.resolve())
|
|
76
76
|
}) {
|
|
77
77
|
super();
|
|
78
78
|
u(this, "dataQueue");
|
|
@@ -85,7 +85,7 @@ class O extends EventTarget {
|
|
|
85
85
|
this.dataQueue = [], this.retryQueue = [], this.maxRetries = t.maxRetries, this.initialDelay = t.initialDelay, this.handler = t.consumerHandler, this.publishEvent = new Event("eventPublished"), this.retryEvent = new Event("retryMessage"), this.consume(), this.retry();
|
|
86
86
|
}
|
|
87
87
|
publish(t) {
|
|
88
|
-
|
|
88
|
+
n.debug("publishing event");
|
|
89
89
|
const i = {
|
|
90
90
|
data: t,
|
|
91
91
|
id: `${Date.now() + Math.random()}`,
|
|
@@ -95,20 +95,20 @@ class O extends EventTarget {
|
|
|
95
95
|
this.dataQueue.push(i), this.dispatchEvent(this.publishEvent);
|
|
96
96
|
}
|
|
97
97
|
consume() {
|
|
98
|
-
|
|
98
|
+
n.debug("Started Consumer Queue"), this.addEventListener("eventPublished", async () => {
|
|
99
99
|
for (; this.dataQueue.length > 0; ) {
|
|
100
100
|
const t = this.dataQueue.shift(), { data: i = {} } = t;
|
|
101
101
|
try {
|
|
102
102
|
await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
|
|
103
103
|
} catch (s) {
|
|
104
|
-
|
|
104
|
+
n.error("Failed to publish event:", s), this.scheduleRetry(t);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
scheduleRetry(t) {
|
|
110
110
|
if (t.retryCount >= this.maxRetries) {
|
|
111
|
-
|
|
111
|
+
n.error("Max retries reached for message:", t);
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
setTimeout(() => {
|
|
@@ -123,13 +123,13 @@ class O extends EventTarget {
|
|
|
123
123
|
this.dataQueue = this.dataQueue.filter((i) => i.id !== t);
|
|
124
124
|
}
|
|
125
125
|
retry() {
|
|
126
|
-
|
|
126
|
+
n.debug("Started Retry Queue"), this.addEventListener("retryMessage", async () => {
|
|
127
127
|
for (; this.retryQueue.length > 0; ) {
|
|
128
128
|
const t = this.retryQueue.shift(), { data: i = {} } = t;
|
|
129
129
|
try {
|
|
130
130
|
await this.handler(i), this.acknowledge(t == null ? void 0 : t.id);
|
|
131
131
|
} catch (s) {
|
|
132
|
-
|
|
132
|
+
n.error("Failed to publish event:", s), this.scheduleRetry(t);
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
});
|
|
@@ -137,10 +137,62 @@ class O extends EventTarget {
|
|
|
137
137
|
}
|
|
138
138
|
class d {
|
|
139
139
|
static getBrowserInfo() {
|
|
140
|
-
var s, c,
|
|
140
|
+
var s, c, h, p, w;
|
|
141
141
|
const e = navigator.userAgent || "";
|
|
142
142
|
let t, i;
|
|
143
|
-
return /chrome/i.test(e) ? (t = "Chrome", i = (s = e.match(/chrome\/(\d+)/i)) == null ? void 0 : s[1]) : /firefox/i.test(e) ? (t = "Firefox", i = (c = e.match(/firefox\/(\d+)/i)) == null ? void 0 : c[1]) : /safari/i.test(e) ? (t = "Safari", i = (
|
|
143
|
+
return /chrome/i.test(e) ? (t = "Chrome", i = (s = e.match(/chrome\/(\d+)/i)) == null ? void 0 : s[1]) : /firefox/i.test(e) ? (t = "Firefox", i = (c = e.match(/firefox\/(\d+)/i)) == null ? void 0 : c[1]) : /safari/i.test(e) ? (t = "Safari", i = (h = e.match(/version\/(\d+)/i)) == null ? void 0 : h[1]) : /edge/i.test(e) ? (t = "Edge", i = (p = e.match(/edge\/(\d+)/i)) == null ? void 0 : p[1]) : /trident/i.test(e) ? (t = "Internet Explorer", i = (w = e.match(/rv:(\d+)/i)) == null ? void 0 : w[1]) : (t = "Unknown", i = "Unknown"), `${t} ${i}`;
|
|
144
|
+
}
|
|
145
|
+
static getBrowserName() {
|
|
146
|
+
const e = navigator.userAgent || "";
|
|
147
|
+
let t;
|
|
148
|
+
return /chrome/i.test(e) && !/edge/i.test(e) ? t = "Chrome" : /firefox/i.test(e) ? t = "Firefox" : /safari/i.test(e) && !/chrome/i.test(e) ? t = "Safari" : /edge/i.test(e) ? t = "Edge" : /trident/i.test(e) ? t = "Internet Explorer" : t = "Unknown", t;
|
|
149
|
+
}
|
|
150
|
+
static getBrowserVersion() {
|
|
151
|
+
var i, s, c, h, p;
|
|
152
|
+
const e = navigator.userAgent || "";
|
|
153
|
+
let t;
|
|
154
|
+
return /chrome/i.test(e) && !/edge/i.test(e) ? t = ((i = e.match(/chrome\/(\d+)/i)) == null ? void 0 : i[1]) || "Unknown" : /firefox/i.test(e) ? t = ((s = e.match(/firefox\/(\d+)/i)) == null ? void 0 : s[1]) || "Unknown" : /safari/i.test(e) && !/chrome/i.test(e) ? t = ((c = e.match(/version\/(\d+)/i)) == null ? void 0 : c[1]) || "Unknown" : /edge/i.test(e) ? t = ((h = e.match(/edge\/(\d+)/i)) == null ? void 0 : h[1]) || "Unknown" : /trident/i.test(e) ? t = ((p = e.match(/rv:(\d+)/i)) == null ? void 0 : p[1]) || "Unknown" : t = "Unknown", t;
|
|
155
|
+
}
|
|
156
|
+
static getScreenResolution() {
|
|
157
|
+
return typeof window > "u" || !window.screen ? "Unknown" : `${window.screen.width}x${window.screen.height}`;
|
|
158
|
+
}
|
|
159
|
+
static getViewportSize() {
|
|
160
|
+
return typeof window > "u" ? "Unknown" : `${window.innerWidth}x${window.innerHeight}`;
|
|
161
|
+
}
|
|
162
|
+
static getLanguage() {
|
|
163
|
+
var e;
|
|
164
|
+
return typeof navigator > "u" ? "Unknown" : navigator.language || ((e = navigator.languages) == null ? void 0 : e[0]) || "Unknown";
|
|
165
|
+
}
|
|
166
|
+
static getOSVersion() {
|
|
167
|
+
const e = navigator.userAgent || "";
|
|
168
|
+
let t = "Unknown";
|
|
169
|
+
if (/iphone|ipad|ipod/i.test(e)) {
|
|
170
|
+
const i = e.match(/os (\d+[._]\d+)/i);
|
|
171
|
+
i && (t = i[1].replace("_", "."));
|
|
172
|
+
} else if (/android/i.test(e)) {
|
|
173
|
+
const i = e.match(/android (\d+(\.\d+)?)/i);
|
|
174
|
+
i && (t = i[1]);
|
|
175
|
+
} else if (/windows/i.test(e))
|
|
176
|
+
if (/windows nt 10.0/i.test(e))
|
|
177
|
+
t = "10";
|
|
178
|
+
else if (/windows nt 6.3/i.test(e))
|
|
179
|
+
t = "8.1";
|
|
180
|
+
else if (/windows nt 6.2/i.test(e))
|
|
181
|
+
t = "8";
|
|
182
|
+
else if (/windows nt 6.1/i.test(e))
|
|
183
|
+
t = "7";
|
|
184
|
+
else {
|
|
185
|
+
const i = e.match(/windows nt (\d+\.\d+)/i);
|
|
186
|
+
i && (t = i[1]);
|
|
187
|
+
}
|
|
188
|
+
else if (/mac|Macintosh/i.test(e)) {
|
|
189
|
+
const i = e.match(/mac os x (\d+[._]\d+)/i);
|
|
190
|
+
i && (t = i[1].replace("_", "."));
|
|
191
|
+
}
|
|
192
|
+
return t;
|
|
193
|
+
}
|
|
194
|
+
static getUserAgent() {
|
|
195
|
+
return typeof navigator > "u" || !navigator.userAgent ? "Unknown" : navigator.userAgent;
|
|
144
196
|
}
|
|
145
197
|
static getDeviceCategory() {
|
|
146
198
|
const e = navigator.userAgent;
|
|
@@ -167,7 +219,7 @@ class d {
|
|
|
167
219
|
ip_address: t.ip_address || "Unknown"
|
|
168
220
|
};
|
|
169
221
|
} catch (e) {
|
|
170
|
-
return
|
|
222
|
+
return n.error("Error retrieving device network parameters:", e), {
|
|
171
223
|
city: "Unknown",
|
|
172
224
|
region: "Unknown",
|
|
173
225
|
country: "Unknown",
|
|
@@ -194,11 +246,11 @@ class d {
|
|
|
194
246
|
})
|
|
195
247
|
})).json()).accessToken;
|
|
196
248
|
} catch (t) {
|
|
197
|
-
throw
|
|
249
|
+
throw n.error("Error acquiring access token:", t), new Error("[CPIX] Authentication error");
|
|
198
250
|
}
|
|
199
251
|
}
|
|
200
252
|
}
|
|
201
|
-
class
|
|
253
|
+
class g {
|
|
202
254
|
static isPresent(e) {
|
|
203
255
|
return typeof e < "u" && e !== null && e !== "";
|
|
204
256
|
}
|
|
@@ -206,20 +258,20 @@ class h {
|
|
|
206
258
|
return 1 * (/* @__PURE__ */ new Date()).getTime();
|
|
207
259
|
}
|
|
208
260
|
static guid() {
|
|
209
|
-
return
|
|
261
|
+
return f.version + "-xxxxxxxx-".replace(/[x]/g, function(e) {
|
|
210
262
|
const t = Math.random() * 36 | 0;
|
|
211
263
|
return (e == "x" ? t : t & 3 | 8).toString(36);
|
|
212
264
|
}) + (1 * (/* @__PURE__ */ new Date()).getTime()).toString(36);
|
|
213
265
|
}
|
|
214
266
|
// reduces all optional data down to a string
|
|
215
267
|
static optionalData(e) {
|
|
216
|
-
return
|
|
268
|
+
return g.isPresent(e) === !1 ? "" : typeof e == "object" ? g.optionalData(JSON.stringify(e)) : typeof e == "function" ? g.optionalData(e()) : String(e);
|
|
217
269
|
}
|
|
218
270
|
static sleep(e) {
|
|
219
271
|
return new Promise((t) => setTimeout(t, e));
|
|
220
272
|
}
|
|
221
273
|
}
|
|
222
|
-
class
|
|
274
|
+
class E {
|
|
223
275
|
static getParametersByName(e, t) {
|
|
224
276
|
t || (t = window.location.href), e = e.replace(/[[\]]/g, "\\$&");
|
|
225
277
|
const i = new RegExp("[?&]" + e + "(=([^&#]*)|&|#|$)", "gi"), s = [];
|
|
@@ -264,7 +316,7 @@ class r {
|
|
|
264
316
|
let t = !1;
|
|
265
317
|
for (let i = 0; i < e.length; i++) {
|
|
266
318
|
const s = e[i];
|
|
267
|
-
if (
|
|
319
|
+
if (g.isPresent(E.getParametersByName(s, window.location.href))) {
|
|
268
320
|
t = !0;
|
|
269
321
|
break;
|
|
270
322
|
}
|
|
@@ -273,31 +325,99 @@ class r {
|
|
|
273
325
|
let i;
|
|
274
326
|
const s = [];
|
|
275
327
|
for (let c = 0; c < e.length; c++) {
|
|
276
|
-
const
|
|
277
|
-
i =
|
|
278
|
-
[
|
|
328
|
+
const h = e[c];
|
|
329
|
+
i = E.getParametersByName(h, window.location.href), s.push({
|
|
330
|
+
[h]: encodeURIComponent(i)
|
|
279
331
|
});
|
|
280
332
|
}
|
|
281
333
|
r.set(
|
|
282
|
-
|
|
334
|
+
o.UTM,
|
|
283
335
|
JSON.stringify(s),
|
|
284
336
|
a.SESSION_EXPIRY_DAYS * 24 * 60
|
|
285
337
|
);
|
|
286
338
|
}
|
|
287
339
|
}
|
|
288
340
|
static getUtms() {
|
|
289
|
-
const e = r.get(
|
|
290
|
-
return
|
|
341
|
+
const e = r.get(o.UTM);
|
|
342
|
+
return g.isPresent(e) ? JSON.parse(e) : {};
|
|
291
343
|
}
|
|
292
344
|
static createSession(e = !1) {
|
|
293
|
-
(e || !r.exists(
|
|
294
|
-
|
|
295
|
-
|
|
345
|
+
(e || !r.exists(o.SESSION)) && r.set(
|
|
346
|
+
o.SESSION,
|
|
347
|
+
g.guid(),
|
|
296
348
|
a.SESSION_EXPIRY_DAYS * 24 * 60
|
|
297
349
|
), r.setUtms();
|
|
298
350
|
}
|
|
299
351
|
}
|
|
300
|
-
class
|
|
352
|
+
class m {
|
|
353
|
+
/**
|
|
354
|
+
* Checks if the current browser is a bot or automated browser
|
|
355
|
+
* @returns true if bot is detected, false otherwise
|
|
356
|
+
*/
|
|
357
|
+
static isBot() {
|
|
358
|
+
var i;
|
|
359
|
+
if (typeof window > "u" || typeof navigator > "u")
|
|
360
|
+
return !1;
|
|
361
|
+
if (navigator.webdriver === !0)
|
|
362
|
+
return n.debug("[CPIX] Bot detected: navigator.webdriver is true"), !0;
|
|
363
|
+
const e = ((i = navigator.userAgent) == null ? void 0 : i.toLowerCase()) || "";
|
|
364
|
+
return this.BOT_USER_AGENTS.some(
|
|
365
|
+
(s) => e.includes(s.toLowerCase())
|
|
366
|
+
) ? (n.debug("[CPIX] Bot detected: User agent matches bot pattern"), !0) : this.hasMissingBrowserFeatures() ? (n.debug("[CPIX] Bot detected: Missing browser features"), !0) : this.isHeadlessBrowser() ? (n.debug("[CPIX] Bot detected: Headless browser indicators"), !0) : !1;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Checks for missing browser features that indicate automation
|
|
370
|
+
* This is a conservative check to avoid false positives
|
|
371
|
+
*/
|
|
372
|
+
static hasMissingBrowserFeatures() {
|
|
373
|
+
const e = typeof navigator.plugins > "u" || navigator.plugins.length === 0, t = typeof navigator.languages > "u" || navigator.languages.length === 0;
|
|
374
|
+
return !!(e && t);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Checks for headless browser indicators
|
|
378
|
+
*/
|
|
379
|
+
static isHeadlessBrowser() {
|
|
380
|
+
var e, t;
|
|
381
|
+
return (e = navigator.userAgent) != null && e.includes("HeadlessChrome") || window.outerWidth === 0 && window.outerHeight === 0 && window.innerWidth === 0 && window.innerHeight === 0 && // Additional check: if screen dimensions are also zero, it's likely headless
|
|
382
|
+
(screen.width === 0 || screen.height === 0) ? !0 : (typeof navigator.permissions > "u" && ((t = navigator.userAgent) != null && t.includes("Chrome")), !1);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Known bot user agent patterns
|
|
387
|
+
*/
|
|
388
|
+
u(m, "BOT_USER_AGENTS", [
|
|
389
|
+
"googlebot",
|
|
390
|
+
"bingbot",
|
|
391
|
+
"slurp",
|
|
392
|
+
"duckduckbot",
|
|
393
|
+
"baiduspider",
|
|
394
|
+
"yandexbot",
|
|
395
|
+
"sogou",
|
|
396
|
+
"exabot",
|
|
397
|
+
"facebot",
|
|
398
|
+
"ia_archiver",
|
|
399
|
+
"siteauditbot",
|
|
400
|
+
"semrushbot",
|
|
401
|
+
"ahrefsbot",
|
|
402
|
+
"mj12bot",
|
|
403
|
+
"dotbot",
|
|
404
|
+
"megaindex",
|
|
405
|
+
"blexbot",
|
|
406
|
+
"petalbot",
|
|
407
|
+
"applebot",
|
|
408
|
+
"crawler",
|
|
409
|
+
"spider",
|
|
410
|
+
"scraper",
|
|
411
|
+
"headless",
|
|
412
|
+
"phantom",
|
|
413
|
+
"selenium",
|
|
414
|
+
"webdriver",
|
|
415
|
+
"puppeteer",
|
|
416
|
+
"playwright",
|
|
417
|
+
"chromium",
|
|
418
|
+
"chrome-lighthouse"
|
|
419
|
+
]);
|
|
420
|
+
class N {
|
|
301
421
|
constructor() {
|
|
302
422
|
u(this, "instances", []);
|
|
303
423
|
u(this, "initialized", !1);
|
|
@@ -305,11 +425,12 @@ class C {
|
|
|
305
425
|
u(this, "accessToken", "");
|
|
306
426
|
u(this, "metaParameters", {});
|
|
307
427
|
u(this, "queue");
|
|
428
|
+
u(this, "isBot", !1);
|
|
308
429
|
if (!window)
|
|
309
430
|
throw new Error(
|
|
310
431
|
"[CPIX] CarterAnalytics SDK can only be used in a browser environment"
|
|
311
432
|
);
|
|
312
|
-
this.queue = new
|
|
433
|
+
this.queue = new k({
|
|
313
434
|
maxRetries: a.QUEUE_MAX_RETRIES,
|
|
314
435
|
initialDelay: a.QUEUE_INITIAL_DELAY,
|
|
315
436
|
consumerHandler: this.publishEventToServer.bind(this)
|
|
@@ -324,36 +445,42 @@ class C {
|
|
|
324
445
|
throw new Error(
|
|
325
446
|
"[CPIX] At least one instance configuration is required for initialization"
|
|
326
447
|
);
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
448
|
+
if (this.isBot = m.isBot(), this.isBot) {
|
|
449
|
+
n.debug(
|
|
450
|
+
"[CPIX] Bot detected - SDK will not track events for this session"
|
|
451
|
+
), this.instances = e, a.DEBUG = this.instances[0].options.debug === !0, this.initialized = !0;
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
this.instances = e, a.DEBUG = this.instances[0].options.debug === !0, a.API_URL = this.instances[0].options.tracker_server_url, a.USER_PROPERTIES = this.instances[0].options.user_properties || {}, a.SESSION_EXPIRY_DAYS = this.instances[0].options.session_expiry_days || 14, a.COMMON_PROPERTIES = this.instances[0].options.common_properties || {}, r.exists(o.SESSION) || (r.createSession(), this.sessionCreated = !0);
|
|
455
|
+
const t = r.get(o.SESSION);
|
|
456
|
+
if (!r.exists(o.META_PARAMETERS))
|
|
330
457
|
this.metaParameters = await this.generateMetaParameters(), r.set(
|
|
331
|
-
|
|
458
|
+
o.META_PARAMETERS,
|
|
332
459
|
JSON.stringify(this.metaParameters),
|
|
333
460
|
60 * 24
|
|
334
461
|
);
|
|
335
462
|
else {
|
|
336
|
-
const i = r.get(
|
|
463
|
+
const i = r.get(o.META_PARAMETERS);
|
|
337
464
|
if (i)
|
|
338
465
|
try {
|
|
339
466
|
const s = JSON.parse(i);
|
|
340
|
-
s.session !== t ? (
|
|
467
|
+
s.session !== t ? (n.debug(
|
|
341
468
|
"Session ID mismatch detected, regenerating meta parameters"
|
|
342
469
|
), this.metaParameters = await this.generateMetaParameters(), r.set(
|
|
343
|
-
|
|
470
|
+
o.META_PARAMETERS,
|
|
344
471
|
JSON.stringify(this.metaParameters),
|
|
345
472
|
60 * 24
|
|
346
473
|
)) : this.metaParameters = s;
|
|
347
474
|
} catch (s) {
|
|
348
|
-
|
|
349
|
-
|
|
475
|
+
n.error("Failed to parse meta parameters, regenerating:", s), this.metaParameters = await this.generateMetaParameters(), r.set(
|
|
476
|
+
o.META_PARAMETERS,
|
|
350
477
|
JSON.stringify(this.metaParameters),
|
|
351
478
|
60 * 24
|
|
352
479
|
);
|
|
353
480
|
}
|
|
354
481
|
else
|
|
355
482
|
this.metaParameters = await this.generateMetaParameters(), r.set(
|
|
356
|
-
|
|
483
|
+
o.META_PARAMETERS,
|
|
357
484
|
JSON.stringify(this.metaParameters),
|
|
358
485
|
60 * 24
|
|
359
486
|
);
|
|
@@ -364,9 +491,9 @@ class C {
|
|
|
364
491
|
);
|
|
365
492
|
if (!this.metaParameters)
|
|
366
493
|
throw new Error("[CPIX] Meta parameters have not been generated");
|
|
367
|
-
r.exists(
|
|
494
|
+
r.exists(o.ACCESS_TOKEN) || (this.accessToken = await d.aquireAccessToken(
|
|
368
495
|
this.instances[0].client_id
|
|
369
|
-
), r.set(
|
|
496
|
+
), r.set(o.ACCESS_TOKEN, this.accessToken, 60 * 4)), this.initialized = !0, n.debug("CPIX Initialized"), n.debug(
|
|
370
497
|
"Carter Analytics SDK initialized with options:",
|
|
371
498
|
this.instances
|
|
372
499
|
), this.sessionCreated && this.publishInit(), this.attachHistoryListener();
|
|
@@ -409,22 +536,26 @@ class C {
|
|
|
409
536
|
throw new Error(
|
|
410
537
|
"[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events."
|
|
411
538
|
);
|
|
539
|
+
if (this.isBot || m.isBot()) {
|
|
540
|
+
n.debug("[CPIX] Event publishing blocked - bot detected");
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
412
543
|
const t = {
|
|
413
544
|
...e,
|
|
414
545
|
...this.metaParameters
|
|
415
546
|
};
|
|
416
|
-
if (t.utm_params = r.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)),
|
|
417
|
-
r.delete(
|
|
418
|
-
const i = r.get(
|
|
547
|
+
if (t.utm_params = r.getUtms(), document.referrer && (t.referrer = encodeURIComponent(document.referrer)), n.debug("Publishing event:", t), this.queue.publish(t), e.event === "logout") {
|
|
548
|
+
r.delete(o.SESSION), r.delete(o.META_PARAMETERS), r.createSession(!0);
|
|
549
|
+
const i = r.get(o.SESSION);
|
|
419
550
|
if (!i) {
|
|
420
|
-
|
|
551
|
+
n.error("[CPIX] Failed to create new session on logout");
|
|
421
552
|
return;
|
|
422
553
|
}
|
|
423
554
|
this.generateMetaParameters().then((s) => {
|
|
424
|
-
s.session !== i && (
|
|
555
|
+
s.session !== i && (n.error(
|
|
425
556
|
"[CPIX] Session ID mismatch after logout, updating meta parameters"
|
|
426
557
|
), s.session = i), this.metaParameters = s, r.set(
|
|
427
|
-
|
|
558
|
+
o.META_PARAMETERS,
|
|
428
559
|
JSON.stringify(this.metaParameters),
|
|
429
560
|
60 * 24
|
|
430
561
|
), this.publishInit();
|
|
@@ -442,7 +573,7 @@ class C {
|
|
|
442
573
|
const e = await d.getDeviceNetworkParameters();
|
|
443
574
|
return {
|
|
444
575
|
client_id: this.instances[0].client_id,
|
|
445
|
-
session: r.get(
|
|
576
|
+
session: r.get(o.SESSION),
|
|
446
577
|
location: {
|
|
447
578
|
city: e.city,
|
|
448
579
|
region: e.region,
|
|
@@ -455,6 +586,13 @@ class C {
|
|
|
455
586
|
brand: d.getDeviceManufacturer(),
|
|
456
587
|
ip_address: e.ip_address,
|
|
457
588
|
platform: d.getDevicePlatform(),
|
|
589
|
+
browser_name: d.getBrowserName(),
|
|
590
|
+
browser_version: d.getBrowserVersion(),
|
|
591
|
+
screen_resolution: d.getScreenResolution(),
|
|
592
|
+
viewport_size: d.getViewportSize(),
|
|
593
|
+
language: d.getLanguage(),
|
|
594
|
+
os_version: d.getOSVersion(),
|
|
595
|
+
user_agent: d.getUserAgent(),
|
|
458
596
|
cpix_sdk_version: a.version
|
|
459
597
|
},
|
|
460
598
|
referrer: encodeURIComponent(document.referrer)
|
|
@@ -476,21 +614,21 @@ class C {
|
|
|
476
614
|
body: JSON.stringify({ event_data: e }),
|
|
477
615
|
headers: {
|
|
478
616
|
"Content-Type": "application/json",
|
|
479
|
-
Authorization: `Bearer ${r.get(
|
|
617
|
+
Authorization: `Bearer ${r.get(o.ACCESS_TOKEN)}`
|
|
480
618
|
}
|
|
481
619
|
});
|
|
482
620
|
if (!t.ok)
|
|
483
621
|
throw t.status === 401 && (this.accessToken = await d.aquireAccessToken(
|
|
484
622
|
this.instances[0].client_id
|
|
485
|
-
), r.set(
|
|
486
|
-
|
|
623
|
+
), r.set(o.ACCESS_TOKEN, this.accessToken, 60 * 4)), new Error("[CPIX] Failed to publish event");
|
|
624
|
+
n.debug("Event published:", t.ok);
|
|
487
625
|
} catch (t) {
|
|
488
|
-
throw
|
|
626
|
+
throw n.error("Failed to publish event:", t), new Error("[CPIX] Failed to publish event");
|
|
489
627
|
}
|
|
490
628
|
}
|
|
491
629
|
}
|
|
492
|
-
const
|
|
493
|
-
typeof window < "u" && (window.cpix =
|
|
630
|
+
const O = new N();
|
|
631
|
+
typeof window < "u" && (window.cpix = O);
|
|
494
632
|
export {
|
|
495
|
-
|
|
633
|
+
O as CarterAnalytics
|
|
496
634
|
};
|
package/dist/cpix.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(l,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(l=typeof globalThis<"u"?globalThis:l||self,d(l.tracker={}))})(this,function(l){"use strict";var T=Object.defineProperty;var R=(l,d,p)=>d in l?T(l,d,{enumerable:!0,configurable:!0,writable:!0,value:p}):l[d]=p;var u=(l,d,p)=>(R(l,typeof d!="symbol"?d+"":d,p),p);const E={name:"@carter-rmn/cpix-js",version:"1.0.7",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},n={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],o=function(){const f=()=>n.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){f()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class _ extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(o.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){o.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){o.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){o.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){o.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(r){o.error("Failed to publish event:",r),this.scheduleRetry(t)}}})}}class m{static getBrowserInfo(){var r,c,g,y,v;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(r=e.match(/chrome\/(\d+)/i))==null?void 0:r[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(y=e.match(/edge\/(\d+)/i))==null?void 0:y[1]):/trident/i.test(e)?(t="Internet Explorer",i=(v=e.match(/rv:(\d+)/i))==null?void 0:v[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${n.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return o.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${n.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:n.package,version:n.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw o.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class h{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return h.isPresent(e)===!1?"":typeof e=="object"?h.optionalData(JSON.stringify(e)):typeof e=="function"?h.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class S{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),r=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&r.push(decodeURIComponent(c[2].replace(/\+/g," ")));return r.length>0?r:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class s{static prefix(){return`__${n.TRACKER_FUNC_NAME}__`}static get(e){const t=`${s.prefix()}${e}`,i=document.cookie.split("; ").find(r=>r.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const r=`${s.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${r}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${s.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(s.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!s.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const r=e[i];if(h.isPresent(S.getParametersByName(r,window.location.href))){t=!0;break}}if(t){let i;const r=[];for(let c=0;c<e.length;c++){const g=e[c];i=S.getParametersByName(g,window.location.href),r.push({[g]:encodeURIComponent(i)})}s.set(a.UTM,JSON.stringify(r),n.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=s.get(a.UTM);return h.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!s.exists(a.SESSION))&&s.set(a.SESSION,h.guid(),n.SESSION_EXPIRY_DAYS*24*60),s.setUtms()}}class A{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new _({maxRetries:n.QUEUE_MAX_RETRIES,initialDelay:n.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");this.instances=e,n.DEBUG=this.instances[0].options.debug===!0,n.API_URL=this.instances[0].options.tracker_server_url,n.USER_PROPERTIES=this.instances[0].options.user_properties||{},n.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,n.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},s.exists(a.SESSION)||(s.createSession(),this.sessionCreated=!0);const t=s.get(a.SESSION);if(!s.exists(a.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=s.get(a.META_PARAMETERS);if(i)try{const r=JSON.parse(i);r.session!==t?(o.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=r}catch(r){o.error("Failed to parse meta parameters, regenerating:",r),this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(s.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");s.exists(a.ACCESS_TOKEN)||(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,o.debug("CPIX Initialized"),o.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:n.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:n.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...r)=>{e.apply(history,r),i()},history.replaceState=(...r)=>{t.apply(history,r),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");const t={...e,...this.metaParameters};if(t.utm_params=s.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),o.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){s.delete(a.SESSION),s.delete(a.META_PARAMETERS),s.createSession(!0);const i=s.get(a.SESSION);if(!i){o.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(r=>{r.session!==i&&(o.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),r.session=i),this.metaParameters=r,s.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await m.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:s.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:m.getDeviceCategory(),brand:m.getDeviceManufacturer(),ip_address:e.ip_address,platform:m.getDevicePlatform(),cpix_sdk_version:n.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...n.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=n.version);const t=await fetch(`${n.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await m.aquireAccessToken(this.instances[0].client_id),s.set(a.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");o.debug("Event published:",t.ok)}catch(t){throw o.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const w=new A;typeof window<"u"&&(window.cpix=w),l.CarterAnalytics=w,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(l,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(l=typeof globalThis<"u"?globalThis:l||self,h(l.tracker={}))})(this,function(l){"use strict";var x=Object.defineProperty;var T=(l,h,f)=>h in l?x(l,h,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[h]=f;var u=(l,h,f)=>(T(l,typeof h!="symbol"?h+"":h,f),f);const E={name:"@carter-rmn/cpix-js",version:"1.0.8",type:"module",files:["dist"],main:"dist/cpix.umd.cjs",module:"dist/cpix.js",types:"dist/cpix.d.ts",exports:{".":{import:"./dist/cpix.js",require:"./dist/cpix.umd.cjs"}},scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview"},devDependencies:{picocolors:"^1.0.0","rollup-plugin-visualizer":"^5.12.0",typescript:"^5.2.2",vite:"^5.2.0","vite-plugin-progress":"^0.0.7"},dependencies:{"vite-plugin-dts":"^3.8.1"}},o={DEBUG:!1,TRACKER_FUNC_NAME:"cpix",API_URL:"",QUEUE_MAX_RETRIES:3,QUEUE_INITIAL_DELAY:1e4,version:E.version,package:E.name,USER_PROPERTIES:{},SESSION_EXPIRY_DAYS:14,COMMON_PROPERTIES:{}},a={SESSION:"cpix_session",META_PARAMETERS:"cpix_meta_parameters",ACCESS_TOKEN:"cpix_access_token",UTM:"cpix_utm"},P=["utm_source","utm_medium","utm_term","utm_content","utm_campaign"],r=function(){const m=()=>o.DEBUG;return{info:function(...e){console.log(...e)},debug:function(...e){m()&&console.log(...e)},error:function(...e){console.error(...e)}}}();class A extends EventTarget{constructor(t={maxRetries:3,initialDelay:1e4,consumerHandler:i=>(r.debug("Consuming event:",i),Promise.resolve())}){super();u(this,"dataQueue");u(this,"retryQueue");u(this,"maxRetries");u(this,"initialDelay");u(this,"publishEvent");u(this,"retryEvent");u(this,"handler");this.dataQueue=[],this.retryQueue=[],this.maxRetries=t.maxRetries,this.initialDelay=t.initialDelay,this.handler=t.consumerHandler,this.publishEvent=new Event("eventPublished"),this.retryEvent=new Event("retryMessage"),this.consume(),this.retry()}publish(t){r.debug("publishing event");const i={data:t,id:`${Date.now()+Math.random()}`,retryCount:0,retryDelay:this.initialDelay};this.dataQueue.push(i),this.dispatchEvent(this.publishEvent)}consume(){r.debug("Started Consumer Queue"),this.addEventListener("eventPublished",async()=>{for(;this.dataQueue.length>0;){const t=this.dataQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){r.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}scheduleRetry(t){if(t.retryCount>=this.maxRetries){r.error("Max retries reached for message:",t);return}setTimeout(()=>{this.retryQueue.push({...t,retryCount:t.retryCount+1,retryDelay:t.retryDelay*2}),this.dispatchEvent(this.retryEvent)},t.retryDelay)}acknowledge(t){this.dataQueue=this.dataQueue.filter(i=>i.id!==t)}retry(){r.debug("Started Retry Queue"),this.addEventListener("retryMessage",async()=>{for(;this.retryQueue.length>0;){const t=this.retryQueue.shift(),{data:i={}}=t;try{await this.handler(i),this.acknowledge(t==null?void 0:t.id)}catch(s){r.error("Failed to publish event:",s),this.scheduleRetry(t)}}})}}class d{static getBrowserInfo(){var s,c,g,w,b;const e=navigator.userAgent||"";let t,i;return/chrome/i.test(e)?(t="Chrome",i=(s=e.match(/chrome\/(\d+)/i))==null?void 0:s[1]):/firefox/i.test(e)?(t="Firefox",i=(c=e.match(/firefox\/(\d+)/i))==null?void 0:c[1]):/safari/i.test(e)?(t="Safari",i=(g=e.match(/version\/(\d+)/i))==null?void 0:g[1]):/edge/i.test(e)?(t="Edge",i=(w=e.match(/edge\/(\d+)/i))==null?void 0:w[1]):/trident/i.test(e)?(t="Internet Explorer",i=(b=e.match(/rv:(\d+)/i))==null?void 0:b[1]):(t="Unknown",i="Unknown"),`${t} ${i}`}static getBrowserName(){const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t="Chrome":/firefox/i.test(e)?t="Firefox":/safari/i.test(e)&&!/chrome/i.test(e)?t="Safari":/edge/i.test(e)?t="Edge":/trident/i.test(e)?t="Internet Explorer":t="Unknown",t}static getBrowserVersion(){var i,s,c,g,w;const e=navigator.userAgent||"";let t;return/chrome/i.test(e)&&!/edge/i.test(e)?t=((i=e.match(/chrome\/(\d+)/i))==null?void 0:i[1])||"Unknown":/firefox/i.test(e)?t=((s=e.match(/firefox\/(\d+)/i))==null?void 0:s[1])||"Unknown":/safari/i.test(e)&&!/chrome/i.test(e)?t=((c=e.match(/version\/(\d+)/i))==null?void 0:c[1])||"Unknown":/edge/i.test(e)?t=((g=e.match(/edge\/(\d+)/i))==null?void 0:g[1])||"Unknown":/trident/i.test(e)?t=((w=e.match(/rv:(\d+)/i))==null?void 0:w[1])||"Unknown":t="Unknown",t}static getScreenResolution(){return typeof window>"u"||!window.screen?"Unknown":`${window.screen.width}x${window.screen.height}`}static getViewportSize(){return typeof window>"u"?"Unknown":`${window.innerWidth}x${window.innerHeight}`}static getLanguage(){var e;return typeof navigator>"u"?"Unknown":navigator.language||((e=navigator.languages)==null?void 0:e[0])||"Unknown"}static getOSVersion(){const e=navigator.userAgent||"";let t="Unknown";if(/iphone|ipad|ipod/i.test(e)){const i=e.match(/os (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}else if(/android/i.test(e)){const i=e.match(/android (\d+(\.\d+)?)/i);i&&(t=i[1])}else if(/windows/i.test(e))if(/windows nt 10.0/i.test(e))t="10";else if(/windows nt 6.3/i.test(e))t="8.1";else if(/windows nt 6.2/i.test(e))t="8";else if(/windows nt 6.1/i.test(e))t="7";else{const i=e.match(/windows nt (\d+\.\d+)/i);i&&(t=i[1])}else if(/mac|Macintosh/i.test(e)){const i=e.match(/mac os x (\d+[._]\d+)/i);i&&(t=i[1].replace("_","."))}return t}static getUserAgent(){return typeof navigator>"u"||!navigator.userAgent?"Unknown":navigator.userAgent}static getDeviceCategory(){const e=navigator.userAgent;return/mobile/i.test(e)?"Mobile":/tablet/i.test(e)?"Tablet":"Desktop"}static getDevicePlatform(){const e=navigator.userAgent;return/android/i.test(e)?"Android":/iphone|ipad|ipod/i.test(e)?"iOS":/windows phone/i.test(e)?"Windows Phone":/mac|Macintosh/i.test(e)?"Mac":/windows|Microsoft/i.test(e)?"Windows":/linux/i.test(e)?"Linux":"Unknown"}static getDeviceManufacturer(){const e=navigator.userAgent;let t;return/iphone|ipad|ipod|mac|Macintosh/i.test(e)?t="Apple":/samsung/i.test(e)?t="Samsung":/google/i.test(e)?t="Google":/huawei/i.test(e)?t="Huawei":/xiaomi/i.test(e)?t="Xiaomi":/oneplus/i.test(e)?t="OnePlus":/dell/i.test(e)?t="Dell":/lenovo/i.test(e)?t="Lenovo":/acer/i.test(e)?t="Acer":/asus/i.test(e)?t="Asus":/toshiba/i.test(e)?t="Toshiba":t="Unknown",t}static async getDeviceNetworkParameters(){try{const e=await fetch(`${o.API_URL}/api/geolocation`),{data:t}=await e.json();return{city:t.city||"Unknown",region:t.region||"Unknown",country:t.country||"Unknown",timezone:t.timezone||"Unknown",loc:t.loc||"Unknown",ip_address:t.ip_address||"Unknown"}}catch(e){return r.error("Error retrieving device network parameters:",e),{city:"Unknown",region:"Unknown",country:"Unknown",timezone:"Unknown",loc:"Unknown",ip_address:"Unknown"}}}static async aquireAccessToken(e){try{return(await(await fetch(`${o.API_URL}/api/authenticate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accountId:e,metadata:{sdk:o.package,version:o.version,hostname:window.location.hostname}})})).json()).accessToken}catch(t){throw r.error("Error acquiring access token:",t),new Error("[CPIX] Authentication error")}}}class p{static isPresent(e){return typeof e<"u"&&e!==null&&e!==""}static now(){return 1*new Date().getTime()}static guid(){return E.version+"-xxxxxxxx-".replace(/[x]/g,function(e){const t=Math.random()*36|0;return(e=="x"?t:t&3|8).toString(36)})+(1*new Date().getTime()).toString(36)}static optionalData(e){return p.isPresent(e)===!1?"":typeof e=="object"?p.optionalData(JSON.stringify(e)):typeof e=="function"?p.optionalData(e()):String(e)}static sleep(e){return new Promise(t=>setTimeout(t,e))}}class v{static getParametersByName(e,t){t||(t=window.location.href),e=e.replace(/[[\]]/g,"\\$&");const i=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)","gi"),s=[];let c;for(;(c=i.exec(t))!==null;)c[2]&&s.push(decodeURIComponent(c[2].replace(/\+/g," ")));return s.length>0?s:null}static externalHost(e){var t;return e.hostname!=location.hostname&&((t=e==null?void 0:e.protocol)==null?void 0:t.indexOf("http"))===0}}class n{static prefix(){return`__${o.TRACKER_FUNC_NAME}__`}static get(e){const t=`${n.prefix()}${e}`,i=document.cookie.split("; ").find(s=>s.startsWith(`${t}=`));return i?i.split("=")[1]:void 0}static set(e,t,i){const s=`${n.prefix()}${e}`,c=new Date;c.setTime(c.getTime()+i*60*1e3),document.cookie=`${s}=${t}; expires=${c.toUTCString()}; path=/`}static delete(e){const t=`${n.prefix()}${e}`;document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`}static clear(){document.cookie.split("; ").filter(e=>e.startsWith(n.prefix())).forEach(e=>{const t=e.split("=")[0];document.cookie=`${t}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`})}static exists(e){return!!n.get(e)}static setUtms(){const e=P;let t=!1;for(let i=0;i<e.length;i++){const s=e[i];if(p.isPresent(v.getParametersByName(s,window.location.href))){t=!0;break}}if(t){let i;const s=[];for(let c=0;c<e.length;c++){const g=e[c];i=v.getParametersByName(g,window.location.href),s.push({[g]:encodeURIComponent(i)})}n.set(a.UTM,JSON.stringify(s),o.SESSION_EXPIRY_DAYS*24*60)}}static getUtms(){const e=n.get(a.UTM);return p.isPresent(e)?JSON.parse(e):{}}static createSession(e=!1){(e||!n.exists(a.SESSION))&&n.set(a.SESSION,p.guid(),o.SESSION_EXPIRY_DAYS*24*60),n.setUtms()}}class S{static isBot(){var i;if(typeof window>"u"||typeof navigator>"u")return!1;if(navigator.webdriver===!0)return r.debug("[CPIX] Bot detected: navigator.webdriver is true"),!0;const e=((i=navigator.userAgent)==null?void 0:i.toLowerCase())||"";return this.BOT_USER_AGENTS.some(s=>e.includes(s.toLowerCase()))?(r.debug("[CPIX] Bot detected: User agent matches bot pattern"),!0):this.hasMissingBrowserFeatures()?(r.debug("[CPIX] Bot detected: Missing browser features"),!0):this.isHeadlessBrowser()?(r.debug("[CPIX] Bot detected: Headless browser indicators"),!0):!1}static hasMissingBrowserFeatures(){const e=typeof navigator.plugins>"u"||navigator.plugins.length===0,t=typeof navigator.languages>"u"||navigator.languages.length===0;return!!(e&&t)}static isHeadlessBrowser(){var e,t;return(e=navigator.userAgent)!=null&&e.includes("HeadlessChrome")||window.outerWidth===0&&window.outerHeight===0&&window.innerWidth===0&&window.innerHeight===0&&(screen.width===0||screen.height===0)?!0:(typeof navigator.permissions>"u"&&((t=navigator.userAgent)!=null&&t.includes("Chrome")),!1)}}u(S,"BOT_USER_AGENTS",["googlebot","bingbot","slurp","duckduckbot","baiduspider","yandexbot","sogou","exabot","facebot","ia_archiver","siteauditbot","semrushbot","ahrefsbot","mj12bot","dotbot","megaindex","blexbot","petalbot","applebot","crawler","spider","scraper","headless","phantom","selenium","webdriver","puppeteer","playwright","chromium","chrome-lighthouse"]);class _{constructor(){u(this,"instances",[]);u(this,"initialized",!1);u(this,"sessionCreated",!1);u(this,"accessToken","");u(this,"metaParameters",{});u(this,"queue");u(this,"isBot",!1);if(!window)throw new Error("[CPIX] CarterAnalytics SDK can only be used in a browser environment");this.queue=new A({maxRetries:o.QUEUE_MAX_RETRIES,initialDelay:o.QUEUE_INITIAL_DELAY,consumerHandler:this.publishEventToServer.bind(this)})}async initialize(e){if(!e||e.length===0)throw new Error("[CPIX] At least one instance configuration is required for initialization");if(this.isBot=S.isBot(),this.isBot){r.debug("[CPIX] Bot detected - SDK will not track events for this session"),this.instances=e,o.DEBUG=this.instances[0].options.debug===!0,this.initialized=!0;return}this.instances=e,o.DEBUG=this.instances[0].options.debug===!0,o.API_URL=this.instances[0].options.tracker_server_url,o.USER_PROPERTIES=this.instances[0].options.user_properties||{},o.SESSION_EXPIRY_DAYS=this.instances[0].options.session_expiry_days||14,o.COMMON_PROPERTIES=this.instances[0].options.common_properties||{},n.exists(a.SESSION)||(n.createSession(),this.sessionCreated=!0);const t=n.get(a.SESSION);if(!n.exists(a.META_PARAMETERS))this.metaParameters=await this.generateMetaParameters(),n.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24);else{const i=n.get(a.META_PARAMETERS);if(i)try{const s=JSON.parse(i);s.session!==t?(r.debug("Session ID mismatch detected, regenerating meta parameters"),this.metaParameters=await this.generateMetaParameters(),n.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)):this.metaParameters=s}catch(s){r.error("Failed to parse meta parameters, regenerating:",s),this.metaParameters=await this.generateMetaParameters(),n.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}else this.metaParameters=await this.generateMetaParameters(),n.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24)}if(n.setUtms(),this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has already been initialized");if(!this.metaParameters)throw new Error("[CPIX] Meta parameters have not been generated");n.exists(a.ACCESS_TOKEN)||(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),n.set(a.ACCESS_TOKEN,this.accessToken,60*4)),this.initialized=!0,r.debug("CPIX Initialized"),r.debug("Carter Analytics SDK initialized with options:",this.instances),this.sessionCreated&&this.publishInit(),this.attachHistoryListener()}publishInit(){this.publish({event:"init",user_properties:o.USER_PROPERTIES,...this.metaParameters})}attachHistoryListener(){const e=history.pushState,t=history.replaceState,i=()=>{this.publish({event:"page_view",event_properties:{title:document.title,page:window.location.pathname,url:window.location.href},user_properties:o.USER_PROPERTIES,...this.metaParameters})};history.pushState=(...s)=>{e.apply(history,s),i()},history.replaceState=(...s)=>{t.apply(history,s),i()},window.addEventListener("popstate",i),i()}publish(e){if(!this.initialized)throw new Error("[CPIX] CarterAnalytics SDK has not been initialized. Please initialize before publishing events.");if(this.isBot||S.isBot()){r.debug("[CPIX] Event publishing blocked - bot detected");return}const t={...e,...this.metaParameters};if(t.utm_params=n.getUtms(),document.referrer&&(t.referrer=encodeURIComponent(document.referrer)),r.debug("Publishing event:",t),this.queue.publish(t),e.event==="logout"){n.delete(a.SESSION),n.delete(a.META_PARAMETERS),n.createSession(!0);const i=n.get(a.SESSION);if(!i){r.error("[CPIX] Failed to create new session on logout");return}this.generateMetaParameters().then(s=>{s.session!==i&&(r.error("[CPIX] Session ID mismatch after logout, updating meta parameters"),s.session=i),this.metaParameters=s,n.set(a.META_PARAMETERS,JSON.stringify(this.metaParameters),60*24),this.publishInit()})}}async generateMetaParameters(){if(!window)throw new Error("[CPIX] Meta parameters can only be generated in a browser environment");const e=await d.getDeviceNetworkParameters();return{client_id:this.instances[0].client_id,session:n.get(a.SESSION),location:{city:e.city,region:e.region,loc:e.loc,timezone:e.timezone,country:e.country},device:{category:d.getDeviceCategory(),brand:d.getDeviceManufacturer(),ip_address:e.ip_address,platform:d.getDevicePlatform(),browser_name:d.getBrowserName(),browser_version:d.getBrowserVersion(),screen_resolution:d.getScreenResolution(),viewport_size:d.getViewportSize(),language:d.getLanguage(),os_version:d.getOSVersion(),user_agent:d.getUserAgent(),cpix_sdk_version:o.version},referrer:encodeURIComponent(document.referrer)}}async publishEventToServer(e){try{e.timestamp=Date.now(),e.event_properties={url:window.location.href,...o.COMMON_PROPERTIES,...e.event_properties},e.device&&(e.device.cpix_sdk_version=o.version);const t=await fetch(`${o.API_URL}/api/event`,{method:"POST",body:JSON.stringify({event_data:e}),headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.get(a.ACCESS_TOKEN)}`}});if(!t.ok)throw t.status===401&&(this.accessToken=await d.aquireAccessToken(this.instances[0].client_id),n.set(a.ACCESS_TOKEN,this.accessToken,60*4)),new Error("[CPIX] Failed to publish event");r.debug("Event published:",t.ok)}catch(t){throw r.error("Failed to publish event:",t),new Error("[CPIX] Failed to publish event")}}}const y=new _;typeof window<"u"&&(window.cpix=y),l.CarterAnalytics=y,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -82,6 +82,34 @@ export interface Device {
|
|
|
82
82
|
* The platform of the device.
|
|
83
83
|
*/
|
|
84
84
|
platform: string;
|
|
85
|
+
/**
|
|
86
|
+
* The browser name.
|
|
87
|
+
*/
|
|
88
|
+
browser_name?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The browser version.
|
|
91
|
+
*/
|
|
92
|
+
browser_version?: string;
|
|
93
|
+
/**
|
|
94
|
+
* The screen resolution (width x height).
|
|
95
|
+
*/
|
|
96
|
+
screen_resolution?: string;
|
|
97
|
+
/**
|
|
98
|
+
* The viewport size (width x height).
|
|
99
|
+
*/
|
|
100
|
+
viewport_size?: string;
|
|
101
|
+
/**
|
|
102
|
+
* The language of the browser.
|
|
103
|
+
*/
|
|
104
|
+
language?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The OS version (if detectable).
|
|
107
|
+
*/
|
|
108
|
+
os_version?: string;
|
|
109
|
+
/**
|
|
110
|
+
* The user agent string.
|
|
111
|
+
*/
|
|
112
|
+
user_agent?: string;
|
|
85
113
|
/**
|
|
86
114
|
* The SDK version.
|
|
87
115
|
*/
|