@ohos-ports/s-ui-segment-wrapper 0.0.0-stage → 5.4.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +269 -2
  2. package/lib/config.js +20 -0
  3. package/lib/events.js +3 -0
  4. package/lib/index.js +82 -0
  5. package/lib/middlewares/destination/optimizelySiteAttribute.js +17 -0
  6. package/lib/middlewares/source/campaignContext.js +10 -0
  7. package/lib/middlewares/source/defaultContextProperties.js +11 -0
  8. package/lib/middlewares/source/optimizelyUserId.js +15 -0
  9. package/lib/middlewares/source/pageData.js +42 -0
  10. package/lib/middlewares/source/pageReferrer.js +102 -0
  11. package/lib/middlewares/source/userScreenInfo.js +12 -0
  12. package/lib/middlewares/source/userTraits.js +48 -0
  13. package/lib/repositories/googleRepository.js +272 -0
  14. package/lib/repositories/xandrRepository.js +42 -0
  15. package/lib/segmentWrapper.js +364 -0
  16. package/lib/tcf.js +230 -0
  17. package/lib/universalId.js +48 -0
  18. package/lib/utils/checkAnonymousId.js +9 -0
  19. package/lib/utils/cookies.js +50 -0
  20. package/lib/utils/ga4Detection.js +18 -0
  21. package/lib/utils/hashEmail.js +24 -0
  22. package/lib/utils/patchAnalytics.js +36 -0
  23. package/lib/utils/storage.js +17 -0
  24. package/package.json +39 -4
  25. package/src/config.js +25 -0
  26. package/src/events.js +3 -0
  27. package/src/index.js +96 -0
  28. package/src/middlewares/destination/optimizelySiteAttribute.js +22 -0
  29. package/src/middlewares/source/campaignContext.js +12 -0
  30. package/src/middlewares/source/defaultContextProperties.js +15 -0
  31. package/src/middlewares/source/optimizelyUserId.js +20 -0
  32. package/src/middlewares/source/pageData.js +45 -0
  33. package/src/middlewares/source/pageReferrer.js +125 -0
  34. package/src/middlewares/source/userScreenInfo.js +11 -0
  35. package/src/middlewares/source/userTraits.js +41 -0
  36. package/src/repositories/googleRepository.js +251 -0
  37. package/src/repositories/xandrRepository.js +48 -0
  38. package/src/segmentWrapper.js +338 -0
  39. package/src/tcf.js +263 -0
  40. package/src/universalId.js +51 -0
  41. package/src/utils/checkAnonymousId.js +10 -0
  42. package/src/utils/cookies.js +56 -0
  43. package/src/utils/ga4Detection.js +22 -0
  44. package/src/utils/hashEmail.js +33 -0
  45. package/src/utils/patchAnalytics.js +46 -0
  46. package/src/utils/storage.js +18 -0
  47. package/src-umd/index.js +8 -0
  48. package/umd/index.js +1 -0
package/README.md CHANGED
@@ -1,3 +1,270 @@
1
- # Temporary Holding Version
1
+ # Segment Wrapper
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ This package adds an abstraction layer on top of [segment.com](https://segment.com/)'s [JavaScript library](https://segment.com/docs/sources/website/analytics.js/) with some useful integrations and fixes:
4
+
5
+ **Data Quality 📈**
6
+
7
+ - [x] Add `page` method that internally uses `track` but with the correct `referrer` property.
8
+ - [x] Send `user.id` and `anonymousId` on every track.
9
+
10
+ **Consent Management Platform 🐾**
11
+
12
+ - [x] Automatic tracking of Consent Management Platform usage.
13
+ - [x] Send `gdpr_privacy` on `context` for for all tracking events. Expect values: `unknown`, `accepted` and `declined`.
14
+ - [x] Send `gdpr_privacy_advertising` on `context` for for all tracking events. Expect values: `unknown`, `accepted` and `declined`.
15
+ - [x] `gdpr_privacy` is accepted when consents [1, 8, 10] are accepted and `gdpr_privacy_advertising` is accepted when consents [3] is accepted.
16
+ - [x] Any track is sent if the user has not accepted/rejected any consent yet.
17
+
18
+ **Developer Experience 👩‍💻**
19
+
20
+ - [x] Always send `platform` property as `web`.
21
+ - [x] Allow to configure `window.__mpi.defaultContext` to send these properties on all tracks inside the context object.
22
+ - [x] Allow to configure `window.__mpi.defaultProperties` to send these properties on all tracks.
23
+
24
+ **Segment Middlewares 🖖**
25
+
26
+ - [x] Optimizely Full Stack middleware to use Segment's anonymousId as Optimizely's userId, more info [here](#optimizelys-userid).
27
+
28
+ ## Usage
29
+
30
+ After adding your Segment snippet into your html, you'll need to include this package in order to be able to fire events.
31
+
32
+ `analytics` will be an object with the methods described [here](#events).
33
+
34
+ ### Step 1: Copy the Snippet in your HTML
35
+
36
+ ```html
37
+ <script>
38
+ !(function () {
39
+ var analytics = (window.analytics = window.analytics || [])
40
+ if (!analytics.initialize)
41
+ if (analytics.invoked) window.console && console.error && console.error('Segment snippet included twice.')
42
+ else {
43
+ analytics.invoked = !0
44
+ analytics.methods = [
45
+ 'trackSubmit',
46
+ 'trackClick',
47
+ 'trackLink',
48
+ 'trackForm',
49
+ 'pageview',
50
+ 'identify',
51
+ 'reset',
52
+ 'group',
53
+ 'track',
54
+ 'ready',
55
+ 'alias',
56
+ 'debug',
57
+ 'page',
58
+ 'once',
59
+ 'off',
60
+ 'on',
61
+ 'addSourceMiddleware',
62
+ 'addIntegrationMiddleware',
63
+ 'setAnonymousId',
64
+ 'addDestinationMiddleware'
65
+ ]
66
+ analytics.factory = function (e) {
67
+ return function () {
68
+ var t = Array.prototype.slice.call(arguments)
69
+ t.unshift(e)
70
+ analytics.push(t)
71
+ return analytics
72
+ }
73
+ }
74
+ for (var e = 0; e < analytics.methods.length; e++) {
75
+ var key = analytics.methods[e]
76
+ analytics[key] = analytics.factory(key)
77
+ }
78
+ analytics.load = function (key, e) {
79
+ var t = document.createElement('script')
80
+ t.type = 'text/javascript'
81
+ t.async = !0
82
+ t.src = 'https://cdn.segment.com/analytics.js/v1/' + key + '/analytics.min.js'
83
+ var n = document.getElementsByTagName('script')[0]
84
+ n.parentNode.insertBefore(t, n)
85
+ analytics._loadOptions = e
86
+ }
87
+ analytics._writeKey = 'YOUR_WRITE_KEY'
88
+ analytics.SNIPPET_VERSION = '4.13.2'
89
+
90
+ analytics.load('YOUR_WRITE_KEY') // your write key must be set here
91
+ }
92
+ })()
93
+ </script>
94
+ ```
95
+
96
+ ### Step 2: Use
97
+
98
+ #### In your modern and beautiful JavaScript...
99
+
100
+ ```js
101
+ import analytics from '@s-ui/segment-wrapper'
102
+ ```
103
+
104
+ ### In your monolithic JavaScript...
105
+
106
+ ```js
107
+ // First load the UMD module.
108
+ <script src="https://unpkg.com/@s-ui/segment-wrapper/umd/index.js"></script>
109
+ <script>
110
+ // Then trigger all the events you need referencing the right namespaced
111
+ // object: `window.sui.analytics`. For more info see the "Events" section below.
112
+ window.sui.analytics.identify('your user id', {});
113
+ window.sui.analytics.track('your event', {});
114
+ window.sui.analytics.reset();
115
+ </script>
116
+ ```
117
+
118
+ ### Step 3: Configure Segment Wrapper (optional)
119
+
120
+ You could put a special config in a the `window.__mpi` to change some behaviour of the wrapper. This config MUST somewhere before using the Segment Wrapper.
121
+
122
+ - `defaultContext`: _(optional)_ If set, properties will be merged and sent with every `track` and `page` in the **context object**. It's the ideal place to put the `site` and `vertical` info to make sure that static info will be sent along with all the tracking.
123
+ - `defaultProperties`: _(optional)_ If set, properties will be merged and sent with every `track` and `page`.
124
+ - `tcfTrackDefaultProperties` _(optional)_ If set, this property will be merged together with the default properties set to send with every tcf track event
125
+ - `universalId`: _(optional)_ If set this value will be used for the Visitor API and other services.
126
+ - `hashedUserEmail`: _(optional)_ If set and not `universalId` is set this value will be used for the Visitor API and other services.
127
+ - `userEmail`: _(optional)_ If set and not `universalId` is available, this value will be hashed with SHA-256 and used for the Visitor API and other services.
128
+ - `isUserTraitsEnabled`: _(optional)_ If set context traits will be populated with all user traits.
129
+ - `userIdPrefix`: _(optional)_ If set, the user id will be prefixed with this string for identify events.
130
+
131
+ Example:
132
+
133
+ ```js
134
+ window.__mpi = {
135
+ segmentWrapper: {
136
+ universalId: '7ab9ddf3281d5d5458a29e8b3ae2864',
137
+ defaultContext: {
138
+ site: 'patinetes',
139
+ vertical: 'motor'
140
+ },
141
+ tcfTrackDefaultProperties: {
142
+ tcfSpecialProp: 'anyvalue'
143
+ }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### It also provides additional information such as:
149
+
150
+ - window.\_\_mpi.isFirstVisit: boolean - true if the user hasn't interacted with the tcf modal yet
151
+
152
+ ## Events
153
+
154
+ ### Track - [docs](https://segment.com/docs/spec/track/)
155
+
156
+ ```js
157
+ import analytics from '@s-ui/segment-wrapper'
158
+
159
+ analytics.track('CTA Clicked')
160
+
161
+ analytics.track('Registered', {
162
+ plan: 'Pro Annual',
163
+ accountType: 'Facebook'
164
+ })
165
+ ```
166
+
167
+ ### Page
168
+
169
+ Internally uses `Track` but changes the `referrer` everytime is called.
170
+
171
+ ```js
172
+ import analytics from '@s-ui/segment-wrapper'
173
+
174
+ analytics.page('Home Viewed')
175
+
176
+ analytics.page('List Viewed', {
177
+ property: 'HOUSE',
178
+ transaction: 'SELL'
179
+ })
180
+ ```
181
+
182
+ ### Identify - [docs](https://segment.com/docs/spec/identify/)
183
+
184
+ ```js
185
+ import analytics from '@s-ui/segment-wrapper'
186
+
187
+ analytics.identify('97980cfea0067', {
188
+ name: 'Peter Gibbons',
189
+ email: 'peter@initech.com',
190
+ plan: 'premium',
191
+ logins: 5
192
+ })
193
+ ```
194
+
195
+ ### Reset - [docs](https://segment.com/docs/sources/website/analytics.js/#reset-logout)
196
+
197
+ ```js
198
+ import analytics from '@s-ui/segment-wrapper'
199
+
200
+ analytics.reset()
201
+ ```
202
+
203
+ ## UniversalID
204
+
205
+ _Segment Wrapper_ is handling all about the UniversalID, an ID to identify the user across different sites by using a hashed email. If you want, you could subscribe yourself to an event in order to retrieve this info:
206
+
207
+ ```js
208
+ document.addEventListener(USER_DATA_READY_EVENT, e => {
209
+ const {universalId} = e.detail
210
+ })
211
+ ```
212
+
213
+ Also, you could check directly if the `universalId` is already available on the window:
214
+
215
+ ```js
216
+ const {universalId} = window.__mpi.segmentWrapper
217
+ ```
218
+
219
+ Or use both systems:
220
+
221
+ ```js
222
+ let {universalId, universalIdInitialized} = window.__mpi.segmentWrapper
223
+
224
+ if (!universalId && !universalIdInitialized) {
225
+ document.addEventListener(USER_DATA_READY_EVENT, e => {
226
+ universalId = e.detail.universalId
227
+ doSomethingWithUniversalId(universalId)
228
+ })
229
+ }
230
+
231
+ console.log(universalId)
232
+ ```
233
+
234
+ ### Send xandrId as externalIds
235
+
236
+ To not send the `xandrId` put this flag as configuration: `window.__mpi.segmentWrapper.sendXandrId = false`
237
+
238
+ By default, all xandrId will be sent.
239
+
240
+ ## Middlewares
241
+
242
+ You can find info about segment's middleware [here](https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/middleware/)
243
+
244
+ ### Optimizely's userId
245
+
246
+ Will use segment's anonymousId as optimizely's userId
247
+
248
+ #### How to
249
+
250
+ ```js
251
+ import {optimizelyUserId} from '@s-ui/segment-wrapper/lib/middlewares/source/optimizelyUserId'
252
+
253
+ window.analytics.ready(() => {
254
+ window.analytics.addSourceMiddleware(optimizelyUserId)
255
+ })
256
+ ```
257
+
258
+ ### Optimizely's site attribute
259
+
260
+ Will add the site property as optimizely attribute
261
+
262
+ #### How to
263
+
264
+ ```js
265
+ import {optimizelySiteAttributeMiddleware} from '@s-ui/segment-wrapper/lib/middlewares/destination/optimizelySiteAttribute'
266
+
267
+ window.analytics.ready(() => {
268
+ window.analytics.addDestinationMiddleware('Optimizely', [optimizelySiteAttributeMiddleware])
269
+ })
270
+ ```
package/lib/config.js ADDED
@@ -0,0 +1,20 @@
1
+ var MPI_CONFIG_KEY = "__mpi";
2
+ export var isClient = typeof window !== "undefined";
3
+ /**
4
+ * Get the Segment Wrapper config from window
5
+ * @param {string=} key Key config to extract. If not provided, all the config will be returned
6
+ * @return {any} Config value or all the config if not key provided
7
+ */ export var getConfig = function(key) {
8
+ var ref;
9
+ var config = (window == null ? void 0 : (ref = window[MPI_CONFIG_KEY]) == null ? void 0 : ref.segmentWrapper) || {};
10
+ return key ? config[key] : config;
11
+ };
12
+ /**
13
+ * Set a config value to the Segment Wrapper config
14
+ * @param {string} key Config key to update
15
+ * @param {boolean|string|number|object} value Value to set on the config key
16
+ */ export var setConfig = function(key, value) {
17
+ window[MPI_CONFIG_KEY] = window[MPI_CONFIG_KEY] || {};
18
+ window[MPI_CONFIG_KEY].segmentWrapper = window[MPI_CONFIG_KEY].segmentWrapper || {};
19
+ window[MPI_CONFIG_KEY].segmentWrapper[key] = value;
20
+ };
package/lib/events.js ADDED
@@ -0,0 +1,3 @@
1
+ export var EVENTS = {
2
+ GA4_INIT_EVENT_SENT: "ga4InitEventSent"
3
+ };
package/lib/index.js ADDED
@@ -0,0 +1,82 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ import "./utils/patchAnalytics.js";
3
+ import { campaignContext } from "./middlewares/source/campaignContext.js";
4
+ import { pageData } from "./middlewares/source/pageData.js";
5
+ import { defaultContextProperties } from "./middlewares/source/defaultContextProperties.js";
6
+ import { pageReferrer } from "./middlewares/source/pageReferrer.js";
7
+ import { userScreenInfo } from "./middlewares/source/userScreenInfo.js";
8
+ import { userTraits } from "./middlewares/source/userTraits.js";
9
+ import { DEFAULT_DATA_LAYER_NAME, getCampaignDetails, loadGoogleAnalytics, sendGoogleConsents } from "./repositories/googleRepository.js";
10
+ import { checkAnonymousId } from "./utils/checkAnonymousId.js";
11
+ import { isGA4DestinationEnabled } from "./utils/ga4Detection.js";
12
+ import { getConfig, isClient } from "./config.js";
13
+ import analytics from "./segmentWrapper.js";
14
+ import initTcfTracking from "./tcf.js";
15
+ import { getUserDataAndNotify } from "./universalId.js";
16
+ // Initialize TCF Tracking with Segment
17
+ initTcfTracking();
18
+ // Generate UniversalId if available
19
+ try {
20
+ getUserDataAndNotify();
21
+ } catch (e) {
22
+ console.error("[segment-wrapper] UniversalID couldn't be initialized") // eslint-disable-line
23
+ ;
24
+ }
25
+ // Initialize middlewares
26
+ var addMiddlewares = function() {
27
+ var experimentalPageDataMiddleware = getConfig("experimentalPageDataMiddleware");
28
+ window.analytics.addSourceMiddleware(userTraits);
29
+ window.analytics.addSourceMiddleware(defaultContextProperties);
30
+ window.analytics.addSourceMiddleware(campaignContext);
31
+ window.analytics.addSourceMiddleware(userScreenInfo);
32
+ window.analytics.addSourceMiddleware(pageReferrer);
33
+ if (experimentalPageDataMiddleware) {
34
+ window.analytics.addSourceMiddleware(pageData);
35
+ }
36
+ };
37
+ if (isClient && window.analytics) {
38
+ // Check GA4 mode synchronously to avoid delaying initialization
39
+ var useSegmentGA4Destination = isGA4DestinationEnabled();
40
+ // Only initialize manual GA4 if destination is not enabled (legacy mode)
41
+ // This runs synchronously to ensure GA4 is ready for first events
42
+ if (!useSegmentGA4Destination) {
43
+ // Legacy behavior: Initialize Google Analytics manually
44
+ var googleAnalyticsMeasurementId = getConfig("googleAnalyticsMeasurementId");
45
+ var dataLayerName = getConfig("googleAnalyticsDataLayer") || DEFAULT_DATA_LAYER_NAME;
46
+ var needsConsentManagement = getConfig("googleAnalyticsConsentManagement");
47
+ if (googleAnalyticsMeasurementId) {
48
+ var googleAnalyticsConfig = getConfig("googleAnalyticsConfig");
49
+ window[dataLayerName] = window[dataLayerName] || [];
50
+ window.gtag = window.gtag || function gtag() {
51
+ window[dataLayerName].push(arguments);
52
+ };
53
+ window.gtag("js", new Date());
54
+ if (needsConsentManagement) sendGoogleConsents();
55
+ window.gtag("config", googleAnalyticsMeasurementId, _extends({
56
+ cookie_prefix: "segment",
57
+ send_page_view: false
58
+ }, googleAnalyticsConfig, getCampaignDetails()));
59
+ loadGoogleAnalytics().catch(function(error) {
60
+ console.error(error);
61
+ });
62
+ }
63
+ }
64
+ window.analytics.ready(checkAnonymousId);
65
+ window.analytics.addSourceMiddleware ? addMiddlewares() : window.analytics.ready(addMiddlewares);
66
+ }
67
+ export default analytics;
68
+ export { getGoogleClientId, getGoogleSessionId } from "./repositories/googleRepository.js";
69
+ export { getUniversalId } from "./universalId.js";
70
+ export { EVENTS } from "./events.js";
71
+ // Deprecated Adobe Analytics functions - kept for backwards compatibility
72
+ // @deprecated Adobe Analytics integration has been removed
73
+ export var getAdobeVisitorData = function() {
74
+ return Promise.resolve({
75
+ trackingServer: "",
76
+ version: ""
77
+ });
78
+ };
79
+ // @deprecated Adobe Analytics integration has been removed
80
+ export var getAdobeMCVisitorID = function() {
81
+ return Promise.resolve("");
82
+ };
@@ -0,0 +1,17 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ export var optimizelySiteAttributeMiddleware = function(param) {
3
+ var payload = param.payload, next = param.next;
4
+ var ref;
5
+ var _obj = payload.obj, integrations = _obj.integrations, context = _obj.context;
6
+ if (!context.site) {
7
+ return next(payload);
8
+ }
9
+ payload.obj.integrations = _extends({}, integrations, {
10
+ Optimizely: _extends({}, integrations.Optimizely, {
11
+ attributes: _extends({
12
+ site: context.site
13
+ }, (ref = integrations.Optimizely) == null ? void 0 : ref.attributes)
14
+ })
15
+ });
16
+ next(payload);
17
+ };
@@ -0,0 +1,10 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ import { getCampaignDetails } from "../../repositories/googleRepository.js";
3
+ export var campaignContext = function(param) {
4
+ var payload = param.payload, next = param.next;
5
+ var campaignDetails = getCampaignDetails({
6
+ needsTransformation: false
7
+ });
8
+ payload.obj.context = _extends({}, payload.obj.context, campaignDetails);
9
+ next(payload);
10
+ };
@@ -0,0 +1,11 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ import { getConfig } from "../../config.js";
3
+ var DEFAULT_CONTEXT = {
4
+ platform: "web"
5
+ };
6
+ export var defaultContextProperties = function(param) {
7
+ var payload = param.payload, next = param.next;
8
+ var defaultContext = getConfig("defaultContext") || {};
9
+ payload.obj.context = _extends({}, DEFAULT_CONTEXT, defaultContext, payload.obj.context);
10
+ next(payload);
11
+ };
@@ -0,0 +1,15 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ export var optimizelyUserId = function(param) {
3
+ var payload = param.payload, next = param.next;
4
+ var integrations = payload.obj.integrations;
5
+ // when integrations.All equals false, destinations are deactivated
6
+ if (integrations.All === false) {
7
+ return next(payload);
8
+ }
9
+ payload.obj.integrations = _extends({}, integrations, {
10
+ Optimizely: _extends({
11
+ userId: window.analytics.user().anonymousId()
12
+ }, integrations.Optimizely)
13
+ });
14
+ next(payload);
15
+ };
@@ -0,0 +1,42 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ export var createPageDataMiddleware = function() {
3
+ var last = null;
4
+ return function(param) {
5
+ var payload = param.payload, next = param.next;
6
+ try {
7
+ var ref;
8
+ var obj = payload.obj;
9
+ var event = obj.event, type = obj.type;
10
+ if (type !== "track") {
11
+ next(payload);
12
+ return;
13
+ }
14
+ if (typeof event === "string" && event.endsWith("Viewed")) {
15
+ var ref1 = obj.properties || {}, name = ref1.page_name, type1 = ref1.page_type;
16
+ last = {
17
+ name: name,
18
+ type: type1
19
+ };
20
+ next(payload);
21
+ return;
22
+ }
23
+ if (!last) {
24
+ next(payload);
25
+ return;
26
+ }
27
+ next(_extends({}, payload, {
28
+ obj: _extends({}, obj, {
29
+ properties: _extends({}, obj.properties, {
30
+ page_name_origin: last.name,
31
+ page_type: ((ref = obj.properties) == null ? void 0 : ref.page_type) || last.type
32
+ })
33
+ })
34
+ }));
35
+ } catch (error) {
36
+ console.error(error) // eslint-disable-line
37
+ ;
38
+ next(payload);
39
+ }
40
+ };
41
+ };
42
+ export var pageData = createPageDataMiddleware();
@@ -0,0 +1,102 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ import { isGA4DestinationEnabled } from "../../utils/ga4Detection.js";
3
+ /**
4
+ * Capture document.referrer at module load time, before Safari ITP can clear it.
5
+ * This ensures the first page event has the real referrer from the external source.
6
+ */ export var INITIAL_DOCUMENT_REFERRER = typeof document !== "undefined" ? document.referrer : "";
7
+ /**
8
+ * Capture window.location.search at module load time, before Safari ITP can
9
+ * strip tracking parameters via redirects.
10
+ */ export var INITIAL_SEARCH_STRING = typeof window !== "undefined" ? window.location.search : "";
11
+ /**
12
+ * Capture initial URL at module load time
13
+ */ var INITIAL_URL = typeof window !== "undefined" ? window.location.href : "";
14
+ export var referrerState = {
15
+ spaReferrer: "",
16
+ referrer: INITIAL_DOCUMENT_REFERRER,
17
+ isFirstPageViewSent: false
18
+ };
19
+ /**
20
+ * Useful wrapper around document and window objects
21
+ */ export var utils = {
22
+ /**
23
+ * @returns {string} The referrer of the document
24
+ */ getDocumentReferrer: function() {
25
+ return document.referrer;
26
+ },
27
+ /**
28
+ * @returns {string} The actual location with protocol, domain and pathname
29
+ */ getActualLocation: function() {
30
+ var _location = window.location, origin = _location.origin, pathname = _location.pathname;
31
+ return "" + origin + pathname;
32
+ },
33
+ /**
34
+ * @returns {string} The actual query string captured at module load (protected from Safari ITP)
35
+ */ getActualQueryString: function() {
36
+ // In tests using window.history.pushState, return current search if different from initial
37
+ if (typeof window !== "undefined" && window.location.search && window.location.search !== INITIAL_SEARCH_STRING) {
38
+ return window.location.search;
39
+ }
40
+ return INITIAL_SEARCH_STRING;
41
+ }
42
+ };
43
+ /**
44
+ * Get the correct page referrer for SPA navigations
45
+ * @returns {string} referrer
46
+ */ export var getPageReferrer = function(param) {
47
+ var ref = param === void 0 ? {} : param, _isPageTrack = ref.isPageTrack, isPageTrack = _isPageTrack === void 0 ? false : _isPageTrack;
48
+ var referrer = referrerState.referrer, spaReferrer = referrerState.spaReferrer;
49
+ if (isPageTrack) {
50
+ // For page events, use referrer (initially from INITIAL_DOCUMENT_REFERRER, then from previous page location)
51
+ return referrer;
52
+ } else {
53
+ // For track events, use spaReferrer if available, otherwise fall back to referrer
54
+ // This handles the case where a track happens before the first page event
55
+ return spaReferrer || referrer;
56
+ }
57
+ };
58
+ /**
59
+ * Update page referrer for SPA navigations
60
+ */ export var updatePageReferrer = function() {
61
+ referrerState.spaReferrer = getPageReferrer({
62
+ isPageTrack: true
63
+ });
64
+ // mutate actualReferrer with what will be the new referrer
65
+ referrerState.referrer = utils.getActualLocation();
66
+ };
67
+ /**
68
+ * @param {object} params
69
+ * @param {{obj: {context: object }}} params.payload
70
+ * @param {function} params.next
71
+ * @returns {void}
72
+ */ export var pageReferrer = function(param) {
73
+ var payload = param.payload, next = param.next;
74
+ var context = payload.obj.context;
75
+ var isPageTrack = context.isPageTrack;
76
+ var referrer = getPageReferrer({
77
+ isPageTrack: isPageTrack
78
+ });
79
+ var props = {};
80
+ if (isPageTrack && !referrerState.isFirstPageViewSent) {
81
+ referrerState.isFirstPageViewSent = true;
82
+ props = {
83
+ url: INITIAL_URL,
84
+ search: INITIAL_SEARCH_STRING
85
+ };
86
+ }
87
+ payload.obj.context = _extends({}, context, {
88
+ page: _extends({}, context.page, props, {
89
+ referrer: referrer
90
+ })
91
+ });
92
+ // In NEW mode (client-side destination), also add referrer to properties
93
+ // GA4 Web destination uses properties.page_referrer for attribution
94
+ if (referrer && isGA4DestinationEnabled()) {
95
+ payload.obj.properties = _extends({}, payload.obj.properties, {
96
+ page_referrer: referrer
97
+ });
98
+ }
99
+ // update page referrer only if it's a page event
100
+ isPageTrack && updatePageReferrer();
101
+ next(payload);
102
+ };
@@ -0,0 +1,12 @@
1
+ import _extends from "@swc/helpers/src/_extends.mjs";
2
+ export var userScreenInfo = function(param) {
3
+ var payload = param.payload, next = param.next;
4
+ payload.obj.context = _extends({}, payload.obj.context, {
5
+ screen: {
6
+ height: window.innerHeight,
7
+ width: window.innerWidth,
8
+ density: window.devicePixelRatio
9
+ }
10
+ });
11
+ next(payload);
12
+ };
@@ -0,0 +1,48 @@
1
+ import _async_to_generator from "@swc/helpers/src/_async_to_generator.mjs";
2
+ import _extends from "@swc/helpers/src/_extends.mjs";
3
+ import _ts_generator from "@swc/helpers/src/_ts_generator.mjs";
4
+ import { getConfig } from "../../config.js";
5
+ import { checkAnalyticsGdprIsAccepted, getGdprPrivacyValue } from "../../tcf.js";
6
+ /**
7
+ * Get user traits from global analytics object and put in the object
8
+ * @param {string} gdprPrivacyValue Determine if we have user consents
9
+ * @returns {object} User traits with to add
10
+ */ var getUserTraits = function(gdprPrivacyValue) {
11
+ var isUserTraitsEnabled = getConfig("isUserTraitsEnabled");
12
+ var user = window.analytics.user();
13
+ var isGdprAccepted = checkAnalyticsGdprIsAccepted(gdprPrivacyValue);
14
+ var userId = user.id();
15
+ return _extends({
16
+ anonymousId: user.anonymousId()
17
+ }, userId && {
18
+ userId: userId
19
+ }, isGdprAccepted && isUserTraitsEnabled && user.traits());
20
+ };
21
+ export var userTraits = /*#__PURE__*/ _async_to_generator(function(param) {
22
+ var payload, next, gdprPrivacyValue, userTraits;
23
+ return _ts_generator(this, function(_state) {
24
+ switch(_state.label){
25
+ case 0:
26
+ payload = param.payload, next = param.next;
27
+ return [
28
+ 4,
29
+ getGdprPrivacyValue()
30
+ ];
31
+ case 1:
32
+ gdprPrivacyValue = _state.sent();
33
+ try {
34
+ userTraits = getUserTraits(gdprPrivacyValue);
35
+ } catch (error) {
36
+ console.error(error) // eslint-disable-line
37
+ ;
38
+ }
39
+ payload.obj.context = _extends({}, payload.obj.context, {
40
+ traits: _extends({}, payload.obj.context.traits, userTraits)
41
+ });
42
+ next(payload);
43
+ return [
44
+ 2
45
+ ];
46
+ }
47
+ });
48
+ });