@chordcommerce/analytics 1.18.3-beta.1 → 1.19.0-beta.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.
Files changed (35) hide show
  1. package/dist/cjs/client/cdp.d.ts +5 -2
  2. package/dist/cjs/client/cdp.js +15 -7
  3. package/dist/cjs/client/consent/index.d.ts +6 -8
  4. package/dist/cjs/client/consent/index.js +55 -89
  5. package/dist/cjs/client/consent/ketch.d.ts +2 -0
  6. package/dist/cjs/client/consent/ketch.js +5 -1
  7. package/dist/cjs/client/consent/onetrust-api.d.ts +103 -0
  8. package/dist/cjs/client/consent/onetrust-api.js +128 -0
  9. package/dist/cjs/client/consent/onetrust.d.ts +4 -16
  10. package/dist/cjs/client/consent/onetrust.js +25 -34
  11. package/dist/cjs/client/consent/segment.d.ts +2 -0
  12. package/dist/cjs/client/consent/segment.js +16 -10
  13. package/dist/cjs/client/consent/shopify.d.ts +2 -0
  14. package/dist/cjs/client/consent/shopify.js +12 -1
  15. package/dist/cjs/client/index.d.ts +54 -2
  16. package/dist/cjs/client/index.js +375 -81
  17. package/dist/cjs/types/consent.d.ts +13 -2
  18. package/dist/client/cdp.d.ts +5 -2
  19. package/dist/client/cdp.js +13 -5
  20. package/dist/client/consent/index.d.ts +6 -8
  21. package/dist/client/consent/index.js +50 -62
  22. package/dist/client/consent/ketch.d.ts +2 -0
  23. package/dist/client/consent/ketch.js +5 -1
  24. package/dist/client/consent/onetrust-api.d.ts +103 -0
  25. package/dist/client/consent/onetrust-api.js +119 -0
  26. package/dist/client/consent/onetrust.d.ts +4 -16
  27. package/dist/client/consent/onetrust.js +25 -33
  28. package/dist/client/consent/segment.d.ts +2 -0
  29. package/dist/client/consent/segment.js +10 -3
  30. package/dist/client/consent/shopify.d.ts +2 -0
  31. package/dist/client/consent/shopify.js +12 -1
  32. package/dist/client/index.d.ts +54 -2
  33. package/dist/client/index.js +244 -10
  34. package/dist/types/consent.d.ts +13 -2
  35. package/package.json +1 -1
@@ -1,11 +1,9 @@
1
1
  import type { ChordAnalyticsOptions, ConsentConfiguration } from '../../types/index.js';
2
- declare global {
3
- interface Window {
4
- jitsuConfig: {
5
- privacy: ConsentConfiguration;
6
- };
7
- }
8
- }
9
2
  export declare const addCdpConsent: (options: ChordAnalyticsOptions) => {
10
- init: () => Promise<boolean>;
3
+ init: () => Promise<ConsentConfiguration | null>;
4
+ getConsentConfig: () => {
5
+ getCategories: () => Record<string, boolean>;
6
+ isConsentReady: () => boolean;
7
+ debug: boolean;
8
+ };
11
9
  };
@@ -12,7 +12,6 @@ import { onetrustConsentAdapter } from './onetrust.js';
12
12
  import { shopifyConsentAdapter } from './shopify.js';
13
13
  import { segmentConsentAdapter } from './segment.js';
14
14
  export const addCdpConsent = (options) => {
15
- let adapter = null;
16
15
  let lastProcessedConsent = null;
17
16
  const POLLING_INTERVAL_MS = 50;
18
17
  const TIMEOUT_MS = options.awaitConsentTimeout
@@ -36,6 +35,8 @@ export const addCdpConsent = (options) => {
36
35
  return null;
37
36
  }
38
37
  };
38
+ // Initialize adapter immediately so getConsentConfig() works
39
+ const adapter = getAdapter();
39
40
  /**
40
41
  * Polls if user can be tracked based on consent
41
42
  * @returns Promise that resolves to true if condition is met within timeout, false otherwise
@@ -60,105 +61,92 @@ export const addCdpConsent = (options) => {
60
61
  });
61
62
  });
62
63
  /**
63
- * Attempts to configure CDP with retry logic.
64
+ * Tracks consent preference changes.
65
+ * Note: Per-event consent stamping is handled in ChordAnalytics via stampConsent().
64
66
  */
65
- const configureCdpWithRetry = (updatedConsent, maxRetries = 5, baseDelay = 100) => __awaiter(void 0, void 0, void 0, function* () {
66
- let attempt = 0;
67
- const tryConfigure = () => __awaiter(void 0, void 0, void 0, function* () {
68
- const cdp = window[`_${options.namespace}`];
69
- if (cdp && typeof cdp.configure === 'function') {
70
- try {
71
- if (Object.keys(updatedConsent).length > 0) {
72
- cdp.configure({ privacy: updatedConsent });
73
- }
74
- return true;
75
- }
76
- catch (error) {
77
- // Continue to retry on error
78
- }
79
- }
80
- if (attempt < maxRetries) {
81
- const delay = baseDelay * Math.pow(2, attempt); // Exponential backoff
82
- yield new Promise((resolve) => {
83
- setTimeout(resolve, delay);
84
- });
85
- attempt++;
86
- return tryConfigure();
87
- }
88
- console.warn('CDP configuration failed after all retries, falling back to jitsuConfig');
89
- return false;
90
- });
91
- return tryConfigure();
92
- });
93
- /**
94
- * Updates consent for all future events.
95
- */
96
- const updateCdpConsent = (updatedConsent) => __awaiter(void 0, void 0, void 0, function* () {
67
+ const trackConsentUpdate = (updatedConsent) => __awaiter(void 0, void 0, void 0, function* () {
97
68
  if (lastProcessedConsent &&
98
69
  JSON.stringify(lastProcessedConsent) === JSON.stringify(updatedConsent)) {
99
70
  return;
100
71
  }
101
72
  lastProcessedConsent = updatedConsent;
102
73
  const chordAnalytics = window[options.namespace];
103
- const shouldTrackConsentUpdate = chordAnalytics &&
74
+ if (chordAnalytics &&
104
75
  typeof chordAnalytics.track === 'function' &&
105
- updatedConsent.consentCategories !== undefined;
106
- if (shouldTrackConsentUpdate &&
107
- // we have to send this BEFORE the CDP is reconfigured or else the track will not be sent, usually in the case of a user opting out
108
- updatedConsent.dontSend === true) {
109
- yield chordAnalytics.track('Consent Preferences Updated', updatedConsent);
110
- }
111
- const cdpConfigured = yield configureCdpWithRetry(updatedConsent);
112
- if (!cdpConfigured) {
113
- // CDP has not yet loaded via the snippet or all retries failed.
114
- window.jitsuConfig = { privacy: updatedConsent };
115
- }
116
- if (shouldTrackConsentUpdate &&
117
- // we have to send this AFTER the CDP is reconfigured to ensure the track is sent, usually in the case of a user opting in
118
- updatedConsent.dontSend === false) {
76
+ updatedConsent.consentCategories !== undefined) {
119
77
  yield chordAnalytics.track('Consent Preferences Updated', updatedConsent);
78
+ if (options.enableLogging && options.debug) {
79
+ console.log('[Chord Analytics DEBUG]: Consent preferences updated, sent tracking event');
80
+ }
120
81
  }
121
82
  });
122
83
  /**
123
84
  * Sets up consent management by initializing the adapter and handling consent updates.
85
+ * Returns the initial consent so it can be tracked after CDP is fully ready (avoiding circular await).
124
86
  */
125
87
  const setupConsentManagement = () => __awaiter(void 0, void 0, void 0, function* () {
126
88
  if (!adapter)
127
- return;
89
+ return null;
128
90
  // Set up the consent update handler first to catch any immediate updates
129
91
  adapter.handleConsentUpdates((updatedConsent) => {
130
- updateCdpConsent(updatedConsent);
92
+ trackConsentUpdate(updatedConsent);
131
93
  });
132
- // Process initial consent - this will be skipped if the adapter already triggered an update
94
+ // Return initial consent to be tracked after CDP is fully initialized
133
95
  const initialConsent = yield adapter.getCurrentConsent();
134
- yield updateCdpConsent(initialConsent);
96
+ lastProcessedConsent = initialConsent;
97
+ return initialConsent;
135
98
  });
136
99
  /**
137
- * Initializes consent management.
138
- * Returns a promise that resolves to true if CDP should be loaded, false otherwise.
100
+ * Initializes consent management and sets up consent update handlers.
101
+ * Returns initial consent configuration to be tracked after CDP is fully ready,
102
+ * or null if consent setup failed or was blocked.
139
103
  */
140
104
  const init = () => __awaiter(void 0, void 0, void 0, function* () {
141
- adapter = getAdapter();
105
+ if (options.debug && options.enableLogging) {
106
+ console.log('[Chord Analytics DEBUG]: consent init() called, adapter:', adapter ? options.consent : 'null');
107
+ }
142
108
  if (adapter === null) {
143
109
  console.error(`Consent management adapter "${options.consent}" is not supported.`);
144
- return false;
110
+ return null;
145
111
  }
146
112
  if (options.awaitConsent) {
113
+ if (options.debug && options.enableLogging) {
114
+ console.log('[Chord Analytics DEBUG]: awaitConsent is true, checking if user can be tracked');
115
+ }
147
116
  const canBeTracked = yield checkUserCanBeTracked();
148
- if (!canBeTracked)
149
- return false;
117
+ if (!canBeTracked) {
118
+ if (options.debug && options.enableLogging) {
119
+ console.log('[Chord Analytics DEBUG]: User cannot be tracked, returning null');
120
+ }
121
+ return null;
122
+ }
150
123
  }
151
124
  try {
152
- yield setupConsentManagement();
125
+ const result = yield setupConsentManagement();
126
+ if (options.debug && options.enableLogging) {
127
+ console.log('[Chord Analytics DEBUG]: setupConsentManagement() returned:', JSON.stringify(result));
128
+ }
129
+ return result;
153
130
  }
154
131
  catch (error) {
155
132
  if (options.debug && options.enableLogging) {
156
- console.error('Error setting up consent management:', error);
133
+ console.error('[Chord Analytics DEBUG]: Error setting up consent management:', error);
157
134
  }
135
+ return null;
158
136
  }
159
- return true;
160
137
  });
138
+ const getConsentConfig = () => {
139
+ if (!(adapter === null || adapter === void 0 ? void 0 : adapter.getCategories) || !(adapter === null || adapter === void 0 ? void 0 : adapter.isConsentReady)) {
140
+ return undefined;
141
+ }
142
+ return {
143
+ getCategories: () => adapter.getCategories(),
144
+ isConsentReady: () => adapter.isConsentReady(),
145
+ debug: options.debug && options.enableLogging,
146
+ };
147
+ };
161
148
  return {
162
149
  init,
150
+ getConsentConfig,
163
151
  };
164
152
  };
@@ -12,5 +12,7 @@ export declare const ketchConsentAdapter: () => {
12
12
  getCurrentConsent: () => ConsentConfiguration;
13
13
  handleConsentUpdates: (updateCdpConsent: (consent: ConsentConfiguration) => void) => void;
14
14
  userCanBeTracked: () => boolean;
15
+ getCategories: () => Record<string, boolean>;
16
+ isConsentReady: () => boolean;
15
17
  };
16
18
  export {};
@@ -18,7 +18,6 @@ const getCurrentConsent = () => {
18
18
  return {};
19
19
  return {
20
20
  consentCategories: Object.assign({}, api),
21
- dontSend: !userCanBeTracked(),
22
21
  };
23
22
  };
24
23
  /**
@@ -34,5 +33,10 @@ export const ketchConsentAdapter = () => {
34
33
  getCurrentConsent,
35
34
  handleConsentUpdates,
36
35
  userCanBeTracked,
36
+ getCategories: () => {
37
+ const api = getApi();
38
+ return api ? Object.assign({}, api) : {};
39
+ },
40
+ isConsentReady: () => !!getApi(),
37
41
  };
38
42
  };
@@ -0,0 +1,103 @@
1
+ /**
2
+ * OneTrust API Utilities
3
+ *
4
+ * Provides type-safe access to OneTrust's global API with proper duck typing
5
+ * to ensure the API is fully loaded before use.
6
+ *
7
+ * Modeled after analytics-next's onetrust-api.ts
8
+ */
9
+ /**
10
+ * OneTrust consent model types
11
+ */
12
+ export declare enum OtConsentModel {
13
+ optIn = "opt-in",
14
+ optOut = "opt-out",
15
+ implied = "implied consent"
16
+ }
17
+ /**
18
+ * OneTrust domain data structure
19
+ */
20
+ export interface OneTrustDomainData {
21
+ ShowAlertNotice: boolean;
22
+ Groups: OneTrustGroup[];
23
+ ConsentModel: {
24
+ Name: OtConsentModel | string;
25
+ };
26
+ }
27
+ export interface OneTrustGroup {
28
+ CustomGroupId: string;
29
+ }
30
+ /**
31
+ * OneTrust consent changed event
32
+ */
33
+ type OtConsentChangedEvent = CustomEvent<string[]>;
34
+ /**
35
+ * OneTrust global API interface
36
+ */
37
+ export interface OneTrustGlobal {
38
+ GetDomainData: () => OneTrustDomainData;
39
+ OnConsentChanged: (cb: (event: OtConsentChangedEvent) => void) => void;
40
+ IsAlertBoxClosed: () => boolean;
41
+ }
42
+ declare global {
43
+ interface Window {
44
+ OneTrust?: OneTrustGlobal | Record<string, unknown>;
45
+ OnetrustActiveGroups?: string;
46
+ }
47
+ }
48
+ /**
49
+ * Get the OneTrust global API if it's ready.
50
+ *
51
+ * Uses duck typing to check if OneTrust is fully loaded.
52
+ * window.OneTrust may exist but not be ready (e.g., just has geolocationResponse).
53
+ *
54
+ * @returns OneTrustGlobal if ready, undefined otherwise
55
+ */
56
+ export declare const getOneTrustGlobal: () => OneTrustGlobal | undefined;
57
+ /**
58
+ * Get the raw OnetrustActiveGroups string.
59
+ *
60
+ * @returns Comma-separated string of active group IDs, or undefined
61
+ */
62
+ export declare const getOneTrustActiveGroups: () => string | undefined;
63
+ /**
64
+ * Get normalized active group IDs as an array.
65
+ * Reads FRESH from window.OnetrustActiveGroups each time - no caching!
66
+ *
67
+ * @returns Array of active group IDs
68
+ *
69
+ * @example
70
+ * // window.OnetrustActiveGroups = ",C0001,C0003,"
71
+ * getNormalizedActiveGroupIds() // ["C0001", "C0003"]
72
+ */
73
+ export declare const getNormalizedActiveGroupIds: () => string[];
74
+ /**
75
+ * Get all configured consent groups from OneTrust.
76
+ *
77
+ * @returns Array of group info objects
78
+ */
79
+ export declare const getAllGroups: () => {
80
+ groupId: string;
81
+ }[];
82
+ /**
83
+ * Get normalized consent categories.
84
+ * Reads FRESH from OneTrust globals each time - NO CACHING!
85
+ *
86
+ * This ensures if a user changes consent between two track() calls,
87
+ * each event reflects the consent state AT THAT MOMENT.
88
+ *
89
+ * @returns Record of category ID to consent boolean
90
+ *
91
+ * @example
92
+ * getNormalizedCategories()
93
+ * // { "C0001": true, "C0002": false, "C0003": true }
94
+ */
95
+ export declare const getNormalizedCategories: () => Record<string, boolean>;
96
+ /**
97
+ * Coerce OneTrust consent model name to our simplified model.
98
+ *
99
+ * @param model - OneTrust consent model name
100
+ * @returns 'opt-in' or 'opt-out'
101
+ */
102
+ export declare const coerceConsentModel: (model: OtConsentModel | string) => 'opt-in' | 'opt-out';
103
+ export {};
@@ -0,0 +1,119 @@
1
+ /**
2
+ * OneTrust API Utilities
3
+ *
4
+ * Provides type-safe access to OneTrust's global API with proper duck typing
5
+ * to ensure the API is fully loaded before use.
6
+ *
7
+ * Modeled after analytics-next's onetrust-api.ts
8
+ */
9
+ /**
10
+ * OneTrust consent model types
11
+ */
12
+ // eslint-disable-next-line no-shadow
13
+ export var OtConsentModel;
14
+ (function (OtConsentModel) {
15
+ OtConsentModel["optIn"] = "opt-in";
16
+ OtConsentModel["optOut"] = "opt-out";
17
+ OtConsentModel["implied"] = "implied consent";
18
+ })(OtConsentModel || (OtConsentModel = {}));
19
+ /**
20
+ * Get the OneTrust global API if it's ready.
21
+ *
22
+ * Uses duck typing to check if OneTrust is fully loaded.
23
+ * window.OneTrust may exist but not be ready (e.g., just has geolocationResponse).
24
+ *
25
+ * @returns OneTrustGlobal if ready, undefined otherwise
26
+ */
27
+ export const getOneTrustGlobal = () => {
28
+ const oneTrust = window.OneTrust;
29
+ if (!oneTrust)
30
+ return undefined;
31
+ // Duck typing - check for required methods to ensure OneTrust is fully loaded
32
+ if (typeof oneTrust === 'object' &&
33
+ 'OnConsentChanged' in oneTrust &&
34
+ 'IsAlertBoxClosed' in oneTrust &&
35
+ 'GetDomainData' in oneTrust) {
36
+ return oneTrust;
37
+ }
38
+ return undefined;
39
+ };
40
+ /**
41
+ * Get the raw OnetrustActiveGroups string.
42
+ *
43
+ * @returns Comma-separated string of active group IDs, or undefined
44
+ */
45
+ export const getOneTrustActiveGroups = () => {
46
+ const groups = window.OnetrustActiveGroups;
47
+ if (!groups || typeof groups !== 'string')
48
+ return undefined;
49
+ return groups;
50
+ };
51
+ /**
52
+ * Get normalized active group IDs as an array.
53
+ * Reads FRESH from window.OnetrustActiveGroups each time - no caching!
54
+ *
55
+ * @returns Array of active group IDs
56
+ *
57
+ * @example
58
+ * // window.OnetrustActiveGroups = ",C0001,C0003,"
59
+ * getNormalizedActiveGroupIds() // ["C0001", "C0003"]
60
+ */
61
+ export const getNormalizedActiveGroupIds = () => {
62
+ const groups = getOneTrustActiveGroups();
63
+ if (!groups)
64
+ return [];
65
+ return groups.trim().split(',').filter(Boolean);
66
+ };
67
+ /**
68
+ * Get all configured consent groups from OneTrust.
69
+ *
70
+ * @returns Array of group info objects
71
+ */
72
+ export const getAllGroups = () => {
73
+ const oneTrust = getOneTrustGlobal();
74
+ if (!oneTrust)
75
+ return [];
76
+ return oneTrust.GetDomainData().Groups.map((group) => ({
77
+ groupId: group.CustomGroupId.trim(),
78
+ }));
79
+ };
80
+ /**
81
+ * Get normalized consent categories.
82
+ * Reads FRESH from OneTrust globals each time - NO CACHING!
83
+ *
84
+ * This ensures if a user changes consent between two track() calls,
85
+ * each event reflects the consent state AT THAT MOMENT.
86
+ *
87
+ * @returns Record of category ID to consent boolean
88
+ *
89
+ * @example
90
+ * getNormalizedCategories()
91
+ * // { "C0001": true, "C0002": false, "C0003": true }
92
+ */
93
+ export const getNormalizedCategories = () => {
94
+ const activeGroupIds = getNormalizedActiveGroupIds();
95
+ return getAllGroups().reduce((acc, group) => {
96
+ acc[group.groupId] = activeGroupIds.includes(group.groupId);
97
+ return acc;
98
+ }, {});
99
+ };
100
+ /**
101
+ * Coerce OneTrust consent model name to our simplified model.
102
+ *
103
+ * @param model - OneTrust consent model name
104
+ * @returns 'opt-in' or 'opt-out'
105
+ */
106
+ export const coerceConsentModel = (model) => {
107
+ switch (model) {
108
+ case OtConsentModel.optIn:
109
+ case OtConsentModel.implied:
110
+ case 'opt-in':
111
+ case 'implied consent':
112
+ return 'opt-in';
113
+ case OtConsentModel.optOut:
114
+ case 'opt-out':
115
+ default:
116
+ // Default to opt-out for unknown models (e.g., 'custom', 'notice')
117
+ return 'opt-out';
118
+ }
119
+ };
@@ -1,22 +1,10 @@
1
1
  import type { ChordAnalyticsOptions, ConsentConfiguration } from '../../types/index.js';
2
- declare global {
3
- interface Window {
4
- OneTrust?: OneTrustApi;
5
- OnetrustActiveGroups?: string;
6
- }
7
- }
8
- interface OneTrustApi {
9
- OnConsentChanged: (callback: () => void) => void;
10
- GetDomainData: () => {
11
- Groups: OneTrustGroup[];
12
- };
13
- }
14
- interface OneTrustGroup {
15
- CustomGroupId: string;
16
- }
17
2
  export declare const onetrustConsentAdapter: (options: ChordAnalyticsOptions) => {
18
3
  getCurrentConsent: () => ConsentConfiguration;
19
4
  handleConsentUpdates: (updateCdpConsent: (consent: ConsentConfiguration) => void) => void;
20
5
  userCanBeTracked: () => boolean;
6
+ getCategories: () => Record<string, boolean>;
7
+ isConsentReady: () => boolean;
8
+ getConsentModel: () => 'opt-in' | 'opt-out';
9
+ getApi: () => import("./onetrust-api.js").OneTrustGlobal;
21
10
  };
22
- export {};
@@ -1,80 +1,72 @@
1
- /**
2
- * Returns OneTrust's API.
3
- */
4
- const getApi = () => {
5
- const oneTrust = window.OneTrust;
6
- if (oneTrust &&
7
- typeof oneTrust === 'object' &&
8
- 'OnConsentChanged' in oneTrust &&
9
- 'GetDomainData' in oneTrust) {
10
- return oneTrust;
11
- }
12
- return undefined;
13
- };
1
+ import { getOneTrustGlobal, getNormalizedCategories, coerceConsentModel, } from './onetrust-api.js';
14
2
  /**
15
3
  * Returns whether the user can currently be tracked.
4
+ * Uses duck typing to check if OneTrust is fully loaded.
16
5
  */
17
6
  const userCanBeTracked = () => {
18
- // Always loads, a la `consentModel: 'opt-out'` in the Segment wrapper.
19
- const api = getApi();
20
- return !!api;
7
+ // Always loads when OneTrust is ready, a la `consentModel: 'opt-out'`
8
+ return !!getOneTrustGlobal();
21
9
  };
22
10
  /**
23
11
  * Returns the user's current consent configuration.
12
+ * Reads FRESH from OneTrust - no caching!
24
13
  */
25
14
  const getCurrentConsent = () => {
26
- const api = getApi();
27
- const activeGroups = window.OnetrustActiveGroups;
28
- if (!api || !activeGroups || typeof activeGroups !== 'string')
15
+ const api = getOneTrustGlobal();
16
+ if (!api)
29
17
  return {};
30
- const activeGroupIds = new Set(activeGroups.trim().split(',').filter(Boolean));
31
18
  return {
32
- consentCategories: api
33
- .GetDomainData()
34
- .Groups.reduce((acc, { CustomGroupId }) => {
35
- const groupId = CustomGroupId.trim();
36
- acc[groupId] = activeGroupIds.has(groupId);
37
- return acc;
38
- }, {}),
39
- dontSend: !userCanBeTracked(),
19
+ consentCategories: getNormalizedCategories(),
40
20
  };
41
21
  };
42
22
  /**
43
23
  * Handles subsequent changes to consent configuration.
24
+ * Sets up OnConsentChanged listener with retry logic.
44
25
  */
45
26
  const handleConsentUpdates = (updateCdpConsent, options) => {
46
27
  const maxRetries = 100;
47
28
  const retryInterval = 50;
48
29
  let attempts = 0;
49
30
  const setupHandler = () => {
50
- const api = getApi();
31
+ const api = getOneTrustGlobal();
51
32
  if (!api) {
52
33
  attempts++;
53
34
  if (attempts < maxRetries) {
54
35
  if (options.debug && options.enableLogging) {
55
- // eslint-disable-next-line no-console
56
- console.log('OneTrust API not found, retrying...');
36
+ console.log('[Chord Analytics DEBUG]: OneTrust API not found, retrying...');
57
37
  }
58
38
  setTimeout(setupHandler, retryInterval);
59
39
  }
60
40
  return;
61
41
  }
62
42
  if (options.debug && options.enableLogging) {
63
- // eslint-disable-next-line no-console
64
- console.log('OneTrust API found, setting up consent changed handler');
43
+ console.log('[Chord Analytics DEBUG]: OneTrust API found, setting up consent changed handler');
65
44
  }
66
45
  api.OnConsentChanged(() => {
67
46
  updateCdpConsent(getCurrentConsent());
47
+ if (options.debug && options.enableLogging) {
48
+ console.log('[Chord Analytics DEBUG]: OneTrust consent changed, sending Consent Preferences Updated track event');
49
+ }
68
50
  });
69
51
  };
70
52
  setupHandler();
71
53
  };
72
54
  export const onetrustConsentAdapter = (options) => {
73
55
  return {
56
+ // Existing methods for backwards compatibility
74
57
  getCurrentConsent,
75
58
  handleConsentUpdates: (updateCdpConsent) => {
76
59
  handleConsentUpdates(updateCdpConsent, options);
77
60
  },
78
61
  userCanBeTracked,
62
+ getCategories: () => getNormalizedCategories(),
63
+ isConsentReady: () => !!getOneTrustGlobal(),
64
+ getConsentModel: () => {
65
+ const api = getOneTrustGlobal();
66
+ if (!api)
67
+ return 'opt-out';
68
+ return coerceConsentModel(api.GetDomainData().ConsentModel.Name);
69
+ },
70
+ getApi: getOneTrustGlobal,
79
71
  };
80
72
  };
@@ -13,5 +13,7 @@ export declare const segmentConsentAdapter: () => {
13
13
  getCurrentConsent: () => Promise<ConsentConfiguration>;
14
14
  handleConsentUpdates: (updateCdpConsent: (consent: ConsentConfiguration) => void) => void;
15
15
  userCanBeTracked: () => Promise<boolean>;
16
+ getCategories: () => Record<string, boolean>;
17
+ isConsentReady: () => boolean;
16
18
  };
17
19
  export {};
@@ -33,8 +33,6 @@ const waitForApi = (maxRetries = 10, baseDelay = 100) => __awaiter(void 0, void
33
33
  return null;
34
34
  });
35
35
  return checkAndWait();
36
- console.warn('Segment API failed to load after all retries');
37
- return null;
38
36
  });
39
37
  /**
40
38
  * Returns whether the user can currently be tracked.
@@ -54,7 +52,6 @@ const getCurrentConsent = () => __awaiter(void 0, void 0, void 0, function* () {
54
52
  return {};
55
53
  return {
56
54
  consentCategories: Object.assign(Object.assign({}, api.customPreferences), api.destinationPreferences),
57
- dontSend: !(yield userCanBeTracked()),
58
55
  };
59
56
  });
60
57
  /**
@@ -70,5 +67,15 @@ export const segmentConsentAdapter = () => {
70
67
  getCurrentConsent,
71
68
  handleConsentUpdates,
72
69
  userCanBeTracked,
70
+ getCategories: () => {
71
+ const api = getApi();
72
+ if (!(api === null || api === void 0 ? void 0 : api.customPreferences))
73
+ return {};
74
+ return Object.assign(Object.assign({}, api.customPreferences), api.destinationPreferences);
75
+ },
76
+ isConsentReady: () => {
77
+ const api = getApi();
78
+ return !!((api === null || api === void 0 ? void 0 : api.customPreferences) && Object.keys(api.customPreferences).length > 0);
79
+ },
73
80
  };
74
81
  };
@@ -17,5 +17,7 @@ export declare const shopifyConsentAdapter: () => {
17
17
  getCurrentConsent: () => ConsentConfiguration;
18
18
  handleConsentUpdates: (updateCdpConsent: (consent: ConsentConfiguration) => void) => void;
19
19
  userCanBeTracked: () => boolean;
20
+ getCategories: () => Record<string, boolean>;
21
+ isConsentReady: () => boolean;
20
22
  };
21
23
  export {};
@@ -27,7 +27,6 @@ const getCurrentConsent = () => {
27
27
  preferences: api.preferencesProcessingAllowed(),
28
28
  sale_of_data: api.saleOfDataAllowed(),
29
29
  },
30
- dontSend: !userCanBeTracked(),
31
30
  };
32
31
  };
33
32
  /**
@@ -43,5 +42,17 @@ export const shopifyConsentAdapter = () => {
43
42
  getCurrentConsent,
44
43
  handleConsentUpdates,
45
44
  userCanBeTracked,
45
+ getCategories: () => {
46
+ const api = getApi();
47
+ if (!api)
48
+ return {};
49
+ return {
50
+ analytics: api.analyticsProcessingAllowed(),
51
+ marketing: api.marketingAllowed(),
52
+ preferences: api.preferencesProcessingAllowed(),
53
+ sale_of_data: api.saleOfDataAllowed(),
54
+ };
55
+ },
56
+ isConsentReady: () => !!getApi(),
46
57
  };
47
58
  };