@chordcommerce/analytics 1.24.2 → 1.24.4
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.
- package/dist/cjs/client/consent/index.js +18 -9
- package/dist/cjs/client/consent/shopify.d.ts +5 -1
- package/dist/cjs/client/consent/shopify.js +76 -24
- package/dist/client/consent/index.js +8 -0
- package/dist/client/consent/shopify.d.ts +5 -1
- package/dist/client/consent/shopify.js +76 -24
- package/package.json +1 -1
|
@@ -171,7 +171,7 @@ var addCdpConsent = function (options) {
|
|
|
171
171
|
* or null if consent setup failed or was blocked.
|
|
172
172
|
*/
|
|
173
173
|
var init = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
174
|
-
var canBeTracked, error_2;
|
|
174
|
+
var canBeTracked, error_2, error_3;
|
|
175
175
|
return __generator(this, function (_a) {
|
|
176
176
|
switch (_a.label) {
|
|
177
177
|
case 0:
|
|
@@ -182,29 +182,38 @@ var addCdpConsent = function (options) {
|
|
|
182
182
|
console.error("Consent management adapter \"".concat(options.consent, "\" is not supported."));
|
|
183
183
|
return [2 /*return*/, null];
|
|
184
184
|
}
|
|
185
|
-
if (!options.awaitConsent) return [3 /*break*/,
|
|
185
|
+
if (!options.awaitConsent) return [3 /*break*/, 6];
|
|
186
186
|
if (options.debug && options.enableLogging) {
|
|
187
187
|
console.log('[Chord Analytics DEBUG]: awaitConsent is true, checking if user can be tracked');
|
|
188
188
|
}
|
|
189
189
|
return [4 /*yield*/, checkUserCanBeTracked()];
|
|
190
190
|
case 1:
|
|
191
191
|
canBeTracked = _a.sent();
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
return [2 /*return*/, null];
|
|
192
|
+
if (!!canBeTracked) return [3 /*break*/, 6];
|
|
193
|
+
if (options.debug && options.enableLogging) {
|
|
194
|
+
console.log('[Chord Analytics DEBUG]: User cannot be tracked, returning null');
|
|
197
195
|
}
|
|
198
196
|
_a.label = 2;
|
|
199
197
|
case 2:
|
|
200
198
|
_a.trys.push([2, 4, , 5]);
|
|
201
199
|
return [4 /*yield*/, setupConsentManagement()];
|
|
202
|
-
case 3:
|
|
200
|
+
case 3:
|
|
201
|
+
_a.sent();
|
|
202
|
+
return [3 /*break*/, 5];
|
|
203
203
|
case 4:
|
|
204
204
|
error_2 = _a.sent();
|
|
205
205
|
console.error('Error setting up consent management:', error_2);
|
|
206
|
+
return [3 /*break*/, 5];
|
|
207
|
+
case 5: return [2 /*return*/, null];
|
|
208
|
+
case 6:
|
|
209
|
+
_a.trys.push([6, 8, , 9]);
|
|
210
|
+
return [4 /*yield*/, setupConsentManagement()];
|
|
211
|
+
case 7: return [2 /*return*/, _a.sent()];
|
|
212
|
+
case 8:
|
|
213
|
+
error_3 = _a.sent();
|
|
214
|
+
console.error('Error setting up consent management:', error_3);
|
|
206
215
|
return [2 /*return*/, null];
|
|
207
|
-
case
|
|
216
|
+
case 9: return [2 /*return*/];
|
|
208
217
|
}
|
|
209
218
|
});
|
|
210
219
|
}); };
|
|
@@ -2,7 +2,11 @@ import type { ConsentConfiguration } from '../../types/index.js';
|
|
|
2
2
|
declare global {
|
|
3
3
|
interface Window {
|
|
4
4
|
Shopify?: {
|
|
5
|
-
customerPrivacy?: ShopifyCustomerPrivacyApi
|
|
5
|
+
customerPrivacy?: Partial<ShopifyCustomerPrivacyApi>;
|
|
6
|
+
loadFeatures?: (features: {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
}[], callback?: (error?: unknown) => void) => void;
|
|
6
10
|
};
|
|
7
11
|
}
|
|
8
12
|
}
|
|
@@ -2,36 +2,81 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.shopifyConsentAdapter = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* Returns Shopify's Customer Privacy API.
|
|
5
|
+
* Returns Shopify's Customer Privacy API, or undefined until its methods load.
|
|
6
|
+
*
|
|
7
|
+
* Shopify puts a placeholder `customerPrivacy` object on every storefront that
|
|
8
|
+
* holds only cached values. The methods appear once a script requests the
|
|
9
|
+
* `consent-tracking-api` feature, so the placeholder alone is not usable.
|
|
6
10
|
*/
|
|
7
|
-
var getApi = function () {
|
|
11
|
+
var getApi = function () {
|
|
12
|
+
var _a;
|
|
13
|
+
var api = (_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.customerPrivacy;
|
|
14
|
+
if (typeof (api === null || api === void 0 ? void 0 : api.analyticsProcessingAllowed) !== 'function' ||
|
|
15
|
+
typeof api.marketingAllowed !== 'function' ||
|
|
16
|
+
typeof api.preferencesProcessingAllowed !== 'function' ||
|
|
17
|
+
typeof api.saleOfDataAllowed !== 'function') {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
return api;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Requests the Customer Privacy API from Shopify when no other script has.
|
|
24
|
+
* CMPs such as CookieYes load it themselves; Shopify's own banner does not
|
|
25
|
+
* expose it, which left every event waiting on a consent check that threw.
|
|
26
|
+
*/
|
|
27
|
+
var loadApi = function () {
|
|
28
|
+
var _a;
|
|
29
|
+
if (getApi() || typeof ((_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.loadFeatures) !== 'function')
|
|
30
|
+
return;
|
|
31
|
+
try {
|
|
32
|
+
window.Shopify.loadFeatures([{ name: 'consent-tracking-api', version: '0.1' }], function (error) {
|
|
33
|
+
// eslint-disable-next-line no-console
|
|
34
|
+
if (error)
|
|
35
|
+
console.error('Could not load Shopify consent API', error);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.error('Could not load Shopify consent API', error);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
8
43
|
/**
|
|
9
44
|
* Returns whether the user can currently be tracked.
|
|
45
|
+
*
|
|
46
|
+
* Region is deliberately not checked: Shopify returns an empty region for
|
|
47
|
+
* visitors it hasn't geolocated (e.g. US visitors who never see a banner),
|
|
48
|
+
* even when analytics and marketing are both allowed. Opt-in regions already
|
|
49
|
+
* report both as not allowed until the visitor accepts.
|
|
10
50
|
*/
|
|
11
51
|
var userCanBeTracked = function () {
|
|
12
52
|
var api = getApi();
|
|
13
53
|
if (!api)
|
|
14
54
|
return false;
|
|
15
|
-
return !!(api.
|
|
16
|
-
api.analyticsProcessingAllowed() &&
|
|
17
|
-
api.marketingAllowed());
|
|
55
|
+
return !!(api.analyticsProcessingAllowed() && api.marketingAllowed());
|
|
18
56
|
};
|
|
19
57
|
/**
|
|
20
|
-
* Returns the user's current consent
|
|
58
|
+
* Returns the user's current consent categories, or an empty object until the
|
|
59
|
+
* API has loaded.
|
|
21
60
|
*/
|
|
22
|
-
var
|
|
61
|
+
var getCategories = function () {
|
|
23
62
|
var api = getApi();
|
|
24
63
|
if (!api)
|
|
25
64
|
return {};
|
|
26
65
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
sale_of_data: api.saleOfDataAllowed(),
|
|
32
|
-
},
|
|
66
|
+
analytics: api.analyticsProcessingAllowed(),
|
|
67
|
+
marketing: api.marketingAllowed(),
|
|
68
|
+
preferences: api.preferencesProcessingAllowed(),
|
|
69
|
+
sale_of_data: api.saleOfDataAllowed(),
|
|
33
70
|
};
|
|
34
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Returns the user's current consent configuration.
|
|
74
|
+
*/
|
|
75
|
+
var getCurrentConsent = function () {
|
|
76
|
+
if (!getApi())
|
|
77
|
+
return {};
|
|
78
|
+
return { consentCategories: getCategories() };
|
|
79
|
+
};
|
|
35
80
|
/**
|
|
36
81
|
* Handles subsequent changes to consent configuration.
|
|
37
82
|
*/
|
|
@@ -41,22 +86,29 @@ var handleConsentUpdates = function (updateCdpConsent) {
|
|
|
41
86
|
});
|
|
42
87
|
};
|
|
43
88
|
var shopifyConsentAdapter = function () {
|
|
89
|
+
// Requested once per adapter. Retried from isConsentReady() because the
|
|
90
|
+
// SDK can start before Shopify defines loadFeatures.
|
|
91
|
+
var apiRequested = false;
|
|
92
|
+
var requestApi = function () {
|
|
93
|
+
var _a;
|
|
94
|
+
if (apiRequested || typeof ((_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.loadFeatures) !== 'function') {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
apiRequested = true;
|
|
98
|
+
loadApi();
|
|
99
|
+
};
|
|
100
|
+
requestApi();
|
|
44
101
|
return {
|
|
45
102
|
getCurrentConsent: getCurrentConsent,
|
|
46
103
|
handleConsentUpdates: handleConsentUpdates,
|
|
47
104
|
userCanBeTracked: userCanBeTracked,
|
|
48
|
-
getCategories:
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
marketing: api.marketingAllowed(),
|
|
55
|
-
preferences: api.preferencesProcessingAllowed(),
|
|
56
|
-
sale_of_data: api.saleOfDataAllowed(),
|
|
57
|
-
};
|
|
105
|
+
getCategories: getCategories,
|
|
106
|
+
isConsentReady: function () {
|
|
107
|
+
if (getApi())
|
|
108
|
+
return true;
|
|
109
|
+
requestApi();
|
|
110
|
+
return false;
|
|
58
111
|
},
|
|
59
|
-
isConsentReady: function () { return !!getApi(); },
|
|
60
112
|
};
|
|
61
113
|
};
|
|
62
114
|
exports.shopifyConsentAdapter = shopifyConsentAdapter;
|
|
@@ -136,6 +136,14 @@ export const addCdpConsent = (options) => {
|
|
|
136
136
|
if (options.debug && options.enableLogging) {
|
|
137
137
|
console.log('[Chord Analytics DEBUG]: User cannot be tracked, returning null');
|
|
138
138
|
}
|
|
139
|
+
// Still listen for consent changes, so a visitor who accepts after
|
|
140
|
+
// the timeout is picked up instead of being lost for the whole visit.
|
|
141
|
+
try {
|
|
142
|
+
yield setupConsentManagement();
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
console.error('Error setting up consent management:', error);
|
|
146
|
+
}
|
|
139
147
|
return null;
|
|
140
148
|
}
|
|
141
149
|
}
|
|
@@ -2,7 +2,11 @@ import type { ConsentConfiguration } from '../../types/index.js';
|
|
|
2
2
|
declare global {
|
|
3
3
|
interface Window {
|
|
4
4
|
Shopify?: {
|
|
5
|
-
customerPrivacy?: ShopifyCustomerPrivacyApi
|
|
5
|
+
customerPrivacy?: Partial<ShopifyCustomerPrivacyApi>;
|
|
6
|
+
loadFeatures?: (features: {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
}[], callback?: (error?: unknown) => void) => void;
|
|
6
10
|
};
|
|
7
11
|
}
|
|
8
12
|
}
|
|
@@ -1,34 +1,79 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns Shopify's Customer Privacy API.
|
|
2
|
+
* Returns Shopify's Customer Privacy API, or undefined until its methods load.
|
|
3
|
+
*
|
|
4
|
+
* Shopify puts a placeholder `customerPrivacy` object on every storefront that
|
|
5
|
+
* holds only cached values. The methods appear once a script requests the
|
|
6
|
+
* `consent-tracking-api` feature, so the placeholder alone is not usable.
|
|
3
7
|
*/
|
|
4
|
-
const getApi = () => {
|
|
8
|
+
const getApi = () => {
|
|
9
|
+
var _a;
|
|
10
|
+
const api = (_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.customerPrivacy;
|
|
11
|
+
if (typeof (api === null || api === void 0 ? void 0 : api.analyticsProcessingAllowed) !== 'function' ||
|
|
12
|
+
typeof api.marketingAllowed !== 'function' ||
|
|
13
|
+
typeof api.preferencesProcessingAllowed !== 'function' ||
|
|
14
|
+
typeof api.saleOfDataAllowed !== 'function') {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return api;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Requests the Customer Privacy API from Shopify when no other script has.
|
|
21
|
+
* CMPs such as CookieYes load it themselves; Shopify's own banner does not
|
|
22
|
+
* expose it, which left every event waiting on a consent check that threw.
|
|
23
|
+
*/
|
|
24
|
+
const loadApi = () => {
|
|
25
|
+
var _a;
|
|
26
|
+
if (getApi() || typeof ((_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.loadFeatures) !== 'function')
|
|
27
|
+
return;
|
|
28
|
+
try {
|
|
29
|
+
window.Shopify.loadFeatures([{ name: 'consent-tracking-api', version: '0.1' }], (error) => {
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
if (error)
|
|
32
|
+
console.error('Could not load Shopify consent API', error);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.error('Could not load Shopify consent API', error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
5
40
|
/**
|
|
6
41
|
* Returns whether the user can currently be tracked.
|
|
42
|
+
*
|
|
43
|
+
* Region is deliberately not checked: Shopify returns an empty region for
|
|
44
|
+
* visitors it hasn't geolocated (e.g. US visitors who never see a banner),
|
|
45
|
+
* even when analytics and marketing are both allowed. Opt-in regions already
|
|
46
|
+
* report both as not allowed until the visitor accepts.
|
|
7
47
|
*/
|
|
8
48
|
const userCanBeTracked = () => {
|
|
9
49
|
const api = getApi();
|
|
10
50
|
if (!api)
|
|
11
51
|
return false;
|
|
12
|
-
return !!(api.
|
|
13
|
-
api.analyticsProcessingAllowed() &&
|
|
14
|
-
api.marketingAllowed());
|
|
52
|
+
return !!(api.analyticsProcessingAllowed() && api.marketingAllowed());
|
|
15
53
|
};
|
|
16
54
|
/**
|
|
17
|
-
* Returns the user's current consent
|
|
55
|
+
* Returns the user's current consent categories, or an empty object until the
|
|
56
|
+
* API has loaded.
|
|
18
57
|
*/
|
|
19
|
-
const
|
|
58
|
+
const getCategories = () => {
|
|
20
59
|
const api = getApi();
|
|
21
60
|
if (!api)
|
|
22
61
|
return {};
|
|
23
62
|
return {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
sale_of_data: api.saleOfDataAllowed(),
|
|
29
|
-
},
|
|
63
|
+
analytics: api.analyticsProcessingAllowed(),
|
|
64
|
+
marketing: api.marketingAllowed(),
|
|
65
|
+
preferences: api.preferencesProcessingAllowed(),
|
|
66
|
+
sale_of_data: api.saleOfDataAllowed(),
|
|
30
67
|
};
|
|
31
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* Returns the user's current consent configuration.
|
|
71
|
+
*/
|
|
72
|
+
const getCurrentConsent = () => {
|
|
73
|
+
if (!getApi())
|
|
74
|
+
return {};
|
|
75
|
+
return { consentCategories: getCategories() };
|
|
76
|
+
};
|
|
32
77
|
/**
|
|
33
78
|
* Handles subsequent changes to consent configuration.
|
|
34
79
|
*/
|
|
@@ -38,21 +83,28 @@ const handleConsentUpdates = (updateCdpConsent) => {
|
|
|
38
83
|
});
|
|
39
84
|
};
|
|
40
85
|
export const shopifyConsentAdapter = () => {
|
|
86
|
+
// Requested once per adapter. Retried from isConsentReady() because the
|
|
87
|
+
// SDK can start before Shopify defines loadFeatures.
|
|
88
|
+
let apiRequested = false;
|
|
89
|
+
const requestApi = () => {
|
|
90
|
+
var _a;
|
|
91
|
+
if (apiRequested || typeof ((_a = window.Shopify) === null || _a === void 0 ? void 0 : _a.loadFeatures) !== 'function') {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
apiRequested = true;
|
|
95
|
+
loadApi();
|
|
96
|
+
};
|
|
97
|
+
requestApi();
|
|
41
98
|
return {
|
|
42
99
|
getCurrentConsent,
|
|
43
100
|
handleConsentUpdates,
|
|
44
101
|
userCanBeTracked,
|
|
45
|
-
getCategories
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
marketing: api.marketingAllowed(),
|
|
52
|
-
preferences: api.preferencesProcessingAllowed(),
|
|
53
|
-
sale_of_data: api.saleOfDataAllowed(),
|
|
54
|
-
};
|
|
102
|
+
getCategories,
|
|
103
|
+
isConsentReady: () => {
|
|
104
|
+
if (getApi())
|
|
105
|
+
return true;
|
|
106
|
+
requestApi();
|
|
107
|
+
return false;
|
|
55
108
|
},
|
|
56
|
-
isConsentReady: () => !!getApi(),
|
|
57
109
|
};
|
|
58
110
|
};
|
package/package.json
CHANGED