@chordcommerce/analytics 1.18.3-beta.1 → 1.19.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 (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,85 +1,76 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.onetrustConsentAdapter = void 0;
4
- /**
5
- * Returns OneTrust's API.
6
- */
7
- var getApi = function () {
8
- var oneTrust = window.OneTrust;
9
- if (oneTrust &&
10
- typeof oneTrust === 'object' &&
11
- 'OnConsentChanged' in oneTrust &&
12
- 'GetDomainData' in oneTrust) {
13
- return oneTrust;
14
- }
15
- return undefined;
16
- };
4
+ var onetrust_api_js_1 = require("./onetrust-api.js");
17
5
  /**
18
6
  * Returns whether the user can currently be tracked.
7
+ * Uses duck typing to check if OneTrust is fully loaded.
19
8
  */
20
9
  var userCanBeTracked = function () {
21
- // Always loads, a la `consentModel: 'opt-out'` in the Segment wrapper.
22
- var api = getApi();
23
- return !!api;
10
+ // Always loads when OneTrust is ready, a la `consentModel: 'opt-out'`
11
+ return !!(0, onetrust_api_js_1.getOneTrustGlobal)();
24
12
  };
25
13
  /**
26
14
  * Returns the user's current consent configuration.
15
+ * Reads FRESH from OneTrust - no caching!
27
16
  */
28
17
  var getCurrentConsent = function () {
29
- var api = getApi();
30
- var activeGroups = window.OnetrustActiveGroups;
31
- if (!api || !activeGroups || typeof activeGroups !== 'string')
18
+ var api = (0, onetrust_api_js_1.getOneTrustGlobal)();
19
+ if (!api)
32
20
  return {};
33
- var activeGroupIds = new Set(activeGroups.trim().split(',').filter(Boolean));
34
21
  return {
35
- consentCategories: api
36
- .GetDomainData()
37
- .Groups.reduce(function (acc, _a) {
38
- var CustomGroupId = _a.CustomGroupId;
39
- var groupId = CustomGroupId.trim();
40
- acc[groupId] = activeGroupIds.has(groupId);
41
- return acc;
42
- }, {}),
43
- dontSend: !userCanBeTracked(),
22
+ consentCategories: (0, onetrust_api_js_1.getNormalizedCategories)(),
44
23
  };
45
24
  };
46
25
  /**
47
26
  * Handles subsequent changes to consent configuration.
27
+ * Sets up OnConsentChanged listener with retry logic.
48
28
  */
49
29
  var handleConsentUpdates = function (updateCdpConsent, options) {
50
30
  var maxRetries = 100;
51
31
  var retryInterval = 50;
52
32
  var attempts = 0;
53
33
  var setupHandler = function () {
54
- var api = getApi();
34
+ var api = (0, onetrust_api_js_1.getOneTrustGlobal)();
55
35
  if (!api) {
56
36
  attempts++;
57
37
  if (attempts < maxRetries) {
58
38
  if (options.debug && options.enableLogging) {
59
- // eslint-disable-next-line no-console
60
- console.log('OneTrust API not found, retrying...');
39
+ console.log('[Chord Analytics DEBUG]: OneTrust API not found, retrying...');
61
40
  }
62
41
  setTimeout(setupHandler, retryInterval);
63
42
  }
64
43
  return;
65
44
  }
66
45
  if (options.debug && options.enableLogging) {
67
- // eslint-disable-next-line no-console
68
- console.log('OneTrust API found, setting up consent changed handler');
46
+ console.log('[Chord Analytics DEBUG]: OneTrust API found, setting up consent changed handler');
69
47
  }
70
48
  api.OnConsentChanged(function () {
71
49
  updateCdpConsent(getCurrentConsent());
50
+ if (options.debug && options.enableLogging) {
51
+ console.log('[Chord Analytics DEBUG]: OneTrust consent changed, sending Consent Preferences Updated track event');
52
+ }
72
53
  });
73
54
  };
74
55
  setupHandler();
75
56
  };
76
57
  var onetrustConsentAdapter = function (options) {
77
58
  return {
59
+ // Existing methods for backwards compatibility
78
60
  getCurrentConsent: getCurrentConsent,
79
61
  handleConsentUpdates: function (updateCdpConsent) {
80
62
  handleConsentUpdates(updateCdpConsent, options);
81
63
  },
82
64
  userCanBeTracked: userCanBeTracked,
65
+ getCategories: function () { return (0, onetrust_api_js_1.getNormalizedCategories)(); },
66
+ isConsentReady: function () { return !!(0, onetrust_api_js_1.getOneTrustGlobal)(); },
67
+ getConsentModel: function () {
68
+ var api = (0, onetrust_api_js_1.getOneTrustGlobal)();
69
+ if (!api)
70
+ return 'opt-out';
71
+ return (0, onetrust_api_js_1.coerceConsentModel)(api.GetDomainData().ConsentModel.Name);
72
+ },
73
+ getApi: onetrust_api_js_1.getOneTrustGlobal,
83
74
  };
84
75
  };
85
76
  exports.onetrustConsentAdapter = onetrustConsentAdapter;
@@ -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 {};
@@ -110,20 +110,16 @@ var userCanBeTracked = function () { return __awaiter(void 0, void 0, void 0, fu
110
110
  */
111
111
  var getCurrentConsent = function () { return __awaiter(void 0, void 0, void 0, function () {
112
112
  var api;
113
- var _a;
114
- return __generator(this, function (_b) {
115
- switch (_b.label) {
113
+ return __generator(this, function (_a) {
114
+ switch (_a.label) {
116
115
  case 0: return [4 /*yield*/, waitForApi()];
117
116
  case 1:
118
- api = _b.sent();
117
+ api = _a.sent();
119
118
  if (!api)
120
119
  return [2 /*return*/, {}];
121
- _a = {
122
- consentCategories: __assign(__assign({}, api.customPreferences), api.destinationPreferences)
123
- };
124
- return [4 /*yield*/, userCanBeTracked()];
125
- case 2: return [2 /*return*/, (_a.dontSend = !(_b.sent()),
126
- _a)];
120
+ return [2 /*return*/, {
121
+ consentCategories: __assign(__assign({}, api.customPreferences), api.destinationPreferences),
122
+ }];
127
123
  }
128
124
  });
129
125
  }); };
@@ -150,6 +146,16 @@ var segmentConsentAdapter = function () {
150
146
  getCurrentConsent: getCurrentConsent,
151
147
  handleConsentUpdates: handleConsentUpdates,
152
148
  userCanBeTracked: userCanBeTracked,
149
+ getCategories: function () {
150
+ var api = getApi();
151
+ if (!(api === null || api === void 0 ? void 0 : api.customPreferences))
152
+ return {};
153
+ return __assign(__assign({}, api.customPreferences), api.destinationPreferences);
154
+ },
155
+ isConsentReady: function () {
156
+ var api = getApi();
157
+ return !!((api === null || api === void 0 ? void 0 : api.customPreferences) && Object.keys(api.customPreferences).length > 0);
158
+ },
153
159
  };
154
160
  };
155
161
  exports.segmentConsentAdapter = segmentConsentAdapter;
@@ -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 {};
@@ -30,7 +30,6 @@ var getCurrentConsent = function () {
30
30
  preferences: api.preferencesProcessingAllowed(),
31
31
  sale_of_data: api.saleOfDataAllowed(),
32
32
  },
33
- dontSend: !userCanBeTracked(),
34
33
  };
35
34
  };
36
35
  /**
@@ -46,6 +45,18 @@ var shopifyConsentAdapter = function () {
46
45
  getCurrentConsent: getCurrentConsent,
47
46
  handleConsentUpdates: handleConsentUpdates,
48
47
  userCanBeTracked: userCanBeTracked,
48
+ getCategories: function () {
49
+ var api = getApi();
50
+ if (!api)
51
+ return {};
52
+ return {
53
+ analytics: api.analyticsProcessingAllowed(),
54
+ marketing: api.marketingAllowed(),
55
+ preferences: api.preferencesProcessingAllowed(),
56
+ sale_of_data: api.saleOfDataAllowed(),
57
+ };
58
+ },
59
+ isConsentReady: function () { return !!getApi(); },
49
60
  };
50
61
  };
51
62
  exports.shopifyConsentAdapter = shopifyConsentAdapter;
@@ -30,10 +30,24 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
30
30
  * Promise that resolves when CDP is ready
31
31
  */
32
32
  private cdpReadyPromise;
33
+ private consentConfig;
33
34
  private resetInProgress;
35
+ /**
36
+ * Queue for events waiting for consent to be ready
37
+ */
38
+ private consentEventQueue;
39
+ /**
40
+ * Whether we're currently waiting for consent and watching for it
41
+ */
42
+ private consentWatcherActive;
43
+ /**
44
+ * Promise that resolves when consent is ready (shared across all queued events)
45
+ */
46
+ private consentReadyPromise;
34
47
  constructor(options: ChordAnalyticsOptions<T>);
35
48
  /**
36
- * Initialize CDP snippet and wait for it to be ready
49
+ * Initialize CDP snippet and wait for it to be ready.
50
+ * Fires initial consent track event after CDP is fully initialized to avoid circular await.
37
51
  */
38
52
  private initializeCdp;
39
53
  /**
@@ -45,6 +59,29 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
45
59
  ccdp: () => AnyAnalytics;
46
60
  logger: (message?: any, ...optionalParams: any[]) => void;
47
61
  isResetting: () => boolean;
62
+ /**
63
+ * Wait for consent manager to be ready (no timeout - queues indefinitely).
64
+ * Uses a shared promise so multiple events share the same watcher.
65
+ */
66
+ private waitForConsent;
67
+ /**
68
+ * Queue an event to be sent when consent is ready.
69
+ * Starts a consent watcher if not already active.
70
+ */
71
+ private queueEventForConsent;
72
+ /**
73
+ * Watch for consent to become ready, then flush the queue.
74
+ */
75
+ private watchForConsentAndFlush;
76
+ /**
77
+ * Flush all queued events now that consent is ready.
78
+ */
79
+ private flushConsentQueue;
80
+ /**
81
+ * Configure CDP with fresh consent categories before each event.
82
+ * Uses Jitsu's configure() to update privacy.consentCategories.
83
+ */
84
+ private configureConsentOnCdp;
48
85
  validate: (event: string, props: EventProperties) => ValidateResult[];
49
86
  /**
50
87
  * Generate the event `meta` property.
@@ -67,21 +104,36 @@ export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> {
67
104
  addSourceMiddleware: (func: AnalyticsMiddleware) => void;
68
105
  /**
69
106
  * Send a `track` event to the CDP with any event name and properties.
107
+ * If consent is not ready, the event is queued until consent is available.
70
108
  */
71
109
  track: (event: string, props?: EventProperties, options?: Options) => Promise<void>;
110
+ /**
111
+ * Internal method to actually send a track event to CDP.
112
+ */
113
+ private sendTrackEvent;
72
114
  /**
73
115
  * Send an `identify` event to the CDP with user id and traits.
116
+ * If consent is not ready, the event is queued until consent is available.
74
117
  */
75
118
  identify: {
76
119
  (userId?: string, traits?: IdentifyTraits, options?: AnyOptions): Promise<void>;
77
120
  (traits?: IdentifyTraits, options?: AnyOptions): Promise<void>;
78
121
  };
122
+ /**
123
+ * Internal method to actually send an identify event to CDP.
124
+ */
125
+ private sendIdentifyEvent;
79
126
  /**
80
127
  * Send a `page` event to the CDP.
128
+ * If consent is not ready, the event is queued until consent is available.
81
129
  */
82
130
  page: {
83
- (props?: Record<string, any>): void;
131
+ (props?: Record<string, any>, options?: Options): void;
84
132
  };
133
+ /**
134
+ * Internal method to actually send a page event to CDP.
135
+ */
136
+ private sendPageEvent;
85
137
  reset: () => Promise<void>;
86
138
  trackCartViewed: (props: CartViewedInput<T>, options?: AnyOptions) => Promise<void>;
87
139
  trackCheckoutStarted: (props: CheckoutStartedInput<T>, options?: AnyOptions) => Promise<void>;