@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,3 +1,6 @@
1
- import type { ChordAnalyticsOptions, ChordAnalyticsQueue } from '../types/index.js';
2
- export declare const addCdpSnippet: (options: ChordAnalyticsOptions) => Promise<void>;
1
+ import type { ChordAnalyticsOptions, ChordAnalyticsQueue, ConsentConfiguration } from '../types/index.js';
2
+ export interface CdpSnippetResult {
3
+ initialConsent: ConsentConfiguration | null;
4
+ }
5
+ export declare const addCdpSnippet: (options: ChordAnalyticsOptions) => Promise<CdpSnippetResult>;
3
6
  export declare const cdpQueue: (namespace: string) => ChordAnalyticsQueue;
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable no-console */
2
3
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
4
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
5
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -41,14 +42,16 @@ var index_js_1 = require("./consent/index.js");
41
42
  var utils_js_1 = require("./utils.js");
42
43
  /*
43
44
  * Adds the Chord CDP snippet to the page.
45
+ * Returns initial consent configuration to be tracked after CDP is fully ready.
44
46
  */
45
47
  var addCdpSnippet = function (options) { return __awaiter(void 0, void 0, void 0, function () {
46
- var normalizedCDPDomain, cdpReadyPromise, s;
48
+ var normalizedCDPDomain, cdpReadyPromise, s, initialConsent;
47
49
  return __generator(this, function (_a) {
48
50
  switch (_a.label) {
49
51
  case 0:
50
- if (!document || typeof document.createElement === 'undefined')
51
- return [2 /*return*/];
52
+ if (!document || typeof document.createElement === 'undefined') {
53
+ return [2 /*return*/, { initialConsent: null }];
54
+ }
52
55
  normalizedCDPDomain = (0, utils_js_1.normalizeCDPDomain)(options.cdpDomain);
53
56
  cdpReadyPromise = new Promise(function (resolve) {
54
57
  var checkCdpReady = function () {
@@ -75,18 +78,23 @@ var addCdpSnippet = function (options) { return __awaiter(void 0, void 0, void 0
75
78
  case 1:
76
79
  // Wait for CDP to be ready before setting up consent
77
80
  _a.sent();
81
+ initialConsent = null;
78
82
  if (!options.consent) return [3 /*break*/, 3];
79
83
  if (options.debug && options.enableLogging) {
80
- console.log('Chord CDP: Setting up consent management');
84
+ console.log('[Chord Analytics DEBUG]: Setting up consent management');
81
85
  }
82
86
  return [4 /*yield*/, (0, index_js_1.addCdpConsent)(options).init()];
83
87
  case 2:
84
- _a.sent();
88
+ initialConsent = _a.sent();
85
89
  if (options.debug && options.enableLogging) {
86
- console.log('Chord CDP: Consent management setup complete');
90
+ console.log('[Chord Analytics DEBUG]: Consent management setup complete');
87
91
  }
88
92
  _a.label = 3;
89
- case 3: return [2 /*return*/];
93
+ case 3:
94
+ if (options.debug && options.enableLogging) {
95
+ console.log('[Chord Analytics DEBUG]: CDP snippet added, initialConsent:', JSON.stringify(initialConsent));
96
+ }
97
+ return [2 /*return*/, { initialConsent: initialConsent }];
90
98
  }
91
99
  });
92
100
  }); };
@@ -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
  };
@@ -42,7 +42,6 @@ var onetrust_js_1 = require("./onetrust.js");
42
42
  var shopify_js_1 = require("./shopify.js");
43
43
  var segment_js_1 = require("./segment.js");
44
44
  var addCdpConsent = function (options) {
45
- var adapter = null;
46
45
  var lastProcessedConsent = null;
47
46
  var POLLING_INTERVAL_MS = 50;
48
47
  var TIMEOUT_MS = options.awaitConsentTimeout
@@ -66,6 +65,8 @@ var addCdpConsent = function (options) {
66
65
  return null;
67
66
  }
68
67
  };
68
+ // Initialize adapter immediately so getConsentConfig() works
69
+ var adapter = getAdapter();
69
70
  /**
70
71
  * Polls if user can be tracked based on consent
71
72
  * @returns Promise that resolves to true if condition is met within timeout, false otherwise
@@ -92,57 +93,11 @@ var addCdpConsent = function (options) {
92
93
  });
93
94
  }); };
94
95
  /**
95
- * Attempts to configure CDP with retry logic.
96
+ * Tracks consent preference changes.
97
+ * Note: Per-event consent stamping is handled in ChordAnalytics via stampConsent().
96
98
  */
97
- var configureCdpWithRetry = function (updatedConsent, maxRetries, baseDelay) {
98
- if (maxRetries === void 0) { maxRetries = 5; }
99
- if (baseDelay === void 0) { baseDelay = 100; }
100
- return __awaiter(void 0, void 0, void 0, function () {
101
- var attempt, tryConfigure;
102
- return __generator(this, function (_a) {
103
- attempt = 0;
104
- tryConfigure = function () { return __awaiter(void 0, void 0, void 0, function () {
105
- var cdp, delay_1;
106
- return __generator(this, function (_a) {
107
- switch (_a.label) {
108
- case 0:
109
- cdp = window["_".concat(options.namespace)];
110
- if (cdp && typeof cdp.configure === 'function') {
111
- try {
112
- if (Object.keys(updatedConsent).length > 0) {
113
- cdp.configure({ privacy: updatedConsent });
114
- }
115
- return [2 /*return*/, true];
116
- }
117
- catch (error) {
118
- // Continue to retry on error
119
- }
120
- }
121
- if (!(attempt < maxRetries)) return [3 /*break*/, 2];
122
- delay_1 = baseDelay * Math.pow(2, attempt) // Exponential backoff
123
- ;
124
- return [4 /*yield*/, new Promise(function (resolve) {
125
- setTimeout(resolve, delay_1);
126
- })];
127
- case 1:
128
- _a.sent();
129
- attempt++;
130
- return [2 /*return*/, tryConfigure()];
131
- case 2:
132
- console.warn('CDP configuration failed after all retries, falling back to jitsuConfig');
133
- return [2 /*return*/, false];
134
- }
135
- });
136
- }); };
137
- return [2 /*return*/, tryConfigure()];
138
- });
139
- });
140
- };
141
- /**
142
- * Updates consent for all future events.
143
- */
144
- var updateCdpConsent = function (updatedConsent) { return __awaiter(void 0, void 0, void 0, function () {
145
- var chordAnalytics, shouldTrackConsentUpdate, cdpConfigured;
99
+ var trackConsentUpdate = function (updatedConsent) { return __awaiter(void 0, void 0, void 0, function () {
100
+ var chordAnalytics;
146
101
  return __generator(this, function (_a) {
147
102
  switch (_a.label) {
148
103
  case 0:
@@ -152,36 +107,23 @@ var addCdpConsent = function (options) {
152
107
  }
153
108
  lastProcessedConsent = updatedConsent;
154
109
  chordAnalytics = window[options.namespace];
155
- shouldTrackConsentUpdate = chordAnalytics &&
110
+ if (!(chordAnalytics &&
156
111
  typeof chordAnalytics.track === 'function' &&
157
- updatedConsent.consentCategories !== undefined;
158
- if (!(shouldTrackConsentUpdate &&
159
- // 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
160
- updatedConsent.dontSend === true)) return [3 /*break*/, 2];
112
+ updatedConsent.consentCategories !== undefined)) return [3 /*break*/, 2];
161
113
  return [4 /*yield*/, chordAnalytics.track('Consent Preferences Updated', updatedConsent)];
162
114
  case 1:
163
115
  _a.sent();
164
- _a.label = 2;
165
- case 2: return [4 /*yield*/, configureCdpWithRetry(updatedConsent)];
166
- case 3:
167
- cdpConfigured = _a.sent();
168
- if (!cdpConfigured) {
169
- // CDP has not yet loaded via the snippet or all retries failed.
170
- window.jitsuConfig = { privacy: updatedConsent };
116
+ if (options.enableLogging && options.debug) {
117
+ console.log('[Chord Analytics DEBUG]: Consent preferences updated, sent tracking event');
171
118
  }
172
- if (!(shouldTrackConsentUpdate &&
173
- // 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
174
- updatedConsent.dontSend === false)) return [3 /*break*/, 5];
175
- return [4 /*yield*/, chordAnalytics.track('Consent Preferences Updated', updatedConsent)];
176
- case 4:
177
- _a.sent();
178
- _a.label = 5;
179
- case 5: return [2 /*return*/];
119
+ _a.label = 2;
120
+ case 2: return [2 /*return*/];
180
121
  }
181
122
  });
182
123
  }); };
183
124
  /**
184
125
  * Sets up consent management by initializing the adapter and handling consent updates.
126
+ * Returns the initial consent so it can be tracked after CDP is fully ready (avoiding circular await).
185
127
  */
186
128
  var setupConsentManagement = function () { return __awaiter(void 0, void 0, void 0, function () {
187
129
  var initialConsent;
@@ -189,60 +131,84 @@ var addCdpConsent = function (options) {
189
131
  switch (_a.label) {
190
132
  case 0:
191
133
  if (!adapter)
192
- return [2 /*return*/];
134
+ return [2 /*return*/, null
135
+ // Set up the consent update handler first to catch any immediate updates
136
+ ];
193
137
  // Set up the consent update handler first to catch any immediate updates
194
138
  adapter.handleConsentUpdates(function (updatedConsent) {
195
- updateCdpConsent(updatedConsent);
139
+ trackConsentUpdate(updatedConsent);
196
140
  });
197
141
  return [4 /*yield*/, adapter.getCurrentConsent()];
198
142
  case 1:
199
143
  initialConsent = _a.sent();
200
- return [4 /*yield*/, updateCdpConsent(initialConsent)];
201
- case 2:
202
- _a.sent();
203
- return [2 /*return*/];
144
+ lastProcessedConsent = initialConsent;
145
+ return [2 /*return*/, initialConsent];
204
146
  }
205
147
  });
206
148
  }); };
207
149
  /**
208
- * Initializes consent management.
209
- * Returns a promise that resolves to true if CDP should be loaded, false otherwise.
150
+ * Initializes consent management and sets up consent update handlers.
151
+ * Returns initial consent configuration to be tracked after CDP is fully ready,
152
+ * or null if consent setup failed or was blocked.
210
153
  */
211
154
  var init = function () { return __awaiter(void 0, void 0, void 0, function () {
212
- var canBeTracked, error_1;
155
+ var canBeTracked, result, error_1;
213
156
  return __generator(this, function (_a) {
214
157
  switch (_a.label) {
215
158
  case 0:
216
- adapter = getAdapter();
159
+ if (options.debug && options.enableLogging) {
160
+ console.log('[Chord Analytics DEBUG]: consent init() called, adapter:', adapter ? options.consent : 'null');
161
+ }
217
162
  if (adapter === null) {
218
163
  console.error("Consent management adapter \"".concat(options.consent, "\" is not supported."));
219
- return [2 /*return*/, false];
164
+ return [2 /*return*/, null];
220
165
  }
221
166
  if (!options.awaitConsent) return [3 /*break*/, 2];
167
+ if (options.debug && options.enableLogging) {
168
+ console.log('[Chord Analytics DEBUG]: awaitConsent is true, checking if user can be tracked');
169
+ }
222
170
  return [4 /*yield*/, checkUserCanBeTracked()];
223
171
  case 1:
224
172
  canBeTracked = _a.sent();
225
- if (!canBeTracked)
226
- return [2 /*return*/, false];
173
+ if (!canBeTracked) {
174
+ if (options.debug && options.enableLogging) {
175
+ console.log('[Chord Analytics DEBUG]: User cannot be tracked, returning null');
176
+ }
177
+ return [2 /*return*/, null];
178
+ }
227
179
  _a.label = 2;
228
180
  case 2:
229
181
  _a.trys.push([2, 4, , 5]);
230
182
  return [4 /*yield*/, setupConsentManagement()];
231
183
  case 3:
232
- _a.sent();
233
- return [3 /*break*/, 5];
184
+ result = _a.sent();
185
+ if (options.debug && options.enableLogging) {
186
+ console.log('[Chord Analytics DEBUG]: setupConsentManagement() returned:', JSON.stringify(result));
187
+ }
188
+ return [2 /*return*/, result];
234
189
  case 4:
235
190
  error_1 = _a.sent();
236
191
  if (options.debug && options.enableLogging) {
237
- console.error('Error setting up consent management:', error_1);
192
+ console.error('[Chord Analytics DEBUG]: Error setting up consent management:', error_1);
238
193
  }
239
- return [3 /*break*/, 5];
240
- case 5: return [2 /*return*/, true];
194
+ return [2 /*return*/, null];
195
+ case 5: return [2 /*return*/];
241
196
  }
242
197
  });
243
198
  }); };
199
+ var getConsentConfig = function () {
200
+ if (!(adapter === null || adapter === void 0 ? void 0 : adapter.getCategories) || !(adapter === null || adapter === void 0 ? void 0 : adapter.isConsentReady)) {
201
+ return undefined;
202
+ }
203
+ return {
204
+ getCategories: function () { return adapter.getCategories(); },
205
+ isConsentReady: function () { return adapter.isConsentReady(); },
206
+ debug: options.debug && options.enableLogging,
207
+ };
208
+ };
244
209
  return {
245
210
  init: init,
211
+ getConsentConfig: getConsentConfig,
246
212
  };
247
213
  };
248
214
  exports.addCdpConsent = addCdpConsent;
@@ -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 {};
@@ -32,7 +32,6 @@ var getCurrentConsent = function () {
32
32
  return {};
33
33
  return {
34
34
  consentCategories: __assign({}, api),
35
- dontSend: !userCanBeTracked(),
36
35
  };
37
36
  };
38
37
  /**
@@ -48,6 +47,11 @@ var ketchConsentAdapter = function () {
48
47
  getCurrentConsent: getCurrentConsent,
49
48
  handleConsentUpdates: handleConsentUpdates,
50
49
  userCanBeTracked: userCanBeTracked,
50
+ getCategories: function () {
51
+ var api = getApi();
52
+ return api ? __assign({}, api) : {};
53
+ },
54
+ isConsentReady: function () { return !!getApi(); },
51
55
  };
52
56
  };
53
57
  exports.ketchConsentAdapter = ketchConsentAdapter;
@@ -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,128 @@
1
+ "use strict";
2
+ /**
3
+ * OneTrust API Utilities
4
+ *
5
+ * Provides type-safe access to OneTrust's global API with proper duck typing
6
+ * to ensure the API is fully loaded before use.
7
+ *
8
+ * Modeled after analytics-next's onetrust-api.ts
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.coerceConsentModel = exports.getNormalizedCategories = exports.getAllGroups = exports.getNormalizedActiveGroupIds = exports.getOneTrustActiveGroups = exports.getOneTrustGlobal = exports.OtConsentModel = void 0;
12
+ /**
13
+ * OneTrust consent model types
14
+ */
15
+ // eslint-disable-next-line no-shadow
16
+ var OtConsentModel;
17
+ (function (OtConsentModel) {
18
+ OtConsentModel["optIn"] = "opt-in";
19
+ OtConsentModel["optOut"] = "opt-out";
20
+ OtConsentModel["implied"] = "implied consent";
21
+ })(OtConsentModel || (exports.OtConsentModel = OtConsentModel = {}));
22
+ /**
23
+ * Get the OneTrust global API if it's ready.
24
+ *
25
+ * Uses duck typing to check if OneTrust is fully loaded.
26
+ * window.OneTrust may exist but not be ready (e.g., just has geolocationResponse).
27
+ *
28
+ * @returns OneTrustGlobal if ready, undefined otherwise
29
+ */
30
+ var getOneTrustGlobal = function () {
31
+ var oneTrust = window.OneTrust;
32
+ if (!oneTrust)
33
+ return undefined;
34
+ // Duck typing - check for required methods to ensure OneTrust is fully loaded
35
+ if (typeof oneTrust === 'object' &&
36
+ 'OnConsentChanged' in oneTrust &&
37
+ 'IsAlertBoxClosed' in oneTrust &&
38
+ 'GetDomainData' in oneTrust) {
39
+ return oneTrust;
40
+ }
41
+ return undefined;
42
+ };
43
+ exports.getOneTrustGlobal = getOneTrustGlobal;
44
+ /**
45
+ * Get the raw OnetrustActiveGroups string.
46
+ *
47
+ * @returns Comma-separated string of active group IDs, or undefined
48
+ */
49
+ var getOneTrustActiveGroups = function () {
50
+ var groups = window.OnetrustActiveGroups;
51
+ if (!groups || typeof groups !== 'string')
52
+ return undefined;
53
+ return groups;
54
+ };
55
+ exports.getOneTrustActiveGroups = getOneTrustActiveGroups;
56
+ /**
57
+ * Get normalized active group IDs as an array.
58
+ * Reads FRESH from window.OnetrustActiveGroups each time - no caching!
59
+ *
60
+ * @returns Array of active group IDs
61
+ *
62
+ * @example
63
+ * // window.OnetrustActiveGroups = ",C0001,C0003,"
64
+ * getNormalizedActiveGroupIds() // ["C0001", "C0003"]
65
+ */
66
+ var getNormalizedActiveGroupIds = function () {
67
+ var groups = (0, exports.getOneTrustActiveGroups)();
68
+ if (!groups)
69
+ return [];
70
+ return groups.trim().split(',').filter(Boolean);
71
+ };
72
+ exports.getNormalizedActiveGroupIds = getNormalizedActiveGroupIds;
73
+ /**
74
+ * Get all configured consent groups from OneTrust.
75
+ *
76
+ * @returns Array of group info objects
77
+ */
78
+ var getAllGroups = function () {
79
+ var oneTrust = (0, exports.getOneTrustGlobal)();
80
+ if (!oneTrust)
81
+ return [];
82
+ return oneTrust.GetDomainData().Groups.map(function (group) { return ({
83
+ groupId: group.CustomGroupId.trim(),
84
+ }); });
85
+ };
86
+ exports.getAllGroups = getAllGroups;
87
+ /**
88
+ * Get normalized consent categories.
89
+ * Reads FRESH from OneTrust globals each time - NO CACHING!
90
+ *
91
+ * This ensures if a user changes consent between two track() calls,
92
+ * each event reflects the consent state AT THAT MOMENT.
93
+ *
94
+ * @returns Record of category ID to consent boolean
95
+ *
96
+ * @example
97
+ * getNormalizedCategories()
98
+ * // { "C0001": true, "C0002": false, "C0003": true }
99
+ */
100
+ var getNormalizedCategories = function () {
101
+ var activeGroupIds = (0, exports.getNormalizedActiveGroupIds)();
102
+ return (0, exports.getAllGroups)().reduce(function (acc, group) {
103
+ acc[group.groupId] = activeGroupIds.includes(group.groupId);
104
+ return acc;
105
+ }, {});
106
+ };
107
+ exports.getNormalizedCategories = getNormalizedCategories;
108
+ /**
109
+ * Coerce OneTrust consent model name to our simplified model.
110
+ *
111
+ * @param model - OneTrust consent model name
112
+ * @returns 'opt-in' or 'opt-out'
113
+ */
114
+ var coerceConsentModel = function (model) {
115
+ switch (model) {
116
+ case OtConsentModel.optIn:
117
+ case OtConsentModel.implied:
118
+ case 'opt-in':
119
+ case 'implied consent':
120
+ return 'opt-in';
121
+ case OtConsentModel.optOut:
122
+ case 'opt-out':
123
+ default:
124
+ // Default to opt-out for unknown models (e.g., 'custom', 'notice')
125
+ return 'opt-out';
126
+ }
127
+ };
128
+ exports.coerceConsentModel = coerceConsentModel;
@@ -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 {};