@deriv-com/analytics 1.42.0 → 1.42.1

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.
@@ -1,2 +1,2 @@
1
- export { P as Posthog } from '../../posthog-ctBaPjWr.mjs';
1
+ export { P as Posthog } from '../../posthog-DmVmqDsn.mjs';
2
2
  import 'posthog-js';
@@ -1,2 +1,2 @@
1
- export { P as Posthog } from '../../posthog-ctBaPjWr.js';
1
+ export { P as Posthog } from '../../posthog-DmVmqDsn.js';
2
2
  import 'posthog-js';
@@ -1,3 +1,3 @@
1
- 'use strict';var chunkT4BXL6JM_js=require('../../chunk-T4BXL6JM.js'),r=require('posthog-js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var r__default=/*#__PURE__*/_interopDefault(r);/* @deriv-com/analytics - NPM Package - Built with tsup */
2
- var g=class g{constructor(e,t=false){this.has_initialized=false;this.has_identified=false;this.debug=false;this.log=chunkT4BXL6JM_js.f("[PostHog]",()=>this.debug);this.cleanupStalePosthogCookies=e=>{if(typeof document>"u"||typeof window>"u")return;let t=`ph_${e}_posthog`,o=document.cookie.split(";").map(i=>i.trim().split("=")[0]??"").filter(i=>/^ph_.+_posthog$/.test(i)&&i!==t);if(o.length===0)return;let a=window.location.hostname,n=a.split("."),s=n.length>=2?`.${n.slice(-2).join(".")}`:a;o.forEach(i=>{[s,a,""].forEach(l=>{let F=l?`; Domain=${l}`:"";document.cookie=`${i}=; path=/${F}; max-age=0; SameSite=Lax`;});let d=!document.cookie.split(";").some(l=>l.trim().startsWith(`${i}=`));this.log(`cleanupStalePosthogCookies | ${d?"removed":"failed to remove"} stale cookie: ${i}`);});};this.init=()=>{try{let{apiKey:e,api_host:t,config:o={}}=this.options;if(!e){console.warn("Posthog: No API key provided");return}this.cleanupStalePosthogCookies(e);let a=t||chunkT4BXL6JM_js.d();this.log("init | loading PostHog SDK",{api_host:a});let n={api_host:a,ui_host:chunkT4BXL6JM_js.c,autocapture:!0,capture_pageview:"history_change",session_recording:{recordCrossOriginIframes:!0,minimumDurationMilliseconds:3e4,maskAllInputs:!0,...o.session_recording},before_send:s=>{if(typeof window>"u")return null;let i=window.location.hostname;if(i==="localhost"||i==="127.0.0.1")return s;let d=chunkT4BXL6JM_js.e.some(l=>i.endsWith(`.${l}`)||i===l);return d||this.log("init | before_send blocked event from disallowed host",{currentHost:i}),d?s:null},...o};r__default.default.init(e,n),this.has_initialized=!0,this.log("init | PostHog SDK loaded successfully");}catch(e){console.error("Posthog: Failed to initialize",e);}};this.identifyEvent=(e,t={})=>{if(!this.has_initialized){console.warn("Posthog: Cannot identify - not initialized");return}try{let o=this.has_identified&&r__default.default.get_distinct_id()===e;e&&!o?(this.log("identifyEvent | identifying user",{user_id:e,traits:t}),r__default.default.identify(e,{...t,client_id:e}),this.has_identified=!0):this.log("identifyEvent | skipped \u2014 user already identified",{user_id:e});}catch(o){console.error("Posthog: Failed to identify user",o);}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting PostHog session"),r__default.default.reset(),this.has_identified=!1;}catch(e){console.error("Posthog: Failed to reset",e);}};this.backfillPersonProperties=({user_id:e,email:t,language:o,country_of_residence:a})=>{if(!(!this.has_initialized||!e))try{let n=r__default.default.get_property("$stored_person_properties")??{},s={};n.client_id||(s.client_id=e),t&&n.is_internal===void 0&&(s.is_internal=chunkT4BXL6JM_js.g(t)),o&&!n.language&&(s.language=o),a&&!n.country_of_residence&&(s.country_of_residence=a),Object.keys(s).length>0?(this.log("backfillPersonProperties | backfilling person properties",{user_id:e,updates:s}),r__default.default.setPersonProperties(s)):this.log("backfillPersonProperties | skipped \u2014 all properties already present",{user_id:e,country_of_residence:a});}catch(n){console.error("Posthog: Failed to backfill person properties",n);}};this.capture=(e,t)=>{if(this.has_initialized)try{this.log("capture | sending event to PostHog",{event_name:e,properties:t}),r__default.default.capture(e,t);}catch(o){console.error("Posthog: Failed to capture event",o);}};this.isFeatureEnabled=e=>{if(this.has_initialized)try{let t=r__default.default.isFeatureEnabled(e);return this.log("isFeatureEnabled",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to check feature flag",t);return}};this.getFeatureFlag=e=>{if(this.has_initialized)try{let t=r__default.default.getFeatureFlag(e);return this.log("getFeatureFlag",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag",t);return}};this.getFeatureFlagPayload=e=>{if(this.has_initialized)try{let t=r__default.default.getFeatureFlagResult(e)?.payload;return this.log("getFeatureFlagPayload",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag payload",t);return}};this.getAllFlags=()=>{if(!this.has_initialized)return {};try{let e=r__default.default.featureFlags?.getFlagVariants()??{};return this.log("getAllFlags",{result:e}),e}catch(e){return console.error("Posthog: Failed to get all feature flags",e),{}}};this.onFeatureFlags=e=>{if(!this.has_initialized)return ()=>{};try{this.log("onFeatureFlags | subscribing to feature flag changes");let t=r__default.default.onFeatureFlags(e);return typeof t=="function"?t:()=>{}}catch(t){return console.error("Posthog: Failed to subscribe to feature flags",t),()=>{}}};this.reloadFeatureFlags=()=>{if(this.has_initialized)try{this.log("reloadFeatureFlags | reloading feature flags"),r__default.default.reloadFeatureFlags();}catch(e){console.error("Posthog: Failed to reload feature flags",e);}};this.options=e,this.debug=t,this.init();}};g.getPosthogInstance=(e,t=false)=>(g._instance||(g._instance=new g(e,t)),g._instance);var P=g;exports.Posthog=P;//# sourceMappingURL=index.js.map
1
+ 'use strict';var chunkT4BXL6JM_js=require('../../chunk-T4BXL6JM.js'),n=require('posthog-js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var n__default=/*#__PURE__*/_interopDefault(n);/* @deriv-com/analytics - NPM Package - Built with tsup */
2
+ var r=class r{constructor(e,t=false){this.has_initialized=false;this.has_identified=false;this.debug=false;this.log=chunkT4BXL6JM_js.f("[PostHog]",()=>this.debug);this.cleanupStalePosthogCookies=e=>{if(typeof document>"u"||typeof window>"u")return;let t=`ph_${e}_posthog`,o=document.cookie.split(";").map(i=>i.trim().split("=")[0]??"").filter(i=>/^ph_.+_posthog$/.test(i)&&i!==t);if(o.length===0)return;let l=window.location.hostname,d=l.split("."),a=d.length>=2?`.${d.slice(-2).join(".")}`:l;o.forEach(i=>{[a,l,""].forEach(s=>{let g=s?`; Domain=${s}`:"";document.cookie=`${i}=; path=/${g}; max-age=0; SameSite=Lax`;});let c=!document.cookie.split(";").some(s=>s.trim().startsWith(`${i}=`));this.log(`cleanupStalePosthogCookies | ${c?"removed":"failed to remove"} stale cookie: ${i}`);});};this.init=()=>{try{let{apiKey:e,api_host:t,config:o={}}=this.options;if(!e){console.warn("Posthog: No API key provided");return}if(r._hasLoaded||n__default.default.__loaded){this.log("init | PostHog already initialized, skipping re-init"),this.has_initialized=!0;return}this.cleanupStalePosthogCookies(e);let l=t||chunkT4BXL6JM_js.d();this.log("init | loading PostHog SDK",{api_host:l});let d={api_host:l,ui_host:chunkT4BXL6JM_js.c,autocapture:{dom_event_allowlist:["click"]},rate_limiting:{events_per_second:10,events_burst_limit:100},...o,person_profiles:"identified_only",capture_pageview:"history_change",capture_pageleave:!0,session_recording:{...o.session_recording,recordCrossOriginIframes:!0,minimumDurationMilliseconds:3e4,maskAllInputs:!0},before_send:a=>{if(typeof window>"u"||!a)return null;if(a.timestamp){let s=a.timestamp.getTime(),g=Date.now();if(s<g-6048e5||s>g+6048e5)return this.log("init | before_send dropped event with bad timestamp",{event:a.event,timestamp:a.timestamp.toISOString()}),null}let i=window.location.hostname;if(i!=="localhost"&&i!=="127.0.0.1"&&!chunkT4BXL6JM_js.e.some(s=>i.endsWith(`.${s}`)||i===s))return this.log("init | before_send blocked event from disallowed host",{currentHost:i}),null;if(o.before_send){let c=Array.isArray(o.before_send)?o.before_send:[o.before_send],s=a;for(let g of c)s=s?g(s):null;return s}return a}};n__default.default.init(e,d),r._hasLoaded=!0,this.has_initialized=!0,this.log("init | PostHog SDK loaded successfully");}catch(e){console.error("Posthog: Failed to initialize",e);}};this.resetIfStaleId=(e,t,o)=>{r.isAnonymousId(e)||(this.log(`${o} | stale identified user, resetting`,{previous:e,next:t}),n__default.default.reset());};this.identifyEvent=(e,t={})=>{if(!this.has_initialized){console.warn("Posthog: Cannot identify - not initialized");return}try{if(!e||!e.trim()||r.ILLEGAL_IDS.has(e.toLowerCase())){this.log("identifyEvent | skipped \u2014 invalid user_id",{user_id:e});return}let o=n__default.default.get_distinct_id();if(o===e){this.log("identifyEvent | skipped \u2014 user already identified",{user_id:e});return}this.resetIfStaleId(o,e,"identifyEvent"),this.log("identifyEvent | identifying user",{user_id:e,traits:t}),n__default.default.identify(e,{...t,client_id:e}),this.has_identified=!0;}catch(o){console.error("Posthog: Failed to identify user",o);}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting PostHog session"),n__default.default.reset(),this.has_identified=!1;}catch(e){console.error("Posthog: Failed to reset",e);}};this.backfillPersonProperties=({user_id:e,email:t,language:o,country_of_residence:l})=>{if(!(!this.has_initialized||!e)){if(!e.trim()||r.ILLEGAL_IDS.has(e.toLowerCase())){this.log("backfillPersonProperties | skipped \u2014 invalid user_id",{user_id:e});return}try{let d=n__default.default.get_distinct_id(),a=d===e;a||this.resetIfStaleId(d,e,"backfillPersonProperties");let i={};if(n__default.default.get_property("client_id")||(i.client_id=e),t&&n__default.default.get_property("is_internal")==null&&(i.is_internal=chunkT4BXL6JM_js.g(t)),o&&!n__default.default.get_property("language")&&(i.language=o),l&&!n__default.default.get_property("country_of_residence")&&(i.country_of_residence=l),a){if(Object.keys(i).length===0){this.log("backfillPersonProperties | skipped \u2014 all properties already present",{user_id:e});return}this.log("backfillPersonProperties | backfilling person properties",{user_id:e,updates:i}),n__default.default.setPersonProperties(i);}else i.client_id||(i.client_id=e),this.log("backfillPersonProperties | user not identified, identifying now",{user_id:e,updates:i}),n__default.default.identify(e,i),this.has_identified=!0;}catch(d){console.error("Posthog: Failed to backfill person properties",d);}}};this.capture=(e,t)=>{if(this.has_initialized)try{this.log("capture | sending event to PostHog",{event_name:e,properties:t}),n__default.default.capture(e,t);}catch(o){console.error("Posthog: Failed to capture event",o);}};this.isFeatureEnabled=e=>{if(this.has_initialized)try{let t=n__default.default.isFeatureEnabled(e);return this.log("isFeatureEnabled",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to check feature flag",t);return}};this.getFeatureFlag=e=>{if(this.has_initialized)try{let t=n__default.default.getFeatureFlag(e);return this.log("getFeatureFlag",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag",t);return}};this.getFeatureFlagPayload=e=>{if(this.has_initialized)try{let t=n__default.default.getFeatureFlagResult(e)?.payload;return this.log("getFeatureFlagPayload",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag payload",t);return}};this.getAllFlags=()=>{if(!this.has_initialized)return {};try{let e=n__default.default.featureFlags?.getFlagVariants()??{},t=Object.fromEntries(Object.entries(e).filter(o=>o[1]!=null));return this.log("getAllFlags",{result:t}),t}catch(e){return console.error("Posthog: Failed to get all feature flags",e),{}}};this.onFeatureFlags=e=>{if(!this.has_initialized)return ()=>{};try{this.log("onFeatureFlags | subscribing to feature flag changes");let t=n__default.default.onFeatureFlags(e);return typeof t=="function"?t:()=>{}}catch(t){return console.error("Posthog: Failed to subscribe to feature flags",t),()=>{}}};this.reloadFeatureFlags=()=>{if(this.has_initialized)try{this.log("reloadFeatureFlags | reloading feature flags"),n__default.default.reloadFeatureFlags();}catch(e){console.error("Posthog: Failed to reload feature flags",e);}};this.options=e,this.debug=t,this.init();}};r._hasLoaded=false,r.ILLEGAL_IDS=new Set(["restored","null","undefined","anonymous","guest","distinctid","distinct_id","id","not_authenticated","email","true","false","0","none","nan"]),r.getPosthogInstance=(e,t=false)=>(r._instance?e.apiKey&&e.apiKey!==r._instance.options.apiKey&&console.warn("Posthog: getPosthogInstance called with a different API key \u2014 returning existing instance"):r._instance=new r(e,t),r._instance),r.isAnonymousId=e=>e?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e):true;var m=r;exports.Posthog=m;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/posthog.ts"],"names":["_Posthog","options","debug","createLogger","currentApiKey","currentCookieName","staleCookies","c","name","hostname","domainParts","rootDomain","domain","domainAttr","deleted","apiKey","api_host","config","resolvedApiHost","getPosthogApiHost","posthogConfig","posthogUiHost","event","currentHost","isAllowed","allowedDomains","posthog","error","user_id","traits","alreadyThisUser","email","language","country_of_residence","storedProperties","updates","isInternalEmail","event_name","properties","key","result","callback","unsubscribe","Posthog"],"mappings":"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","file":"index.js","sourcesContent":["import posthog from 'posthog-js'\nimport type { TPosthogConfig, TPosthogIdentifyTraits, TPosthogOptions } from './posthogTypes'\nimport { allowedDomains, getPosthogApiHost, posthogUiHost } from '../utils/urls'\nimport { createLogger, isInternalEmail } from '../utils/helpers'\n\n/**\n * PostHog analytics wrapper with singleton pattern.\n * Provides optional PostHog integration for event tracking and session recording.\n *\n * Features:\n * - Dynamically loads PostHog SDK on demand\n * - Domain allowlisting for security\n * - Automatic user identification with client_id enforcement\n * - client_id backfill for previously identified users via backfillPersonProperties\n * - Custom event tracking with property sanitization\n * - Built-in caching and retry mechanisms (handled by posthog-js library)\n *\n * Note: PostHog handles its own event queuing, caching, and retry logic internally.\n * No additional caching is needed at the wrapper level.\n */\nexport class Posthog {\n has_initialized = false\n has_identified = false\n private static _instance: Posthog\n private options: TPosthogOptions\n private debug = false\n private log = createLogger('[PostHog]', () => this.debug)\n\n constructor(options: TPosthogOptions, debug = false) {\n this.options = options\n this.debug = debug\n this.init()\n }\n\n /**\n * Get or create the singleton instance of Posthog\n * @param options - PostHog configuration options including API key\n * @param debug - Enable debug logging\n * @returns The Posthog singleton instance\n */\n public static getPosthogInstance = (options: TPosthogOptions, debug = false): Posthog => {\n if (!Posthog._instance) {\n Posthog._instance = new Posthog(options, debug)\n }\n return Posthog._instance\n }\n\n /**\n * Remove stale PostHog cookies that don't belong to the current project key.\n * PostHog sets cookies named `ph_{apiKey}_posthog` — if multiple project keys\n * have been used in the same browser, old cookies pile up and should be cleaned.\n */\n private cleanupStalePosthogCookies = (currentApiKey: string): void => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n\n const currentCookieName = `ph_${currentApiKey}_posthog`\n const staleCookies = document.cookie\n .split(';')\n .map(c => c.trim().split('=')[0] ?? '')\n .filter(name => /^ph_.+_posthog$/.test(name) && name !== currentCookieName)\n\n if (staleCookies.length === 0) return\n\n const hostname = window.location.hostname\n const domainParts = hostname.split('.')\n // TLD+2 assumption: works for deriv.com → .deriv.com but would produce\n // .co.uk for app.deriv.co.uk. Acceptable for current Deriv domains.\n const rootDomain = domainParts.length >= 2 ? `.${domainParts.slice(-2).join('.')}` : hostname\n\n staleCookies.forEach(name => {\n // Try deleting with root domain, subdomain, and no domain\n ;[rootDomain, hostname, ''].forEach(domain => {\n const domainAttr = domain ? `; Domain=${domain}` : ''\n document.cookie = `${name}=; path=/${domainAttr}; max-age=0; SameSite=Lax`\n })\n const deleted = !document.cookie.split(';').some(c => c.trim().startsWith(`${name}=`))\n this.log(`cleanupStalePosthogCookies | ${deleted ? 'removed' : 'failed to remove'} stale cookie: ${name}`)\n })\n }\n\n /**\n * Initialize PostHog with configuration\n * Configures PostHog instance with provided options\n */\n init = (): void => {\n try {\n const { apiKey, api_host, config = {} } = this.options\n\n if (!apiKey) {\n console.warn('Posthog: No API key provided')\n return\n }\n\n this.cleanupStalePosthogCookies(apiKey)\n\n const resolvedApiHost = api_host || getPosthogApiHost()\n this.log('init | loading PostHog SDK', { api_host: resolvedApiHost })\n\n const posthogConfig: TPosthogConfig = {\n api_host: resolvedApiHost,\n ui_host: posthogUiHost,\n autocapture: true,\n capture_pageview: 'history_change',\n session_recording: {\n recordCrossOriginIframes: true,\n minimumDurationMilliseconds: 30000,\n maskAllInputs: true,\n ...config.session_recording,\n },\n before_send: event => {\n if (typeof window === 'undefined') return null\n\n const currentHost = window.location.hostname\n if (currentHost === 'localhost' || currentHost === '127.0.0.1') return event\n\n const isAllowed = allowedDomains.some(\n domain => currentHost.endsWith(`.${domain}`) || currentHost === domain\n )\n if (!isAllowed) this.log('init | before_send blocked event from disallowed host', { currentHost })\n return isAllowed ? event : null\n },\n ...config,\n }\n\n // Initialize PostHog\n posthog.init(apiKey, posthogConfig)\n this.has_initialized = true\n this.log('init | PostHog SDK loaded successfully')\n } catch (error) {\n console.error('Posthog: Failed to initialize', error)\n }\n }\n\n /**\n * Identify a user with PostHog.\n * Skipped if the user is already identified — use backfillPersonProperties to backfill\n * client_id for users identified in previous sessions.\n *\n * @param user_id - The user ID to identify\n * @param traits - User properties (language, country_of_residence, etc.)\n */\n identifyEvent = (user_id: string, traits: TPosthogIdentifyTraits = {}): void => {\n if (!this.has_initialized) {\n console.warn('Posthog: Cannot identify - not initialized')\n return\n }\n\n try {\n const alreadyThisUser = this.has_identified && posthog.get_distinct_id() === user_id\n\n if (user_id && !alreadyThisUser) {\n this.log('identifyEvent | identifying user', { user_id, traits })\n posthog.identify(user_id, {\n ...traits,\n client_id: user_id,\n })\n this.has_identified = true\n } else {\n this.log('identifyEvent | skipped — user already identified', { user_id })\n }\n } catch (error) {\n console.error('Posthog: Failed to identify user', error)\n }\n }\n\n /**\n * Reset PostHog state\n * Clears user identification and resets the instance\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting PostHog session')\n posthog.reset()\n this.has_identified = false\n } catch (error) {\n console.error('Posthog: Failed to reset', error)\n }\n }\n\n /**\n * Ensure client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * No-op if client_id is already present.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n */\n backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n if (!this.has_initialized || !user_id) return\n\n try {\n const storedProperties: Record<string, any> = posthog.get_property('$stored_person_properties') ?? {}\n const updates: Record<string, any> = {}\n\n if (!storedProperties.client_id) {\n updates.client_id = user_id\n }\n if (email && storedProperties.is_internal === undefined) {\n updates.is_internal = isInternalEmail(email)\n }\n if (language && !storedProperties.language) {\n updates.language = language\n }\n if (country_of_residence && !storedProperties.country_of_residence) {\n updates.country_of_residence = country_of_residence\n }\n\n if (Object.keys(updates).length > 0) {\n this.log('backfillPersonProperties | backfilling person properties', { user_id, updates })\n posthog.setPersonProperties(updates)\n } else {\n this.log('backfillPersonProperties | skipped — all properties already present', {\n user_id,\n country_of_residence,\n })\n }\n } catch (error) {\n console.error('Posthog: Failed to backfill person properties', error)\n }\n }\n\n /**\n * Capture a custom event with properties\n * Properties are pre-flattened and cleaned by analytics.ts before being passed here\n *\n * @param event_name - The name of the event to track\n * @param properties - Event properties including core attributes (already flattened and cleaned)\n */\n capture = (event_name: string, properties?: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('capture | sending event to PostHog', { event_name, properties })\n posthog.capture(event_name, properties)\n } catch (error) {\n console.error('Posthog: Failed to capture event', error)\n }\n }\n\n /**\n * Check whether a feature flag is enabled for the current user.\n *\n * @param key - The feature flag key\n * @returns true/false, or undefined if PostHog is not ready\n */\n isFeatureEnabled = (key: string): boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.isFeatureEnabled(key)\n this.log('isFeatureEnabled', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to check feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the value of a feature flag.\n * Returns a string variant for multivariate flags, true/false for boolean flags,\n * or undefined if the flag does not exist or PostHog is not ready.\n *\n * @param key - The feature flag key\n */\n getFeatureFlag = (key: string): string | boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlag(key)\n this.log('getFeatureFlag', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the JSON payload associated with a feature flag.\n * Payloads allow attaching structured metadata (e.g. config objects) to a flag.\n *\n * @param key - The feature flag key\n */\n getFeatureFlagPayload = (\n key: string\n ): string | number | boolean | null | Record<string, unknown> | unknown[] | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlagResult(key)?.payload as\n | string\n | number\n | boolean\n | null\n | Record<string, unknown>\n | unknown[]\n | undefined\n this.log('getFeatureFlagPayload', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag payload', error)\n return undefined\n }\n }\n\n /**\n * Get all currently active feature flags and their values.\n *\n * @returns A map of flag key → value (boolean or string variant)\n */\n getAllFlags = (): Record<string, string | boolean> => {\n if (!this.has_initialized) return {}\n\n try {\n const result = posthog.featureFlags?.getFlagVariants() ?? {}\n this.log('getAllFlags', { result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get all feature flags', error)\n return {}\n }\n }\n\n /**\n * Subscribe to feature flag changes.\n * The callback fires immediately with the current flags and again whenever they are reloaded.\n *\n * @param callback - Receives the list of active flag keys and a map of key → variant\n * @returns An unsubscribe function — call it to stop listening\n */\n onFeatureFlags = (\n callback: (flags: string[], variants: Record<string, string | boolean>) => void\n ): (() => void) => {\n if (!this.has_initialized) return () => {}\n\n try {\n this.log('onFeatureFlags | subscribing to feature flag changes')\n const unsubscribe = posthog.onFeatureFlags(callback)\n return typeof unsubscribe === 'function' ? unsubscribe : () => {}\n } catch (error) {\n console.error('Posthog: Failed to subscribe to feature flags', error)\n return () => {}\n }\n }\n\n /**\n * Force PostHog to reload feature flags from the server.\n * Useful after login, logout, or any attribute change that may affect targeting.\n */\n reloadFeatureFlags = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reloadFeatureFlags | reloading feature flags')\n posthog.reloadFeatureFlags()\n } catch (error) {\n console.error('Posthog: Failed to reload feature flags', error)\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/providers/posthog.ts"],"names":["_Posthog","options","debug","createLogger","currentApiKey","currentCookieName","staleCookies","c","name","hostname","domainParts","rootDomain","domain","domainAttr","deleted","apiKey","api_host","config","posthog","resolvedApiHost","getPosthogApiHost","posthogConfig","posthogUiHost","event","eventMs","now","currentHost","allowedDomains","fns","result","fn","error","currentDistinctId","nextUserId","caller","user_id","traits","email","language","country_of_residence","alreadyIdentified","updates","isInternalEmail","event_name","properties","key","raw","entry","callback","unsubscribe","id","Posthog"],"mappings":"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","file":"index.js","sourcesContent":["import posthog from 'posthog-js'\nimport type { TPosthogConfig, TPosthogIdentifyTraits, TPosthogOptions } from './posthogTypes'\nimport { allowedDomains, getPosthogApiHost, posthogUiHost } from '../utils/urls'\nimport { createLogger, isInternalEmail } from '../utils/helpers'\n\n/**\n * PostHog analytics wrapper with singleton pattern.\n * Provides optional PostHog integration for event tracking and session recording.\n *\n * Features:\n * - Dynamically loads PostHog SDK on demand\n * - Domain allowlisting for security\n * - Automatic user identification with client_id enforcement\n * - client_id backfill for previously identified users via backfillPersonProperties\n * - Custom event tracking with property sanitization\n * - Built-in caching and retry mechanisms (handled by posthog-js library)\n *\n * Note: PostHog handles its own event queuing, caching, and retry logic internally.\n * No additional caching is needed at the wrapper level.\n */\nexport class Posthog {\n has_initialized = false\n has_identified = false\n private static _instance: Posthog\n // Survives re-instantiation — covers hot reload and multiple module copies.\n // posthog.__loaded is checked as a secondary guard for cases where this\n // static field is reset but posthog-js already has a live instance (e.g.\n // duplicate module bundles in micro-frontends).\n private static _hasLoaded = false\n private static readonly ILLEGAL_IDS = new Set([\n 'restored',\n 'null',\n 'undefined',\n 'anonymous',\n 'guest',\n 'distinctid',\n 'distinct_id',\n 'id',\n 'not_authenticated',\n 'email',\n 'true',\n 'false',\n '0',\n 'none',\n 'nan',\n ])\n private options: TPosthogOptions\n private debug = false\n private log = createLogger('[PostHog]', () => this.debug)\n\n constructor(options: TPosthogOptions, debug = false) {\n this.options = options\n this.debug = debug\n this.init()\n }\n\n /**\n * Get or create the singleton instance of Posthog\n * @param options - PostHog configuration options including API key\n * @param debug - Enable debug logging\n * @returns The Posthog singleton instance\n */\n public static getPosthogInstance = (options: TPosthogOptions, debug = false): Posthog => {\n if (!Posthog._instance) {\n Posthog._instance = new Posthog(options, debug)\n } else if (options.apiKey && options.apiKey !== Posthog._instance.options.apiKey) {\n console.warn('Posthog: getPosthogInstance called with a different API key — returning existing instance')\n }\n return Posthog._instance\n }\n\n /**\n * Remove stale PostHog cookies that don't belong to the current project key.\n * PostHog sets cookies named `ph_{apiKey}_posthog` — if multiple project keys\n * have been used in the same browser, old cookies pile up and should be cleaned.\n */\n private cleanupStalePosthogCookies = (currentApiKey: string): void => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n\n const currentCookieName = `ph_${currentApiKey}_posthog`\n const staleCookies = document.cookie\n .split(';')\n .map(c => c.trim().split('=')[0] ?? '')\n .filter(name => /^ph_.+_posthog$/.test(name) && name !== currentCookieName)\n\n if (staleCookies.length === 0) return\n\n const hostname = window.location.hostname\n const domainParts = hostname.split('.')\n // TLD+2 assumption: works for deriv.com → .deriv.com but would produce\n // .co.uk for app.deriv.co.uk. Acceptable for current Deriv domains.\n const rootDomain = domainParts.length >= 2 ? `.${domainParts.slice(-2).join('.')}` : hostname\n\n staleCookies.forEach(name => {\n // Try deleting with root domain, subdomain, and no domain\n ;[rootDomain, hostname, ''].forEach(domain => {\n const domainAttr = domain ? `; Domain=${domain}` : ''\n document.cookie = `${name}=; path=/${domainAttr}; max-age=0; SameSite=Lax`\n })\n const deleted = !document.cookie.split(';').some(c => c.trim().startsWith(`${name}=`))\n this.log(`cleanupStalePosthogCookies | ${deleted ? 'removed' : 'failed to remove'} stale cookie: ${name}`)\n })\n }\n\n /**\n * Initialize PostHog with configuration\n * Configures PostHog instance with provided options\n */\n init = (): void => {\n try {\n const { apiKey, api_host, config = {} } = this.options\n\n if (!apiKey) {\n console.warn('Posthog: No API key provided')\n return\n }\n\n if (Posthog._hasLoaded || (posthog as any).__loaded) {\n this.log('init | PostHog already initialized, skipping re-init')\n this.has_initialized = true\n return\n }\n\n this.cleanupStalePosthogCookies(apiKey)\n\n const resolvedApiHost = api_host || getPosthogApiHost()\n this.log('init | loading PostHog SDK', { api_host: resolvedApiHost })\n\n const posthogConfig: TPosthogConfig = {\n // Overridable defaults — consumers can override these via config\n api_host: resolvedApiHost,\n ui_host: posthogUiHost,\n // Scope autocapture to clicks only. Default also captures input changes and\n // form submissions which, on a high-frequency trading SPA, contributes to\n // burst-limit hits.\n autocapture: { dom_event_allowlist: ['click'] },\n // Pin rate limits explicitly so SDK default changes don't silently affect us.\n rate_limiting: {\n events_per_second: 10,\n events_burst_limit: 100,\n },\n ...config,\n\n // ── Enforced after consumer spread ─────────────────────────────────────\n person_profiles: 'identified_only',\n // 'history_change' fires $pageview on every pushState/replaceState (SPA-friendly).\n // Consumers must NOT also call posthog.capture('$pageview') manually — that\n // causes a duplicate on every navigation and hits the burst rate limit.\n capture_pageview: 'history_change',\n capture_pageleave: true,\n session_recording: {\n ...config.session_recording,\n recordCrossOriginIframes: true,\n minimumDurationMilliseconds: 30000,\n maskAllInputs: true,\n },\n before_send: event => {\n // SSR guard — note: this drops all server-side events.\n // If consumers ever use SSR (Next.js, Nuxt), move domain check\n // to runtime and remove the window guard from the timestamp filter.\n if (typeof window === 'undefined' || !event) return null\n\n if (event.timestamp) {\n const sevenDaysMs = 7 * 24 * 60 * 60 * 1000\n const eventMs = event.timestamp.getTime()\n const now = Date.now()\n if (eventMs < now - sevenDaysMs || eventMs > now + sevenDaysMs) {\n this.log('init | before_send dropped event with bad timestamp', {\n event: event.event,\n timestamp: event.timestamp.toISOString(),\n })\n return null\n }\n }\n\n const currentHost = window.location.hostname\n if (currentHost !== 'localhost' && currentHost !== '127.0.0.1') {\n const isAllowed = allowedDomains.some(\n domain => currentHost.endsWith(`.${domain}`) || currentHost === domain\n )\n if (!isAllowed) {\n this.log('init | before_send blocked event from disallowed host', { currentHost })\n return null\n }\n }\n\n if (config.before_send) {\n const fns = Array.isArray(config.before_send) ? config.before_send : [config.before_send]\n let result: typeof event | null = event\n for (const fn of fns) {\n result = result ? fn(result) : null\n }\n return result\n }\n return event\n },\n }\n\n // Initialize PostHog\n posthog.init(apiKey, posthogConfig)\n Posthog._hasLoaded = true\n this.has_initialized = true\n this.log('init | PostHog SDK loaded successfully')\n } catch (error) {\n console.error('Posthog: Failed to initialize', error)\n }\n }\n\n private static isAnonymousId = (id: string | undefined | null): boolean => {\n if (!id) return true\n // Hard-coded UUID v4 pattern — matches posthog-js anonymous ID format.\n // Verify after major posthog-js version bumps; a changed format would treat\n // new anonymous IDs as identified and trigger spurious resets on every login.\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)\n }\n\n private resetIfStaleId = (\n currentDistinctId: string | undefined | null,\n nextUserId: string,\n caller: string\n ): void => {\n if (!Posthog.isAnonymousId(currentDistinctId)) {\n this.log(`${caller} | stale identified user, resetting`, {\n previous: currentDistinctId,\n next: nextUserId,\n })\n posthog.reset()\n }\n }\n\n /**\n * Identify a user with PostHog.\n * Skipped if the user is already identified — use backfillPersonProperties to backfill\n * client_id for users identified in previous sessions.\n *\n * @param user_id - The user ID to identify\n * @param traits - User properties (language, country_of_residence, etc.)\n */\n identifyEvent = (user_id: string, traits: TPosthogIdentifyTraits = {}): void => {\n if (!this.has_initialized) {\n console.warn('Posthog: Cannot identify - not initialized')\n return\n }\n\n try {\n if (!user_id || !user_id.trim() || Posthog.ILLEGAL_IDS.has(user_id.toLowerCase())) {\n this.log('identifyEvent | skipped — invalid user_id', { user_id })\n return\n }\n\n const currentDistinctId = posthog.get_distinct_id()\n\n if (currentDistinctId === user_id) {\n this.log('identifyEvent | skipped — user already identified', { user_id })\n return\n }\n\n // If PostHog holds a different identified user's ID (not an anonymous UUID),\n // reset first to prevent profile merging between accounts.\n this.resetIfStaleId(currentDistinctId, user_id, 'identifyEvent')\n\n this.log('identifyEvent | identifying user', { user_id, traits })\n posthog.identify(user_id, {\n ...traits,\n client_id: user_id,\n })\n this.has_identified = true\n } catch (error) {\n console.error('Posthog: Failed to identify user', error)\n }\n }\n\n /**\n * Reset PostHog state\n * Clears user identification and resets the instance\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting PostHog session')\n posthog.reset()\n this.has_identified = false\n } catch (error) {\n console.error('Posthog: Failed to reset', error)\n }\n }\n\n /**\n * Ensure client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * No-op if client_id is already present.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n */\n backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n if (!this.has_initialized || !user_id) return\n\n if (!user_id.trim() || Posthog.ILLEGAL_IDS.has(user_id.toLowerCase())) {\n this.log('backfillPersonProperties | skipped — invalid user_id', { user_id })\n return\n }\n\n try {\n const currentDistinctId = posthog.get_distinct_id()\n const alreadyIdentified = currentDistinctId === user_id\n\n // Reset stale identity FIRST — otherwise property reads below see the previous\n // user's cached values and we may early-return without identifying the new user.\n if (!alreadyIdentified) {\n this.resetIfStaleId(currentDistinctId, user_id, 'backfillPersonProperties')\n }\n\n const updates: Record<string, any> = {}\n\n // Falsy is correct for string-valued properties; '' is not a valid value and also warrants a rewrite.\n // is_internal uses == null because false is a legitimate value that must not be overwritten.\n if (!posthog.get_property('client_id')) {\n updates.client_id = user_id\n }\n if (email && posthog.get_property('is_internal') == null) {\n updates.is_internal = isInternalEmail(email)\n }\n if (language && !posthog.get_property('language')) {\n updates.language = language\n }\n if (country_of_residence && !posthog.get_property('country_of_residence')) {\n updates.country_of_residence = country_of_residence\n }\n\n if (alreadyIdentified) {\n if (Object.keys(updates).length === 0) {\n this.log('backfillPersonProperties | skipped — all properties already present', { user_id })\n return\n }\n this.log('backfillPersonProperties | backfilling person properties', { user_id, updates })\n posthog.setPersonProperties(updates)\n } else {\n // Always identify after a potential reset — ensures client_id lands even if persistence was cleared.\n if (!updates.client_id) updates.client_id = user_id\n this.log('backfillPersonProperties | user not identified, identifying now', { user_id, updates })\n posthog.identify(user_id, updates)\n this.has_identified = true\n }\n } catch (error) {\n console.error('Posthog: Failed to backfill person properties', error)\n }\n }\n\n /**\n * Capture a custom event with properties\n * Properties are pre-flattened and cleaned by analytics.ts before being passed here\n *\n * @param event_name - The name of the event to track\n * @param properties - Event properties including core attributes (already flattened and cleaned)\n */\n capture = (event_name: string, properties?: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('capture | sending event to PostHog', { event_name, properties })\n posthog.capture(event_name, properties)\n } catch (error) {\n console.error('Posthog: Failed to capture event', error)\n }\n }\n\n /**\n * Check whether a feature flag is enabled for the current user.\n *\n * @param key - The feature flag key\n * @returns true/false, or undefined if PostHog is not ready\n */\n isFeatureEnabled = (key: string): boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.isFeatureEnabled(key)\n this.log('isFeatureEnabled', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to check feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the value of a feature flag.\n * Returns a string variant for multivariate flags, true/false for boolean flags,\n * or undefined if the flag does not exist or PostHog is not ready.\n *\n * @param key - The feature flag key\n */\n getFeatureFlag = (key: string): string | boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlag(key)\n this.log('getFeatureFlag', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the JSON payload associated with a feature flag.\n * Payloads allow attaching structured metadata (e.g. config objects) to a flag.\n *\n * @param key - The feature flag key\n */\n getFeatureFlagPayload = (\n key: string\n ): string | number | boolean | null | Record<string, unknown> | unknown[] | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlagResult(key)?.payload as\n | string\n | number\n | boolean\n | null\n | Record<string, unknown>\n | unknown[]\n | undefined\n this.log('getFeatureFlagPayload', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag payload', error)\n return undefined\n }\n }\n\n /**\n * Get all currently active feature flags and their values.\n *\n * @returns A map of flag key → value (boolean or string variant)\n */\n getAllFlags = (): Record<string, string | boolean> => {\n if (!this.has_initialized) return {}\n\n try {\n // NOTE: featureFlags and getFlagVariants() are internal posthog-js APIs.\n // Verify after major SDK version bumps.\n const raw = posthog.featureFlags?.getFlagVariants() ?? {}\n // FeatureFlagValue includes null/undefined for disabled/unresolved flags;\n // filter them out to honour the declared return type.\n const result = Object.fromEntries(\n Object.entries(raw).filter((entry): entry is [string, string | boolean] => entry[1] != null)\n )\n this.log('getAllFlags', { result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get all feature flags', error)\n return {}\n }\n }\n\n /**\n * Subscribe to feature flag changes.\n * The callback fires immediately with the current flags and again whenever they are reloaded.\n *\n * @param callback - Receives the list of active flag keys and a map of key → variant\n * @returns An unsubscribe function — call it to stop listening\n */\n onFeatureFlags = (\n callback: (flags: string[], variants: Record<string, string | boolean>) => void\n ): (() => void) => {\n if (!this.has_initialized) return () => {}\n\n try {\n this.log('onFeatureFlags | subscribing to feature flag changes')\n const unsubscribe = posthog.onFeatureFlags(callback)\n return typeof unsubscribe === 'function' ? unsubscribe : () => {}\n } catch (error) {\n console.error('Posthog: Failed to subscribe to feature flags', error)\n return () => {}\n }\n }\n\n /**\n * Force PostHog to reload feature flags from the server.\n * Useful after login, logout, or any attribute change that may affect targeting.\n */\n reloadFeatureFlags = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reloadFeatureFlags | reloading feature flags')\n posthog.reloadFeatureFlags()\n } catch (error) {\n console.error('Posthog: Failed to reload feature flags', error)\n }\n }\n}\n"]}
@@ -1,3 +1,3 @@
1
- import {f,d,e,c,g as g$1}from'../../chunk-TE3DYZVQ.mjs';import r from'posthog-js';/* @deriv-com/analytics - NPM Package - Built with tsup */
2
- var g=class g{constructor(e$1,t=false){this.has_initialized=false;this.has_identified=false;this.debug=false;this.log=f("[PostHog]",()=>this.debug);this.cleanupStalePosthogCookies=e=>{if(typeof document>"u"||typeof window>"u")return;let t=`ph_${e}_posthog`,o=document.cookie.split(";").map(i=>i.trim().split("=")[0]??"").filter(i=>/^ph_.+_posthog$/.test(i)&&i!==t);if(o.length===0)return;let a=window.location.hostname,n=a.split("."),s=n.length>=2?`.${n.slice(-2).join(".")}`:a;o.forEach(i=>{[s,a,""].forEach(l=>{let F=l?`; Domain=${l}`:"";document.cookie=`${i}=; path=/${F}; max-age=0; SameSite=Lax`;});let d=!document.cookie.split(";").some(l=>l.trim().startsWith(`${i}=`));this.log(`cleanupStalePosthogCookies | ${d?"removed":"failed to remove"} stale cookie: ${i}`);});};this.init=()=>{try{let{apiKey:e$1,api_host:t,config:o={}}=this.options;if(!e$1){console.warn("Posthog: No API key provided");return}this.cleanupStalePosthogCookies(e$1);let a=t||d();this.log("init | loading PostHog SDK",{api_host:a});let n={api_host:a,ui_host:c,autocapture:!0,capture_pageview:"history_change",session_recording:{recordCrossOriginIframes:!0,minimumDurationMilliseconds:3e4,maskAllInputs:!0,...o.session_recording},before_send:s=>{if(typeof window>"u")return null;let i=window.location.hostname;if(i==="localhost"||i==="127.0.0.1")return s;let d=e.some(l=>i.endsWith(`.${l}`)||i===l);return d||this.log("init | before_send blocked event from disallowed host",{currentHost:i}),d?s:null},...o};r.init(e$1,n),this.has_initialized=!0,this.log("init | PostHog SDK loaded successfully");}catch(e){console.error("Posthog: Failed to initialize",e);}};this.identifyEvent=(e,t={})=>{if(!this.has_initialized){console.warn("Posthog: Cannot identify - not initialized");return}try{let o=this.has_identified&&r.get_distinct_id()===e;e&&!o?(this.log("identifyEvent | identifying user",{user_id:e,traits:t}),r.identify(e,{...t,client_id:e}),this.has_identified=!0):this.log("identifyEvent | skipped \u2014 user already identified",{user_id:e});}catch(o){console.error("Posthog: Failed to identify user",o);}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting PostHog session"),r.reset(),this.has_identified=!1;}catch(e){console.error("Posthog: Failed to reset",e);}};this.backfillPersonProperties=({user_id:e,email:t,language:o,country_of_residence:a})=>{if(!(!this.has_initialized||!e))try{let n=r.get_property("$stored_person_properties")??{},s={};n.client_id||(s.client_id=e),t&&n.is_internal===void 0&&(s.is_internal=g$1(t)),o&&!n.language&&(s.language=o),a&&!n.country_of_residence&&(s.country_of_residence=a),Object.keys(s).length>0?(this.log("backfillPersonProperties | backfilling person properties",{user_id:e,updates:s}),r.setPersonProperties(s)):this.log("backfillPersonProperties | skipped \u2014 all properties already present",{user_id:e,country_of_residence:a});}catch(n){console.error("Posthog: Failed to backfill person properties",n);}};this.capture=(e,t)=>{if(this.has_initialized)try{this.log("capture | sending event to PostHog",{event_name:e,properties:t}),r.capture(e,t);}catch(o){console.error("Posthog: Failed to capture event",o);}};this.isFeatureEnabled=e=>{if(this.has_initialized)try{let t=r.isFeatureEnabled(e);return this.log("isFeatureEnabled",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to check feature flag",t);return}};this.getFeatureFlag=e=>{if(this.has_initialized)try{let t=r.getFeatureFlag(e);return this.log("getFeatureFlag",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag",t);return}};this.getFeatureFlagPayload=e=>{if(this.has_initialized)try{let t=r.getFeatureFlagResult(e)?.payload;return this.log("getFeatureFlagPayload",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag payload",t);return}};this.getAllFlags=()=>{if(!this.has_initialized)return {};try{let e=r.featureFlags?.getFlagVariants()??{};return this.log("getAllFlags",{result:e}),e}catch(e){return console.error("Posthog: Failed to get all feature flags",e),{}}};this.onFeatureFlags=e=>{if(!this.has_initialized)return ()=>{};try{this.log("onFeatureFlags | subscribing to feature flag changes");let t=r.onFeatureFlags(e);return typeof t=="function"?t:()=>{}}catch(t){return console.error("Posthog: Failed to subscribe to feature flags",t),()=>{}}};this.reloadFeatureFlags=()=>{if(this.has_initialized)try{this.log("reloadFeatureFlags | reloading feature flags"),r.reloadFeatureFlags();}catch(e){console.error("Posthog: Failed to reload feature flags",e);}};this.options=e$1,this.debug=t,this.init();}};g.getPosthogInstance=(e,t=false)=>(g._instance||(g._instance=new g(e,t)),g._instance);var P=g;export{P as Posthog};//# sourceMappingURL=index.mjs.map
1
+ import {f,d,e,c,g}from'../../chunk-TE3DYZVQ.mjs';import n from'posthog-js';/* @deriv-com/analytics - NPM Package - Built with tsup */
2
+ var r=class r{constructor(e$1,t=false){this.has_initialized=false;this.has_identified=false;this.debug=false;this.log=f("[PostHog]",()=>this.debug);this.cleanupStalePosthogCookies=e=>{if(typeof document>"u"||typeof window>"u")return;let t=`ph_${e}_posthog`,o=document.cookie.split(";").map(i=>i.trim().split("=")[0]??"").filter(i=>/^ph_.+_posthog$/.test(i)&&i!==t);if(o.length===0)return;let l=window.location.hostname,d=l.split("."),a=d.length>=2?`.${d.slice(-2).join(".")}`:l;o.forEach(i=>{[a,l,""].forEach(s=>{let g=s?`; Domain=${s}`:"";document.cookie=`${i}=; path=/${g}; max-age=0; SameSite=Lax`;});let c=!document.cookie.split(";").some(s=>s.trim().startsWith(`${i}=`));this.log(`cleanupStalePosthogCookies | ${c?"removed":"failed to remove"} stale cookie: ${i}`);});};this.init=()=>{try{let{apiKey:e$1,api_host:t,config:o={}}=this.options;if(!e$1){console.warn("Posthog: No API key provided");return}if(r._hasLoaded||n.__loaded){this.log("init | PostHog already initialized, skipping re-init"),this.has_initialized=!0;return}this.cleanupStalePosthogCookies(e$1);let l=t||d();this.log("init | loading PostHog SDK",{api_host:l});let d$1={api_host:l,ui_host:c,autocapture:{dom_event_allowlist:["click"]},rate_limiting:{events_per_second:10,events_burst_limit:100},...o,person_profiles:"identified_only",capture_pageview:"history_change",capture_pageleave:!0,session_recording:{...o.session_recording,recordCrossOriginIframes:!0,minimumDurationMilliseconds:3e4,maskAllInputs:!0},before_send:a=>{if(typeof window>"u"||!a)return null;if(a.timestamp){let s=a.timestamp.getTime(),g=Date.now();if(s<g-6048e5||s>g+6048e5)return this.log("init | before_send dropped event with bad timestamp",{event:a.event,timestamp:a.timestamp.toISOString()}),null}let i=window.location.hostname;if(i!=="localhost"&&i!=="127.0.0.1"&&!e.some(s=>i.endsWith(`.${s}`)||i===s))return this.log("init | before_send blocked event from disallowed host",{currentHost:i}),null;if(o.before_send){let c=Array.isArray(o.before_send)?o.before_send:[o.before_send],s=a;for(let g of c)s=s?g(s):null;return s}return a}};n.init(e$1,d$1),r._hasLoaded=!0,this.has_initialized=!0,this.log("init | PostHog SDK loaded successfully");}catch(e){console.error("Posthog: Failed to initialize",e);}};this.resetIfStaleId=(e,t,o)=>{r.isAnonymousId(e)||(this.log(`${o} | stale identified user, resetting`,{previous:e,next:t}),n.reset());};this.identifyEvent=(e,t={})=>{if(!this.has_initialized){console.warn("Posthog: Cannot identify - not initialized");return}try{if(!e||!e.trim()||r.ILLEGAL_IDS.has(e.toLowerCase())){this.log("identifyEvent | skipped \u2014 invalid user_id",{user_id:e});return}let o=n.get_distinct_id();if(o===e){this.log("identifyEvent | skipped \u2014 user already identified",{user_id:e});return}this.resetIfStaleId(o,e,"identifyEvent"),this.log("identifyEvent | identifying user",{user_id:e,traits:t}),n.identify(e,{...t,client_id:e}),this.has_identified=!0;}catch(o){console.error("Posthog: Failed to identify user",o);}};this.reset=()=>{if(this.has_initialized)try{this.log("reset | resetting PostHog session"),n.reset(),this.has_identified=!1;}catch(e){console.error("Posthog: Failed to reset",e);}};this.backfillPersonProperties=({user_id:e,email:t,language:o,country_of_residence:l})=>{if(!(!this.has_initialized||!e)){if(!e.trim()||r.ILLEGAL_IDS.has(e.toLowerCase())){this.log("backfillPersonProperties | skipped \u2014 invalid user_id",{user_id:e});return}try{let d=n.get_distinct_id(),a=d===e;a||this.resetIfStaleId(d,e,"backfillPersonProperties");let i={};if(n.get_property("client_id")||(i.client_id=e),t&&n.get_property("is_internal")==null&&(i.is_internal=g(t)),o&&!n.get_property("language")&&(i.language=o),l&&!n.get_property("country_of_residence")&&(i.country_of_residence=l),a){if(Object.keys(i).length===0){this.log("backfillPersonProperties | skipped \u2014 all properties already present",{user_id:e});return}this.log("backfillPersonProperties | backfilling person properties",{user_id:e,updates:i}),n.setPersonProperties(i);}else i.client_id||(i.client_id=e),this.log("backfillPersonProperties | user not identified, identifying now",{user_id:e,updates:i}),n.identify(e,i),this.has_identified=!0;}catch(d){console.error("Posthog: Failed to backfill person properties",d);}}};this.capture=(e,t)=>{if(this.has_initialized)try{this.log("capture | sending event to PostHog",{event_name:e,properties:t}),n.capture(e,t);}catch(o){console.error("Posthog: Failed to capture event",o);}};this.isFeatureEnabled=e=>{if(this.has_initialized)try{let t=n.isFeatureEnabled(e);return this.log("isFeatureEnabled",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to check feature flag",t);return}};this.getFeatureFlag=e=>{if(this.has_initialized)try{let t=n.getFeatureFlag(e);return this.log("getFeatureFlag",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag",t);return}};this.getFeatureFlagPayload=e=>{if(this.has_initialized)try{let t=n.getFeatureFlagResult(e)?.payload;return this.log("getFeatureFlagPayload",{key:e,result:t}),t}catch(t){console.error("Posthog: Failed to get feature flag payload",t);return}};this.getAllFlags=()=>{if(!this.has_initialized)return {};try{let e=n.featureFlags?.getFlagVariants()??{},t=Object.fromEntries(Object.entries(e).filter(o=>o[1]!=null));return this.log("getAllFlags",{result:t}),t}catch(e){return console.error("Posthog: Failed to get all feature flags",e),{}}};this.onFeatureFlags=e=>{if(!this.has_initialized)return ()=>{};try{this.log("onFeatureFlags | subscribing to feature flag changes");let t=n.onFeatureFlags(e);return typeof t=="function"?t:()=>{}}catch(t){return console.error("Posthog: Failed to subscribe to feature flags",t),()=>{}}};this.reloadFeatureFlags=()=>{if(this.has_initialized)try{this.log("reloadFeatureFlags | reloading feature flags"),n.reloadFeatureFlags();}catch(e){console.error("Posthog: Failed to reload feature flags",e);}};this.options=e$1,this.debug=t,this.init();}};r._hasLoaded=false,r.ILLEGAL_IDS=new Set(["restored","null","undefined","anonymous","guest","distinctid","distinct_id","id","not_authenticated","email","true","false","0","none","nan"]),r.getPosthogInstance=(e,t=false)=>(r._instance?e.apiKey&&e.apiKey!==r._instance.options.apiKey&&console.warn("Posthog: getPosthogInstance called with a different API key \u2014 returning existing instance"):r._instance=new r(e,t),r._instance),r.isAnonymousId=e=>e?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e):true;var m=r;export{m as Posthog};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/posthog.ts"],"names":["_Posthog","options","debug","createLogger","currentApiKey","currentCookieName","staleCookies","c","name","hostname","domainParts","rootDomain","domain","domainAttr","deleted","apiKey","api_host","config","resolvedApiHost","getPosthogApiHost","posthogConfig","posthogUiHost","event","currentHost","isAllowed","allowedDomains","posthog","error","user_id","traits","alreadyThisUser","email","language","country_of_residence","storedProperties","updates","isInternalEmail","event_name","properties","key","result","callback","unsubscribe","Posthog"],"mappings":"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","file":"index.mjs","sourcesContent":["import posthog from 'posthog-js'\nimport type { TPosthogConfig, TPosthogIdentifyTraits, TPosthogOptions } from './posthogTypes'\nimport { allowedDomains, getPosthogApiHost, posthogUiHost } from '../utils/urls'\nimport { createLogger, isInternalEmail } from '../utils/helpers'\n\n/**\n * PostHog analytics wrapper with singleton pattern.\n * Provides optional PostHog integration for event tracking and session recording.\n *\n * Features:\n * - Dynamically loads PostHog SDK on demand\n * - Domain allowlisting for security\n * - Automatic user identification with client_id enforcement\n * - client_id backfill for previously identified users via backfillPersonProperties\n * - Custom event tracking with property sanitization\n * - Built-in caching and retry mechanisms (handled by posthog-js library)\n *\n * Note: PostHog handles its own event queuing, caching, and retry logic internally.\n * No additional caching is needed at the wrapper level.\n */\nexport class Posthog {\n has_initialized = false\n has_identified = false\n private static _instance: Posthog\n private options: TPosthogOptions\n private debug = false\n private log = createLogger('[PostHog]', () => this.debug)\n\n constructor(options: TPosthogOptions, debug = false) {\n this.options = options\n this.debug = debug\n this.init()\n }\n\n /**\n * Get or create the singleton instance of Posthog\n * @param options - PostHog configuration options including API key\n * @param debug - Enable debug logging\n * @returns The Posthog singleton instance\n */\n public static getPosthogInstance = (options: TPosthogOptions, debug = false): Posthog => {\n if (!Posthog._instance) {\n Posthog._instance = new Posthog(options, debug)\n }\n return Posthog._instance\n }\n\n /**\n * Remove stale PostHog cookies that don't belong to the current project key.\n * PostHog sets cookies named `ph_{apiKey}_posthog` — if multiple project keys\n * have been used in the same browser, old cookies pile up and should be cleaned.\n */\n private cleanupStalePosthogCookies = (currentApiKey: string): void => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n\n const currentCookieName = `ph_${currentApiKey}_posthog`\n const staleCookies = document.cookie\n .split(';')\n .map(c => c.trim().split('=')[0] ?? '')\n .filter(name => /^ph_.+_posthog$/.test(name) && name !== currentCookieName)\n\n if (staleCookies.length === 0) return\n\n const hostname = window.location.hostname\n const domainParts = hostname.split('.')\n // TLD+2 assumption: works for deriv.com → .deriv.com but would produce\n // .co.uk for app.deriv.co.uk. Acceptable for current Deriv domains.\n const rootDomain = domainParts.length >= 2 ? `.${domainParts.slice(-2).join('.')}` : hostname\n\n staleCookies.forEach(name => {\n // Try deleting with root domain, subdomain, and no domain\n ;[rootDomain, hostname, ''].forEach(domain => {\n const domainAttr = domain ? `; Domain=${domain}` : ''\n document.cookie = `${name}=; path=/${domainAttr}; max-age=0; SameSite=Lax`\n })\n const deleted = !document.cookie.split(';').some(c => c.trim().startsWith(`${name}=`))\n this.log(`cleanupStalePosthogCookies | ${deleted ? 'removed' : 'failed to remove'} stale cookie: ${name}`)\n })\n }\n\n /**\n * Initialize PostHog with configuration\n * Configures PostHog instance with provided options\n */\n init = (): void => {\n try {\n const { apiKey, api_host, config = {} } = this.options\n\n if (!apiKey) {\n console.warn('Posthog: No API key provided')\n return\n }\n\n this.cleanupStalePosthogCookies(apiKey)\n\n const resolvedApiHost = api_host || getPosthogApiHost()\n this.log('init | loading PostHog SDK', { api_host: resolvedApiHost })\n\n const posthogConfig: TPosthogConfig = {\n api_host: resolvedApiHost,\n ui_host: posthogUiHost,\n autocapture: true,\n capture_pageview: 'history_change',\n session_recording: {\n recordCrossOriginIframes: true,\n minimumDurationMilliseconds: 30000,\n maskAllInputs: true,\n ...config.session_recording,\n },\n before_send: event => {\n if (typeof window === 'undefined') return null\n\n const currentHost = window.location.hostname\n if (currentHost === 'localhost' || currentHost === '127.0.0.1') return event\n\n const isAllowed = allowedDomains.some(\n domain => currentHost.endsWith(`.${domain}`) || currentHost === domain\n )\n if (!isAllowed) this.log('init | before_send blocked event from disallowed host', { currentHost })\n return isAllowed ? event : null\n },\n ...config,\n }\n\n // Initialize PostHog\n posthog.init(apiKey, posthogConfig)\n this.has_initialized = true\n this.log('init | PostHog SDK loaded successfully')\n } catch (error) {\n console.error('Posthog: Failed to initialize', error)\n }\n }\n\n /**\n * Identify a user with PostHog.\n * Skipped if the user is already identified — use backfillPersonProperties to backfill\n * client_id for users identified in previous sessions.\n *\n * @param user_id - The user ID to identify\n * @param traits - User properties (language, country_of_residence, etc.)\n */\n identifyEvent = (user_id: string, traits: TPosthogIdentifyTraits = {}): void => {\n if (!this.has_initialized) {\n console.warn('Posthog: Cannot identify - not initialized')\n return\n }\n\n try {\n const alreadyThisUser = this.has_identified && posthog.get_distinct_id() === user_id\n\n if (user_id && !alreadyThisUser) {\n this.log('identifyEvent | identifying user', { user_id, traits })\n posthog.identify(user_id, {\n ...traits,\n client_id: user_id,\n })\n this.has_identified = true\n } else {\n this.log('identifyEvent | skipped — user already identified', { user_id })\n }\n } catch (error) {\n console.error('Posthog: Failed to identify user', error)\n }\n }\n\n /**\n * Reset PostHog state\n * Clears user identification and resets the instance\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting PostHog session')\n posthog.reset()\n this.has_identified = false\n } catch (error) {\n console.error('Posthog: Failed to reset', error)\n }\n }\n\n /**\n * Ensure client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * No-op if client_id is already present.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n */\n backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n if (!this.has_initialized || !user_id) return\n\n try {\n const storedProperties: Record<string, any> = posthog.get_property('$stored_person_properties') ?? {}\n const updates: Record<string, any> = {}\n\n if (!storedProperties.client_id) {\n updates.client_id = user_id\n }\n if (email && storedProperties.is_internal === undefined) {\n updates.is_internal = isInternalEmail(email)\n }\n if (language && !storedProperties.language) {\n updates.language = language\n }\n if (country_of_residence && !storedProperties.country_of_residence) {\n updates.country_of_residence = country_of_residence\n }\n\n if (Object.keys(updates).length > 0) {\n this.log('backfillPersonProperties | backfilling person properties', { user_id, updates })\n posthog.setPersonProperties(updates)\n } else {\n this.log('backfillPersonProperties | skipped — all properties already present', {\n user_id,\n country_of_residence,\n })\n }\n } catch (error) {\n console.error('Posthog: Failed to backfill person properties', error)\n }\n }\n\n /**\n * Capture a custom event with properties\n * Properties are pre-flattened and cleaned by analytics.ts before being passed here\n *\n * @param event_name - The name of the event to track\n * @param properties - Event properties including core attributes (already flattened and cleaned)\n */\n capture = (event_name: string, properties?: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('capture | sending event to PostHog', { event_name, properties })\n posthog.capture(event_name, properties)\n } catch (error) {\n console.error('Posthog: Failed to capture event', error)\n }\n }\n\n /**\n * Check whether a feature flag is enabled for the current user.\n *\n * @param key - The feature flag key\n * @returns true/false, or undefined if PostHog is not ready\n */\n isFeatureEnabled = (key: string): boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.isFeatureEnabled(key)\n this.log('isFeatureEnabled', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to check feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the value of a feature flag.\n * Returns a string variant for multivariate flags, true/false for boolean flags,\n * or undefined if the flag does not exist or PostHog is not ready.\n *\n * @param key - The feature flag key\n */\n getFeatureFlag = (key: string): string | boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlag(key)\n this.log('getFeatureFlag', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the JSON payload associated with a feature flag.\n * Payloads allow attaching structured metadata (e.g. config objects) to a flag.\n *\n * @param key - The feature flag key\n */\n getFeatureFlagPayload = (\n key: string\n ): string | number | boolean | null | Record<string, unknown> | unknown[] | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlagResult(key)?.payload as\n | string\n | number\n | boolean\n | null\n | Record<string, unknown>\n | unknown[]\n | undefined\n this.log('getFeatureFlagPayload', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag payload', error)\n return undefined\n }\n }\n\n /**\n * Get all currently active feature flags and their values.\n *\n * @returns A map of flag key → value (boolean or string variant)\n */\n getAllFlags = (): Record<string, string | boolean> => {\n if (!this.has_initialized) return {}\n\n try {\n const result = posthog.featureFlags?.getFlagVariants() ?? {}\n this.log('getAllFlags', { result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get all feature flags', error)\n return {}\n }\n }\n\n /**\n * Subscribe to feature flag changes.\n * The callback fires immediately with the current flags and again whenever they are reloaded.\n *\n * @param callback - Receives the list of active flag keys and a map of key → variant\n * @returns An unsubscribe function — call it to stop listening\n */\n onFeatureFlags = (\n callback: (flags: string[], variants: Record<string, string | boolean>) => void\n ): (() => void) => {\n if (!this.has_initialized) return () => {}\n\n try {\n this.log('onFeatureFlags | subscribing to feature flag changes')\n const unsubscribe = posthog.onFeatureFlags(callback)\n return typeof unsubscribe === 'function' ? unsubscribe : () => {}\n } catch (error) {\n console.error('Posthog: Failed to subscribe to feature flags', error)\n return () => {}\n }\n }\n\n /**\n * Force PostHog to reload feature flags from the server.\n * Useful after login, logout, or any attribute change that may affect targeting.\n */\n reloadFeatureFlags = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reloadFeatureFlags | reloading feature flags')\n posthog.reloadFeatureFlags()\n } catch (error) {\n console.error('Posthog: Failed to reload feature flags', error)\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/providers/posthog.ts"],"names":["_Posthog","options","debug","createLogger","currentApiKey","currentCookieName","staleCookies","c","name","hostname","domainParts","rootDomain","domain","domainAttr","deleted","apiKey","api_host","config","posthog","resolvedApiHost","getPosthogApiHost","posthogConfig","posthogUiHost","event","eventMs","now","currentHost","allowedDomains","fns","result","fn","error","currentDistinctId","nextUserId","caller","user_id","traits","email","language","country_of_residence","alreadyIdentified","updates","isInternalEmail","event_name","properties","key","raw","entry","callback","unsubscribe","id","Posthog"],"mappings":"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","file":"index.mjs","sourcesContent":["import posthog from 'posthog-js'\nimport type { TPosthogConfig, TPosthogIdentifyTraits, TPosthogOptions } from './posthogTypes'\nimport { allowedDomains, getPosthogApiHost, posthogUiHost } from '../utils/urls'\nimport { createLogger, isInternalEmail } from '../utils/helpers'\n\n/**\n * PostHog analytics wrapper with singleton pattern.\n * Provides optional PostHog integration for event tracking and session recording.\n *\n * Features:\n * - Dynamically loads PostHog SDK on demand\n * - Domain allowlisting for security\n * - Automatic user identification with client_id enforcement\n * - client_id backfill for previously identified users via backfillPersonProperties\n * - Custom event tracking with property sanitization\n * - Built-in caching and retry mechanisms (handled by posthog-js library)\n *\n * Note: PostHog handles its own event queuing, caching, and retry logic internally.\n * No additional caching is needed at the wrapper level.\n */\nexport class Posthog {\n has_initialized = false\n has_identified = false\n private static _instance: Posthog\n // Survives re-instantiation — covers hot reload and multiple module copies.\n // posthog.__loaded is checked as a secondary guard for cases where this\n // static field is reset but posthog-js already has a live instance (e.g.\n // duplicate module bundles in micro-frontends).\n private static _hasLoaded = false\n private static readonly ILLEGAL_IDS = new Set([\n 'restored',\n 'null',\n 'undefined',\n 'anonymous',\n 'guest',\n 'distinctid',\n 'distinct_id',\n 'id',\n 'not_authenticated',\n 'email',\n 'true',\n 'false',\n '0',\n 'none',\n 'nan',\n ])\n private options: TPosthogOptions\n private debug = false\n private log = createLogger('[PostHog]', () => this.debug)\n\n constructor(options: TPosthogOptions, debug = false) {\n this.options = options\n this.debug = debug\n this.init()\n }\n\n /**\n * Get or create the singleton instance of Posthog\n * @param options - PostHog configuration options including API key\n * @param debug - Enable debug logging\n * @returns The Posthog singleton instance\n */\n public static getPosthogInstance = (options: TPosthogOptions, debug = false): Posthog => {\n if (!Posthog._instance) {\n Posthog._instance = new Posthog(options, debug)\n } else if (options.apiKey && options.apiKey !== Posthog._instance.options.apiKey) {\n console.warn('Posthog: getPosthogInstance called with a different API key — returning existing instance')\n }\n return Posthog._instance\n }\n\n /**\n * Remove stale PostHog cookies that don't belong to the current project key.\n * PostHog sets cookies named `ph_{apiKey}_posthog` — if multiple project keys\n * have been used in the same browser, old cookies pile up and should be cleaned.\n */\n private cleanupStalePosthogCookies = (currentApiKey: string): void => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n\n const currentCookieName = `ph_${currentApiKey}_posthog`\n const staleCookies = document.cookie\n .split(';')\n .map(c => c.trim().split('=')[0] ?? '')\n .filter(name => /^ph_.+_posthog$/.test(name) && name !== currentCookieName)\n\n if (staleCookies.length === 0) return\n\n const hostname = window.location.hostname\n const domainParts = hostname.split('.')\n // TLD+2 assumption: works for deriv.com → .deriv.com but would produce\n // .co.uk for app.deriv.co.uk. Acceptable for current Deriv domains.\n const rootDomain = domainParts.length >= 2 ? `.${domainParts.slice(-2).join('.')}` : hostname\n\n staleCookies.forEach(name => {\n // Try deleting with root domain, subdomain, and no domain\n ;[rootDomain, hostname, ''].forEach(domain => {\n const domainAttr = domain ? `; Domain=${domain}` : ''\n document.cookie = `${name}=; path=/${domainAttr}; max-age=0; SameSite=Lax`\n })\n const deleted = !document.cookie.split(';').some(c => c.trim().startsWith(`${name}=`))\n this.log(`cleanupStalePosthogCookies | ${deleted ? 'removed' : 'failed to remove'} stale cookie: ${name}`)\n })\n }\n\n /**\n * Initialize PostHog with configuration\n * Configures PostHog instance with provided options\n */\n init = (): void => {\n try {\n const { apiKey, api_host, config = {} } = this.options\n\n if (!apiKey) {\n console.warn('Posthog: No API key provided')\n return\n }\n\n if (Posthog._hasLoaded || (posthog as any).__loaded) {\n this.log('init | PostHog already initialized, skipping re-init')\n this.has_initialized = true\n return\n }\n\n this.cleanupStalePosthogCookies(apiKey)\n\n const resolvedApiHost = api_host || getPosthogApiHost()\n this.log('init | loading PostHog SDK', { api_host: resolvedApiHost })\n\n const posthogConfig: TPosthogConfig = {\n // Overridable defaults — consumers can override these via config\n api_host: resolvedApiHost,\n ui_host: posthogUiHost,\n // Scope autocapture to clicks only. Default also captures input changes and\n // form submissions which, on a high-frequency trading SPA, contributes to\n // burst-limit hits.\n autocapture: { dom_event_allowlist: ['click'] },\n // Pin rate limits explicitly so SDK default changes don't silently affect us.\n rate_limiting: {\n events_per_second: 10,\n events_burst_limit: 100,\n },\n ...config,\n\n // ── Enforced after consumer spread ─────────────────────────────────────\n person_profiles: 'identified_only',\n // 'history_change' fires $pageview on every pushState/replaceState (SPA-friendly).\n // Consumers must NOT also call posthog.capture('$pageview') manually — that\n // causes a duplicate on every navigation and hits the burst rate limit.\n capture_pageview: 'history_change',\n capture_pageleave: true,\n session_recording: {\n ...config.session_recording,\n recordCrossOriginIframes: true,\n minimumDurationMilliseconds: 30000,\n maskAllInputs: true,\n },\n before_send: event => {\n // SSR guard — note: this drops all server-side events.\n // If consumers ever use SSR (Next.js, Nuxt), move domain check\n // to runtime and remove the window guard from the timestamp filter.\n if (typeof window === 'undefined' || !event) return null\n\n if (event.timestamp) {\n const sevenDaysMs = 7 * 24 * 60 * 60 * 1000\n const eventMs = event.timestamp.getTime()\n const now = Date.now()\n if (eventMs < now - sevenDaysMs || eventMs > now + sevenDaysMs) {\n this.log('init | before_send dropped event with bad timestamp', {\n event: event.event,\n timestamp: event.timestamp.toISOString(),\n })\n return null\n }\n }\n\n const currentHost = window.location.hostname\n if (currentHost !== 'localhost' && currentHost !== '127.0.0.1') {\n const isAllowed = allowedDomains.some(\n domain => currentHost.endsWith(`.${domain}`) || currentHost === domain\n )\n if (!isAllowed) {\n this.log('init | before_send blocked event from disallowed host', { currentHost })\n return null\n }\n }\n\n if (config.before_send) {\n const fns = Array.isArray(config.before_send) ? config.before_send : [config.before_send]\n let result: typeof event | null = event\n for (const fn of fns) {\n result = result ? fn(result) : null\n }\n return result\n }\n return event\n },\n }\n\n // Initialize PostHog\n posthog.init(apiKey, posthogConfig)\n Posthog._hasLoaded = true\n this.has_initialized = true\n this.log('init | PostHog SDK loaded successfully')\n } catch (error) {\n console.error('Posthog: Failed to initialize', error)\n }\n }\n\n private static isAnonymousId = (id: string | undefined | null): boolean => {\n if (!id) return true\n // Hard-coded UUID v4 pattern — matches posthog-js anonymous ID format.\n // Verify after major posthog-js version bumps; a changed format would treat\n // new anonymous IDs as identified and trigger spurious resets on every login.\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)\n }\n\n private resetIfStaleId = (\n currentDistinctId: string | undefined | null,\n nextUserId: string,\n caller: string\n ): void => {\n if (!Posthog.isAnonymousId(currentDistinctId)) {\n this.log(`${caller} | stale identified user, resetting`, {\n previous: currentDistinctId,\n next: nextUserId,\n })\n posthog.reset()\n }\n }\n\n /**\n * Identify a user with PostHog.\n * Skipped if the user is already identified — use backfillPersonProperties to backfill\n * client_id for users identified in previous sessions.\n *\n * @param user_id - The user ID to identify\n * @param traits - User properties (language, country_of_residence, etc.)\n */\n identifyEvent = (user_id: string, traits: TPosthogIdentifyTraits = {}): void => {\n if (!this.has_initialized) {\n console.warn('Posthog: Cannot identify - not initialized')\n return\n }\n\n try {\n if (!user_id || !user_id.trim() || Posthog.ILLEGAL_IDS.has(user_id.toLowerCase())) {\n this.log('identifyEvent | skipped — invalid user_id', { user_id })\n return\n }\n\n const currentDistinctId = posthog.get_distinct_id()\n\n if (currentDistinctId === user_id) {\n this.log('identifyEvent | skipped — user already identified', { user_id })\n return\n }\n\n // If PostHog holds a different identified user's ID (not an anonymous UUID),\n // reset first to prevent profile merging between accounts.\n this.resetIfStaleId(currentDistinctId, user_id, 'identifyEvent')\n\n this.log('identifyEvent | identifying user', { user_id, traits })\n posthog.identify(user_id, {\n ...traits,\n client_id: user_id,\n })\n this.has_identified = true\n } catch (error) {\n console.error('Posthog: Failed to identify user', error)\n }\n }\n\n /**\n * Reset PostHog state\n * Clears user identification and resets the instance\n */\n reset = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reset | resetting PostHog session')\n posthog.reset()\n this.has_identified = false\n } catch (error) {\n console.error('Posthog: Failed to reset', error)\n }\n }\n\n /**\n * Ensure client_id is set in PostHog stored person properties.\n * Call this when the user ID is available and PostHog is loaded.\n * No-op if client_id is already present.\n *\n * @param params.user_id - The user ID to use as client_id\n * @param params.email - The user's email, used to determine is_internal\n * @param params.language - The user's language (BCP 47 tag, e.g. \"en-GB\")\n * @param params.country_of_residence - The user's country of residence\n */\n backfillPersonProperties = ({\n user_id,\n email,\n language,\n country_of_residence,\n }: {\n user_id: string\n email?: string\n language?: string\n country_of_residence?: string\n }): void => {\n if (!this.has_initialized || !user_id) return\n\n if (!user_id.trim() || Posthog.ILLEGAL_IDS.has(user_id.toLowerCase())) {\n this.log('backfillPersonProperties | skipped — invalid user_id', { user_id })\n return\n }\n\n try {\n const currentDistinctId = posthog.get_distinct_id()\n const alreadyIdentified = currentDistinctId === user_id\n\n // Reset stale identity FIRST — otherwise property reads below see the previous\n // user's cached values and we may early-return without identifying the new user.\n if (!alreadyIdentified) {\n this.resetIfStaleId(currentDistinctId, user_id, 'backfillPersonProperties')\n }\n\n const updates: Record<string, any> = {}\n\n // Falsy is correct for string-valued properties; '' is not a valid value and also warrants a rewrite.\n // is_internal uses == null because false is a legitimate value that must not be overwritten.\n if (!posthog.get_property('client_id')) {\n updates.client_id = user_id\n }\n if (email && posthog.get_property('is_internal') == null) {\n updates.is_internal = isInternalEmail(email)\n }\n if (language && !posthog.get_property('language')) {\n updates.language = language\n }\n if (country_of_residence && !posthog.get_property('country_of_residence')) {\n updates.country_of_residence = country_of_residence\n }\n\n if (alreadyIdentified) {\n if (Object.keys(updates).length === 0) {\n this.log('backfillPersonProperties | skipped — all properties already present', { user_id })\n return\n }\n this.log('backfillPersonProperties | backfilling person properties', { user_id, updates })\n posthog.setPersonProperties(updates)\n } else {\n // Always identify after a potential reset — ensures client_id lands even if persistence was cleared.\n if (!updates.client_id) updates.client_id = user_id\n this.log('backfillPersonProperties | user not identified, identifying now', { user_id, updates })\n posthog.identify(user_id, updates)\n this.has_identified = true\n }\n } catch (error) {\n console.error('Posthog: Failed to backfill person properties', error)\n }\n }\n\n /**\n * Capture a custom event with properties\n * Properties are pre-flattened and cleaned by analytics.ts before being passed here\n *\n * @param event_name - The name of the event to track\n * @param properties - Event properties including core attributes (already flattened and cleaned)\n */\n capture = (event_name: string, properties?: Record<string, any>): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('capture | sending event to PostHog', { event_name, properties })\n posthog.capture(event_name, properties)\n } catch (error) {\n console.error('Posthog: Failed to capture event', error)\n }\n }\n\n /**\n * Check whether a feature flag is enabled for the current user.\n *\n * @param key - The feature flag key\n * @returns true/false, or undefined if PostHog is not ready\n */\n isFeatureEnabled = (key: string): boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.isFeatureEnabled(key)\n this.log('isFeatureEnabled', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to check feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the value of a feature flag.\n * Returns a string variant for multivariate flags, true/false for boolean flags,\n * or undefined if the flag does not exist or PostHog is not ready.\n *\n * @param key - The feature flag key\n */\n getFeatureFlag = (key: string): string | boolean | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlag(key)\n this.log('getFeatureFlag', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag', error)\n return undefined\n }\n }\n\n /**\n * Get the JSON payload associated with a feature flag.\n * Payloads allow attaching structured metadata (e.g. config objects) to a flag.\n *\n * @param key - The feature flag key\n */\n getFeatureFlagPayload = (\n key: string\n ): string | number | boolean | null | Record<string, unknown> | unknown[] | undefined => {\n if (!this.has_initialized) return undefined\n\n try {\n const result = posthog.getFeatureFlagResult(key)?.payload as\n | string\n | number\n | boolean\n | null\n | Record<string, unknown>\n | unknown[]\n | undefined\n this.log('getFeatureFlagPayload', { key, result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get feature flag payload', error)\n return undefined\n }\n }\n\n /**\n * Get all currently active feature flags and their values.\n *\n * @returns A map of flag key → value (boolean or string variant)\n */\n getAllFlags = (): Record<string, string | boolean> => {\n if (!this.has_initialized) return {}\n\n try {\n // NOTE: featureFlags and getFlagVariants() are internal posthog-js APIs.\n // Verify after major SDK version bumps.\n const raw = posthog.featureFlags?.getFlagVariants() ?? {}\n // FeatureFlagValue includes null/undefined for disabled/unresolved flags;\n // filter them out to honour the declared return type.\n const result = Object.fromEntries(\n Object.entries(raw).filter((entry): entry is [string, string | boolean] => entry[1] != null)\n )\n this.log('getAllFlags', { result })\n return result\n } catch (error) {\n console.error('Posthog: Failed to get all feature flags', error)\n return {}\n }\n }\n\n /**\n * Subscribe to feature flag changes.\n * The callback fires immediately with the current flags and again whenever they are reloaded.\n *\n * @param callback - Receives the list of active flag keys and a map of key → variant\n * @returns An unsubscribe function — call it to stop listening\n */\n onFeatureFlags = (\n callback: (flags: string[], variants: Record<string, string | boolean>) => void\n ): (() => void) => {\n if (!this.has_initialized) return () => {}\n\n try {\n this.log('onFeatureFlags | subscribing to feature flag changes')\n const unsubscribe = posthog.onFeatureFlags(callback)\n return typeof unsubscribe === 'function' ? unsubscribe : () => {}\n } catch (error) {\n console.error('Posthog: Failed to subscribe to feature flags', error)\n return () => {}\n }\n }\n\n /**\n * Force PostHog to reload feature flags from the server.\n * Useful after login, logout, or any attribute change that may affect targeting.\n */\n reloadFeatureFlags = (): void => {\n if (!this.has_initialized) return\n\n try {\n this.log('reloadFeatureFlags | reloading feature flags')\n posthog.reloadFeatureFlags()\n } catch (error) {\n console.error('Posthog: Failed to reload feature flags', error)\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deriv-com/analytics",
3
- "version": "1.42.0",
3
+ "version": "1.42.1",
4
4
  "description": "Comprehensive analytics package for Deriv applications. Provides unified event tracking, A/B testing, and user analytics through RudderStack, PostHog and GrowthBook integrations with built-in caching and offline support.",
5
5
  "keywords": [
6
6
  "rudderstack",