@codecademy/tracking 1.0.2 → 1.0.3-alpha.37044bcdd.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 (34) hide show
  1. package/dist/README.md +100 -0
  2. package/dist/events/index.d.ts +3 -3
  3. package/dist/events/track.d.ts +12 -12
  4. package/dist/events/types.d.ts +250 -250
  5. package/dist/events/user.d.ts +2 -2
  6. package/dist/index.cjs +711 -0
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +595 -3
  9. package/dist/integrations/conditionallyLoadAnalytics.d.ts +9 -9
  10. package/dist/integrations/consent.d.ts +9 -9
  11. package/dist/integrations/device.d.ts +13 -13
  12. package/dist/integrations/fetchDestinationsForWriteKey.d.ts +6 -6
  13. package/dist/integrations/getConsentDecision.d.ts +8 -8
  14. package/dist/integrations/index.d.ts +31 -31
  15. package/dist/integrations/mapDestinations.d.ts +13 -13
  16. package/dist/integrations/onetrust.d.ts +6 -6
  17. package/dist/integrations/runSegmentSnippet.d.ts +7 -7
  18. package/dist/integrations/types.d.ts +24 -24
  19. package/dist/package.json +21 -0
  20. package/package.json +2 -2
  21. package/dist/events/index.js +0 -3
  22. package/dist/events/track.js +0 -115
  23. package/dist/events/types.js +0 -1
  24. package/dist/events/user.js +0 -41
  25. package/dist/integrations/conditionallyLoadAnalytics.js +0 -27
  26. package/dist/integrations/consent.js +0 -11
  27. package/dist/integrations/device.js +0 -25
  28. package/dist/integrations/fetchDestinationsForWriteKey.js +0 -88
  29. package/dist/integrations/getConsentDecision.js +0 -32
  30. package/dist/integrations/index.js +0 -90
  31. package/dist/integrations/mapDestinations.js +0 -55
  32. package/dist/integrations/onetrust.js +0 -53
  33. package/dist/integrations/runSegmentSnippet.js +0 -64
  34. package/dist/integrations/types.js +0 -1
package/dist/index.js CHANGED
@@ -1,3 +1,595 @@
1
- export * from './integrations';
2
- export * from './events';
3
- export {};
1
+ /**
2
+ * @returns Whether the site is running both in ChromeOS and in PWA mode.
3
+ */
4
+ const isChromeOSPWA = () => isChromeOS() && 'getDigitalGoodsService' in window && // https://stackoverflow.com/questions/41742390/javascript-to-check-if-pwa-or-mobile-web
5
+ window.matchMedia('(display-mode: standalone)').matches;
6
+ /**
7
+ * @returns Whether the site is running in ChromeOS
8
+ */
9
+
10
+ const isChromeOS = () => typeof navigator !== 'undefined' && // https://stackoverflow.com/questions/29657165/detecting-chrome-os-with-javascript
11
+ /\bCrOS\b/.test(navigator.userAgent);
12
+ var ClientTypes;
13
+
14
+ (function (ClientTypes) {
15
+ ClientTypes["PWA"] = "pwa";
16
+ ClientTypes["Default"] = "default";
17
+ })(ClientTypes || (ClientTypes = {}));
18
+
19
+ const getClientType = () => isChromeOSPWA() ? ClientTypes.PWA : ClientTypes.Default;
20
+
21
+ const conditionallyLoadAnalytics = ({
22
+ analytics,
23
+ destinationPreferences,
24
+ identifyPreferences,
25
+ user,
26
+ writeKey
27
+ }) => {
28
+ if (analytics.initialize) {
29
+ return;
30
+ }
31
+
32
+ analytics.load(writeKey, {
33
+ integrations: destinationPreferences
34
+ });
35
+ analytics.page();
36
+
37
+ if (user) {
38
+ const identifyParams = {
39
+ email: user.email,
40
+ client: getClientType()
41
+ };
42
+ analytics.identify(user.id, identifyParams, {
43
+ integrations: identifyPreferences
44
+ });
45
+ }
46
+ };
47
+
48
+ const knownFetchFailures = ['Failed to fetch', 'Load failed', 'NetworkError when attempting to fetch resource', 'Resource blocked by content blocker'];
49
+ const fetchDestinationsForWriteKey = async ({
50
+ writeKey,
51
+ onError
52
+ }) => {
53
+ const filteredOnError = error => {
54
+ if (!knownFetchFailures.some(failure => error.includes(failure))) {
55
+ onError(error);
56
+ }
57
+ };
58
+
59
+ try {
60
+ const response = await fetch(`https://cdn.segment.com/v1/projects/${writeKey}/integrations`);
61
+
62
+ if (!response.ok) {
63
+ filteredOnError(`Failed to fetch integrations for write key ${writeKey}: HTTP ${response.status} ${response.statusText}`);
64
+ return [];
65
+ }
66
+
67
+ const destinations = await response.json();
68
+
69
+ for (const destination of destinations) {
70
+ destination.id = destination.creationName;
71
+ delete destination.creationName;
72
+ }
73
+
74
+ return destinations;
75
+ } catch (error) {
76
+ filteredOnError(`Unknown error fetching Segment destinations for write key ${writeKey}: ${error}`);
77
+ return [];
78
+ }
79
+ };
80
+
81
+ /**
82
+ * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
83
+ */
84
+ var Consent;
85
+
86
+ (function (Consent) {
87
+ Consent["Functional"] = "C0003";
88
+ Consent["Performance"] = "C0002";
89
+ Consent["StrictlyNecessary"] = "C0001";
90
+ Consent["Targeting"] = "C0004";
91
+ })(Consent || (Consent = {}));
92
+
93
+ const OPT_OUT_DATALAYER_VAR = 'user_opted_out_external_tracking';
94
+ const getConsentDecision = ({
95
+ scope,
96
+ optedOutExternalTracking
97
+ }) => {
98
+ let consentDecision = [];
99
+
100
+ if (typeof scope.OnetrustActiveGroups === 'string') {
101
+ consentDecision = scope.OnetrustActiveGroups.split(',').filter(Boolean);
102
+ } else if (scope.OnetrustActiveGroups) {
103
+ consentDecision = scope.OnetrustActiveGroups;
104
+ }
105
+
106
+ if (optedOutExternalTracking) {
107
+ var _scope$dataLayer;
108
+
109
+ /**
110
+ * If user has already opted out of everything but the essentials
111
+ * don't force them to consent to Functional & Performance trackers
112
+ */
113
+ if (consentDecision.length > 2) {
114
+ consentDecision = [Consent.StrictlyNecessary, Consent.Functional, Consent.Performance];
115
+ }
116
+
117
+ (_scope$dataLayer = scope.dataLayer) != null ? _scope$dataLayer : scope.dataLayer = [];
118
+ scope.dataLayer.push({
119
+ [OPT_OUT_DATALAYER_VAR]: true
120
+ });
121
+ }
122
+
123
+ return consentDecision;
124
+ };
125
+
126
+ const targetingCategories = ['Advertising', 'Attribution', 'Email Marketing'];
127
+ const performanceCategories = ['Analytics', 'Customer Success', 'Surveys', 'Heatmaps & Recording'];
128
+ const functionalCategories = ['SMS & Push Notifications'];
129
+ /**
130
+ * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
131
+ */
132
+
133
+ const mapDestinations = ({
134
+ consentDecision: _consentDecision = [Consent.StrictlyNecessary],
135
+ destinations
136
+ }) => {
137
+ const destinationPreferences = Object.assign({
138
+ 'Segment.io': _consentDecision.includes(Consent.Functional)
139
+ }, ...destinations.map(dest => {
140
+ if (targetingCategories.includes(dest.category)) {
141
+ return {
142
+ [dest.id]: _consentDecision.includes(Consent.Targeting)
143
+ };
144
+ }
145
+
146
+ if (performanceCategories.includes(dest.category)) {
147
+ return {
148
+ [dest.id]: _consentDecision.includes(Consent.Performance)
149
+ };
150
+ }
151
+
152
+ if (functionalCategories.includes(dest.category)) {
153
+ return {
154
+ [dest.id]: _consentDecision.includes(Consent.Functional)
155
+ };
156
+ }
157
+
158
+ return {
159
+ [dest.id]: true
160
+ };
161
+ }));
162
+ const identifyPreferences = {
163
+ All: false,
164
+ FullStory: _consentDecision.includes(Consent.Performance),
165
+ Hindsight: _consentDecision.includes(Consent.Targeting),
166
+ UserLeap: _consentDecision.includes(Consent.Performance)
167
+ };
168
+ return {
169
+ destinationPreferences,
170
+ identifyPreferences
171
+ };
172
+ };
173
+
174
+ const initializeOneTrust = async ({
175
+ production,
176
+ scope
177
+ }) => {
178
+ const script = document.createElement('script');
179
+ script.setAttribute('async', 'true');
180
+ script.setAttribute('src', 'https://cdn.cookielaw.org/scripttemplates/otSDKStub.js');
181
+ script.setAttribute('type', 'text/javascript');
182
+ script.setAttribute('data-domain-script', `cfa7b129-f37b-4f5a-9991-3f75ba7b85fb${production ? '' : '-test'}`);
183
+ document.body.appendChild(script);
184
+ const style = document.createElement('style');
185
+ style.textContent = rawStyles;
186
+ document.body.appendChild(style);
187
+ return new Promise(resolve => {
188
+ scope.OptanonWrapper = () => {
189
+ var _scope$dataLayer, _script$parentNode;
190
+
191
+ (_scope$dataLayer = scope.dataLayer) != null ? _scope$dataLayer : scope.dataLayer = [];
192
+ scope.dataLayer.push({
193
+ event: 'OneTrustGroupsUpdated'
194
+ });
195
+ resolve();
196
+ (_script$parentNode = script.parentNode) == null ? void 0 : _script$parentNode.removeChild(script);
197
+ };
198
+ });
199
+ }; // For now, these three values duplicate theme colors from gamut-styles
200
+ // We don't want to take a full dependency on that package here...
201
+
202
+ const rawStyles = `
203
+ :root {
204
+ --onetrust-brand-purple: #3A10E5;
205
+ --onetrust-color-gray-500: #828285;
206
+ --onetrust-color-white: #fff;
207
+ }
208
+
209
+ #onetrust-banner-sdk {
210
+ padding: 1rem !important;
211
+ }
212
+ #onetrust-banner-sdk > .ot-sdk-container {
213
+ width: 100% !important;
214
+ }
215
+ #onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {
216
+ display: flex !important;
217
+ flex-direction: column !important;
218
+ align-items: center !important;
219
+ max-width: 1436px !important;
220
+ margin: 0 auto !important;
221
+ }
222
+ #onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row:after {
223
+ content: none !important;
224
+ }
225
+ #onetrust-group-container {
226
+ display: flex !important;
227
+ justify-content: center;
228
+ float: none !important;
229
+ width: 100% !important;
230
+ max-width: 1148px !important;
231
+ margin-left: 0 !important;
232
+ margin-bottom: 0.625rem !important;
233
+ }
234
+ #onetrust-policy,
235
+ #onetrust-policy-text {
236
+ margin: 0 !important;
237
+ font-size: 0.875rem !important;
238
+ line-height: 1.375rem !important;
239
+ text-align: center !important;
240
+ float: none !important;
241
+ }
242
+ #onetrust-policy-text a {
243
+ text-decoration: none;
244
+ line-height: 26px !important;
245
+ margin-left: 0 !important;
246
+ }
247
+ #onetrust-button-group-parent {
248
+ position: relative !important;
249
+ top: initial !important;
250
+ left: initial !important;
251
+ transform: initial !important;
252
+ width: 264px !important;
253
+ margin: 0 !important;
254
+ padding: 0 !important;
255
+ float: none !important;
256
+ }
257
+ #onetrust-button-group {
258
+ display: flex !important;
259
+ margin: 0 !important;
260
+ }
261
+ #onetrust-pc-btn-handler, #onetrust-accept-btn-handler {
262
+ min-width: initial !important;
263
+ padding: 0.375rem 1rem !important;
264
+ margin: 0 !important;
265
+ opacity: 1 !important;
266
+ border-radius: 2px !important;
267
+ line-height: 1.5 !important;
268
+ user-select: none !important;
269
+ font-size: 1rem !important;
270
+ }
271
+ #onetrust-pc-btn-handler:focus, #onetrust-accept-btn-handler:focus {
272
+ box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);
273
+ text-decoration: none !important;
274
+ outline: none !important;
275
+ }
276
+ #onetrust-pc-btn-handler{
277
+ color: var(--onetrust-brand-purple) !important;
278
+ border: 1px solid var(--onetrust-brand-purple)!important;
279
+ background: var(--onetrust-color-white) !important
280
+ }
281
+ #onetrust-accept-btn-handler {
282
+ color: var(--onetrust-color-white) !important;
283
+ background: var(--onetrust-brand-purple)!important;
284
+ margin-left: 1rem !important;
285
+ }
286
+ #onetrust-close-btn-container {
287
+ display: none !important;
288
+ }
289
+
290
+ .pc-logo {
291
+ display: none !important;
292
+ }
293
+
294
+ #accept-recommended-btn-handler,
295
+ .ot-pc-refuse-all-handler,
296
+ .save-preference-btn-handler {
297
+ margin-left: 4px !important;
298
+ font-size: 14px !important;
299
+ }
300
+
301
+ #accept-recommended-btn-handler:focus,
302
+ #onetrust-pc-sdk .ot-pc-refuse-all-handler:focus,
303
+ #onetrust-pc-sdk .save-preference-btn-handler:focus {
304
+ box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);
305
+ text-decoration: none !important;
306
+ outline: none !important;
307
+ opacity: 1 !important;
308
+ }
309
+
310
+ .ot-switch-label {
311
+ border: 1px solid var(--onetrust-color-gray-500) !important;
312
+ background-color: var(--onetrust-color-gray-500) !important;
313
+ }
314
+
315
+ .ot-switch-nob {
316
+ background: var(--onetrust-color-white) !important;
317
+ }
318
+
319
+ .ot-switch-inner:before {
320
+ background-color: var(--onetrust-brand-purple) !important;
321
+ }
322
+
323
+ .switch-checkbox:checked+.ot-switch-label .ot-switch-nob {
324
+ border-color: var(--onetrust-brand-purple) !important;
325
+ }
326
+
327
+ .ot-pc-footer-logo {
328
+ display: none !important;
329
+ }
330
+
331
+ #onetrust-banner-sdk>.ot-sdk-container {
332
+ overflow: visible !important;
333
+ }
334
+
335
+ @media (max-width: 30rem) {
336
+ #accept-recommended-btn-handler,
337
+ .ot-pc-refuse-all-handler,
338
+ .save-preference-btn-handler {
339
+ width: 96% !important;
340
+ }
341
+ }
342
+
343
+ @media (min-width: 37.5rem) {
344
+ #onetrust-banner-sdk {
345
+ padding: 0.875rem 1rem !important;
346
+ }
347
+ }
348
+ @media (min-width: 48rem) {
349
+ #onetrust-banner-sdk {
350
+ padding: 0.875rem 1.25rem !important;
351
+ }
352
+ }
353
+ @media (min-width: 1650px) {
354
+ #onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {
355
+ flex-direction: row !important;
356
+ justify-content: space-between !important;
357
+ }
358
+ #onetrust-group-container {
359
+ margin-bottom: 0 !important;
360
+ }
361
+ #onetrust-button-group {
362
+ flex-direction: row !important;
363
+ }
364
+ }
365
+ `;
366
+
367
+ // @ts-nocheck
368
+
369
+ /**
370
+ * This code is copypasta from the Segment documentation.
371
+ * It creates the global analytics object and loads the Segment Analytics API that uses it.
372
+ *
373
+ * @see https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/#step-2-copy-the-segment-snippet
374
+ */
375
+ const runSegmentSnippet = () => {
376
+ var _window;
377
+
378
+ // Create a queue, but don't obliterate an existing one!
379
+ (_window = window).analytics || (_window.analytics = []);
380
+ const {
381
+ analytics
382
+ } = window; // If the real analytics.js is already on the page return.
383
+
384
+ if (analytics.initialize) return; // If the snippet was invoked already show an error.
385
+
386
+ if (analytics.invoked) {
387
+ console.error('Segment snippet included twice.');
388
+ return;
389
+ } // Invoked flag, to make sure the snippet
390
+ // is never invoked twice.
391
+
392
+
393
+ analytics.invoked = true; // A list of the methods in Analytics.js to stub.
394
+
395
+ analytics.methods = ['trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'debug', 'page', 'once', 'off', 'on', 'addSourceMiddleware', 'addIntegrationMiddleware', 'setAnonymousId', 'addDestinationMiddleware']; // Define a factory to create stubs. These are placeholders
396
+ // for methods in Analytics.js so that you never have to wait
397
+ // for it to load to actually record data. The `method` is
398
+ // stored as the first argument, so we can replay the data.
399
+
400
+ analytics.factory = function (method) {
401
+ return function () {
402
+ const args = Array.prototype.slice.call(arguments);
403
+ args.unshift(method);
404
+ analytics.push(args);
405
+ return analytics;
406
+ };
407
+ }; // For each of our methods, generate a queueing stub.
408
+
409
+
410
+ for (let i = 0; i < analytics.methods.length; i += 1) {
411
+ const key = analytics.methods[i];
412
+ analytics[key] = analytics.factory(key);
413
+ } // Define a method to load Analytics.js from our CDN,
414
+ // and that will be sure to only ever load it once.
415
+
416
+
417
+ analytics.load = function (key, options) {
418
+ // Create an async script element based on your key.
419
+ const script = document.createElement('script');
420
+ script.type = 'text/javascript';
421
+ script.async = true;
422
+ script.src = 'https://cdn.segment.com/analytics.js/v1/' + key + '/analytics.min.js'; // Insert our script next to the first script element.
423
+
424
+ const first = document.getElementsByTagName('script')[0];
425
+ first.parentNode.insertBefore(script, first);
426
+ analytics._loadOptions = options;
427
+ }; // Add a version to keep track of what's in the wild.
428
+
429
+
430
+ analytics.SNIPPET_VERSION = '4.1.0';
431
+ };
432
+
433
+ /**
434
+ * @see README.md for details and usage.
435
+ */
436
+
437
+ const initializeTrackingIntegrations = async ({
438
+ onError,
439
+ production,
440
+ scope,
441
+ user,
442
+ optedOutExternalTracking,
443
+ writeKey
444
+ }) => {
445
+ // 1. Wait 1000ms to allow any other post-hydration logic to run first
446
+ await new Promise(resolve => setTimeout(resolve, 1000)); // 2. Load in OneTrust's banner and wait for its `OptanonWrapper` callback
447
+
448
+ await initializeOneTrust({
449
+ scope,
450
+ production
451
+ }); // 3. Segment's copy-and-paste snippet is run to load the Segment global library
452
+
453
+ runSegmentSnippet(); // 4. Destination integrations for Segment are fetched
454
+
455
+ const destinations = await fetchDestinationsForWriteKey({
456
+ onError,
457
+ writeKey
458
+ });
459
+
460
+ if (!destinations) {
461
+ return;
462
+ }
463
+
464
+ const consentDecision = getConsentDecision({
465
+ scope,
466
+ optedOutExternalTracking
467
+ }); // 5. Those integrations are compared against the user's consent decisions into a list of allowed destinations
468
+
469
+ const {
470
+ destinationPreferences,
471
+ identifyPreferences
472
+ } = mapDestinations({
473
+ consentDecision,
474
+ destinations
475
+ }); // 6. We load only those allowed destinations using Segment's `analytics.load`
476
+
477
+ conditionallyLoadAnalytics({
478
+ analytics: scope.analytics,
479
+ destinationPreferences,
480
+ identifyPreferences,
481
+ user,
482
+ writeKey
483
+ });
484
+ };
485
+
486
+ function _extends() {
487
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
488
+ for (var i = 1; i < arguments.length; i++) {
489
+ var source = arguments[i];
490
+
491
+ for (var key in source) {
492
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
493
+ target[key] = source[key];
494
+ }
495
+ }
496
+ }
497
+
498
+ return target;
499
+ };
500
+ return _extends.apply(this, arguments);
501
+ }
502
+
503
+ const browserSupportsKeepalive = () => 'keepalive' in window.Request.prototype;
504
+
505
+ const createTracker = ({
506
+ apiBaseUrl,
507
+ verbose
508
+ }) => {
509
+ const beacon = (endpoint, data) => {
510
+ const uri = new URL(endpoint, apiBaseUrl).toString();
511
+ const form = new FormData();
512
+
513
+ for (const [k, v] of Object.entries(data)) {
514
+ form.append(k, v.toString());
515
+ }
516
+
517
+ try {
518
+ // Firefox allows users to disable navigator.sendBeacon, and very old Safari versions don't have it.
519
+ // [WEB-1700]: Additionally, Chrome 79-80 gives "Illegal invocation" with ?., so through 2022 we should support them.
520
+ // It seems similar to this: https://github.com/vercel/next.js/issues/23856
521
+ if (navigator.sendBeacon && navigator.sendBeacon(uri, form)) {
522
+ return;
523
+ }
524
+ } catch (_unused) {// Even with the proper scoping, Chrome 79-80 still gives "Illegal invocation" crashes. Sigh.
525
+ } // Either way, we fall back to standard fetch if sendBeacon fails.
526
+ // We don't mind this rejecting with an error because it's tracking, and we'll know if that starts to fail.
527
+
528
+
529
+ window.fetch(uri, _extends({
530
+ method: 'POST',
531
+ body: form
532
+ }, browserSupportsKeepalive() && {
533
+ keepalive: true
534
+ }));
535
+ };
536
+
537
+ const event = (category, event, userData, options = {}) => {
538
+ const properties = _extends({}, userData, {
539
+ fullpath: window.location.pathname + window.location.search,
540
+ search: window.location.search,
541
+ path: window.location.pathname,
542
+ title: window.document.title,
543
+ url: window.location.href,
544
+ referrer: userData.referrer || window.document.referrer,
545
+ client: getClientType()
546
+ });
547
+
548
+ if (verbose) {
549
+ console.groupCollapsed(`%cTracking Event Fired: ${category}:${event}`, 'color: #4b35ef; font-style: italic;');
550
+ console.log({
551
+ category,
552
+ event,
553
+ properties
554
+ });
555
+ console.groupEnd();
556
+ } // This allows the UTM query params to get registered in the user session.
557
+
558
+
559
+ const queryParams = window.location.search;
560
+ beacon(`/analytics/${category}${queryParams}`, {
561
+ category,
562
+ event,
563
+ properties: JSON.stringify(properties),
564
+ gdpr_safe: `${options.gdprSafe}`
565
+ });
566
+ };
567
+
568
+ return {
569
+ event,
570
+ click: data => event('user', 'click', data),
571
+ impression: data => event('user', 'impression', data),
572
+ visit: data => event('user', 'visit', data),
573
+ pushDataLayerEvent: eventName => {
574
+ var _window;
575
+
576
+ ((_window = window).dataLayer || (_window.dataLayer = [])).push({
577
+ event: eventName
578
+ });
579
+ }
580
+ };
581
+ };
582
+
583
+ const fetchUser = async apiBaseUrl => {
584
+ const response = await fetch(`${apiBaseUrl}/users/web`, {
585
+ method: 'GET',
586
+ headers: {
587
+ 'Content-type': 'application/json',
588
+ Accept: 'application/json'
589
+ },
590
+ credentials: 'include'
591
+ });
592
+ return response.json();
593
+ };
594
+
595
+ export { createTracker, fetchUser, initializeTrackingIntegrations };
@@ -1,9 +1,9 @@
1
- import { SegmentAnalytics, UserIntegrationSummary } from './types';
2
- export declare type AnalyticsLoadOptions = {
3
- analytics: SegmentAnalytics;
4
- destinationPreferences: Record<string, boolean>;
5
- identifyPreferences: Record<string, boolean>;
6
- user?: UserIntegrationSummary;
7
- writeKey: string;
8
- };
9
- export declare const conditionallyLoadAnalytics: ({ analytics, destinationPreferences, identifyPreferences, user, writeKey, }: AnalyticsLoadOptions) => void;
1
+ import { SegmentAnalytics, UserIntegrationSummary } from './types';
2
+ export declare type AnalyticsLoadOptions = {
3
+ analytics: SegmentAnalytics;
4
+ destinationPreferences: Record<string, boolean>;
5
+ identifyPreferences: Record<string, boolean>;
6
+ user?: UserIntegrationSummary;
7
+ writeKey: string;
8
+ };
9
+ export declare const conditionallyLoadAnalytics: ({ analytics, destinationPreferences, identifyPreferences, user, writeKey, }: AnalyticsLoadOptions) => void;
@@ -1,9 +1,9 @@
1
- /**
2
- * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
3
- */
4
- export declare enum Consent {
5
- Functional = "C0003",
6
- Performance = "C0002",
7
- StrictlyNecessary = "C0001",
8
- Targeting = "C0004"
9
- }
1
+ /**
2
+ * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
3
+ */
4
+ export declare enum Consent {
5
+ Functional = "C0003",
6
+ Performance = "C0002",
7
+ StrictlyNecessary = "C0001",
8
+ Targeting = "C0004"
9
+ }
@@ -1,13 +1,13 @@
1
- /**
2
- * @returns Whether the site is running both in ChromeOS and in PWA mode.
3
- */
4
- export declare const isChromeOSPWA: () => boolean;
5
- /**
6
- * @returns Whether the site is running in ChromeOS
7
- */
8
- export declare const isChromeOS: () => boolean;
9
- export declare enum ClientTypes {
10
- PWA = "pwa",
11
- Default = "default"
12
- }
13
- export declare const getClientType: () => ClientTypes;
1
+ /**
2
+ * @returns Whether the site is running both in ChromeOS and in PWA mode.
3
+ */
4
+ export declare const isChromeOSPWA: () => boolean;
5
+ /**
6
+ * @returns Whether the site is running in ChromeOS
7
+ */
8
+ export declare const isChromeOS: () => boolean;
9
+ export declare enum ClientTypes {
10
+ PWA = "pwa",
11
+ Default = "default"
12
+ }
13
+ export declare const getClientType: () => ClientTypes;
@@ -1,6 +1,6 @@
1
- import { SegmentDestination } from './types';
2
- export declare type FetchDestinationsSettings = {
3
- onError: (message: string) => void;
4
- writeKey: string;
5
- };
6
- export declare const fetchDestinationsForWriteKey: ({ writeKey, onError, }: FetchDestinationsSettings) => Promise<SegmentDestination[] | undefined>;
1
+ import { SegmentDestination } from './types';
2
+ export declare type FetchDestinationsSettings = {
3
+ onError: (message: string) => void;
4
+ writeKey: string;
5
+ };
6
+ export declare const fetchDestinationsForWriteKey: ({ writeKey, onError, }: FetchDestinationsSettings) => Promise<SegmentDestination[] | undefined>;
@@ -1,8 +1,8 @@
1
- import { Consent } from './consent';
2
- import { TrackingWindow } from './types';
3
- export interface ConsentDecisionOptions {
4
- scope: TrackingWindow;
5
- optedOutExternalTracking?: boolean;
6
- }
7
- export declare const OPT_OUT_DATALAYER_VAR = "user_opted_out_external_tracking";
8
- export declare const getConsentDecision: ({ scope, optedOutExternalTracking, }: ConsentDecisionOptions) => Consent[];
1
+ import { Consent } from './consent';
2
+ import { TrackingWindow } from './types';
3
+ export interface ConsentDecisionOptions {
4
+ scope: TrackingWindow;
5
+ optedOutExternalTracking?: boolean;
6
+ }
7
+ export declare const OPT_OUT_DATALAYER_VAR = "user_opted_out_external_tracking";
8
+ export declare const getConsentDecision: ({ scope, optedOutExternalTracking, }: ConsentDecisionOptions) => Consent[];