@codecademy/tracking 0.25.1-alpha.62d330.0 → 0.25.1-alpha.8af593.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.
- package/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +1 -1
- package/dist/integrations/__tests__/getConsentDecision.test.d.ts +1 -0
- package/dist/integrations/__tests__/getConsentDecision.test.js +58 -0
- package/dist/integrations/getConsentDecision.d.ts +8 -0
- package/dist/integrations/getConsentDecision.js +32 -0
- package/dist/integrations/index.js +13 -21
- package/dist/integrations/onetrust.d.ts +0 -4
- package/dist/integrations/onetrust.js +1 -15
- package/dist/integrations/types.d.ts +0 -5
- package/package.json +2 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[35m@codecademy/tracking:build: [0mcache hit, replaying output [
|
|
1
|
+
[35m@codecademy/tracking:build: [0mcache hit, replaying output [2m0460dd8835c0ee48[0m
|
|
2
2
|
[35m@codecademy/tracking:build: [0m$ yarn build:clean && yarn build:compile && yarn build:types
|
|
3
3
|
[35m@codecademy/tracking:build: [0m$ rm -rf dist
|
|
4
4
|
[35m@codecademy/tracking:build: [0m$ babel ./src --out-dir ./dist --copy-files --extensions ".ts,.tsx"
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
[35m@codecademy/tracking:build: [0m
|
|
8
8
|
[35m@codecademy/tracking:build: [0mWhy you should do it regularly:
|
|
9
9
|
[35m@codecademy/tracking:build: [0mhttps://github.com/browserslist/browserslist#browsers-data-updating
|
|
10
|
-
[35m@codecademy/tracking:build: [0mSuccessfully compiled
|
|
10
|
+
[35m@codecademy/tracking:build: [0mSuccessfully compiled 20 files with Babel (2607ms).
|
|
11
11
|
[35m@codecademy/tracking:build: [0m$ tsc --emitDeclarationOnly
|
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
### [0.25.1-alpha.
|
|
6
|
+
### [0.25.1-alpha.8af593.0](https://github.com/Codecademy/client-modules/compare/@codecademy/tracking@0.25.0...@codecademy/tracking@0.25.1-alpha.8af593.0) (2022-10-27)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @codecademy/tracking
|
|
9
9
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Consent } from '../consent';
|
|
2
|
+
import { getConsentDecision, OPT_OUT_DATALAYER_VAR } from '../getConsentDecision';
|
|
3
|
+
var MINIMUM_CONSENT = [Consent.StrictlyNecessary];
|
|
4
|
+
var FULL_CONSENT = [Consent.StrictlyNecessary, Consent.Functional, Consent.Performance, Consent.Targeting];
|
|
5
|
+
var FULL_CONSENT_STRING = [','].concat(FULL_CONSENT).join(',');
|
|
6
|
+
describe('getConsentDecision', function () {
|
|
7
|
+
it('converts a stringified consent decision into an array', function () {
|
|
8
|
+
var result = getConsentDecision({
|
|
9
|
+
scope: {
|
|
10
|
+
OnetrustActiveGroups: FULL_CONSENT_STRING
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
expect(result).toEqual(FULL_CONSENT);
|
|
14
|
+
});
|
|
15
|
+
it('does not modify an array formatted consent decision', function () {
|
|
16
|
+
var result = getConsentDecision({
|
|
17
|
+
scope: {
|
|
18
|
+
OnetrustActiveGroups: FULL_CONSENT
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
expect(result).toEqual(FULL_CONSENT);
|
|
22
|
+
});
|
|
23
|
+
describe('optedOutExternalTracking', function () {
|
|
24
|
+
it('Reduces the consent decision to necessary and functional for opted out users', function () {
|
|
25
|
+
var result = getConsentDecision({
|
|
26
|
+
scope: {
|
|
27
|
+
OnetrustActiveGroups: FULL_CONSENT
|
|
28
|
+
},
|
|
29
|
+
optedOutExternalTracking: true
|
|
30
|
+
});
|
|
31
|
+
expect(result).toEqual([Consent.StrictlyNecessary, Consent.Functional]);
|
|
32
|
+
});
|
|
33
|
+
it('Does not add Functional tracking if the user has opted out of it', function () {
|
|
34
|
+
var result = getConsentDecision({
|
|
35
|
+
scope: {
|
|
36
|
+
OnetrustActiveGroups: MINIMUM_CONSENT
|
|
37
|
+
},
|
|
38
|
+
optedOutExternalTracking: true
|
|
39
|
+
});
|
|
40
|
+
expect(result).toEqual(MINIMUM_CONSENT);
|
|
41
|
+
});
|
|
42
|
+
it('triggers the opt out datalayer variable', function () {
|
|
43
|
+
var _scope$dataLayer;
|
|
44
|
+
|
|
45
|
+
var scope = {
|
|
46
|
+
OnetrustActiveGroups: FULL_CONSENT
|
|
47
|
+
};
|
|
48
|
+
getConsentDecision({
|
|
49
|
+
scope: scope,
|
|
50
|
+
optedOutExternalTracking: true
|
|
51
|
+
});
|
|
52
|
+
var dataLayerVars = (_scope$dataLayer = scope.dataLayer) === null || _scope$dataLayer === void 0 ? void 0 : _scope$dataLayer.map(function (v) {
|
|
53
|
+
return Object.keys(v);
|
|
54
|
+
}).flat();
|
|
55
|
+
expect(dataLayerVars).toEqual([OPT_OUT_DATALAYER_VAR]);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +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[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
+
|
|
3
|
+
import { Consent } from './consent';
|
|
4
|
+
export var OPT_OUT_DATALAYER_VAR = 'user_opted_out_external_tracking';
|
|
5
|
+
export var getConsentDecision = function getConsentDecision(_ref) {
|
|
6
|
+
var scope = _ref.scope,
|
|
7
|
+
optedOutExternalTracking = _ref.optedOutExternalTracking;
|
|
8
|
+
var consentDecision = [];
|
|
9
|
+
|
|
10
|
+
if (typeof scope.OnetrustActiveGroups === 'string') {
|
|
11
|
+
consentDecision = scope.OnetrustActiveGroups.split(',').filter(Boolean);
|
|
12
|
+
} else if (scope.OnetrustActiveGroups) {
|
|
13
|
+
consentDecision = scope.OnetrustActiveGroups;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (optedOutExternalTracking) {
|
|
17
|
+
var _scope$dataLayer;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* If user has already opted out of everything but the essentials
|
|
21
|
+
* don't force them to consent to Functional trackers
|
|
22
|
+
*/
|
|
23
|
+
if (consentDecision.length > 1) {
|
|
24
|
+
consentDecision = [Consent.StrictlyNecessary, Consent.Functional];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
(_scope$dataLayer = scope.dataLayer) !== null && _scope$dataLayer !== void 0 ? _scope$dataLayer : scope.dataLayer = [];
|
|
28
|
+
scope.dataLayer.push(_defineProperty({}, OPT_OUT_DATALAYER_VAR, true));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return consentDecision;
|
|
32
|
+
};
|
|
@@ -5,16 +5,15 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try
|
|
|
5
5
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
6
6
|
|
|
7
7
|
import { conditionallyLoadAnalytics } from './conditionallyLoadAnalytics';
|
|
8
|
-
import { Consent } from './consent';
|
|
9
8
|
import { fetchDestinationsForWriteKey } from './fetchDestinationsForWriteKey';
|
|
9
|
+
import { getConsentDecision } from './getConsentDecision';
|
|
10
10
|
import { mapDestinations } from './mapDestinations';
|
|
11
|
-
import { initializeOneTrust
|
|
11
|
+
import { initializeOneTrust } from './onetrust';
|
|
12
12
|
import { runSegmentSnippet } from './runSegmentSnippet';
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
/**
|
|
15
15
|
* @see README.md for details and usage.
|
|
16
16
|
*/
|
|
17
|
-
|
|
18
17
|
export var initializeTrackingIntegrations = /*#__PURE__*/function () {
|
|
19
18
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
|
|
20
19
|
var onError, production, scope, user, optedOutExternalTracking, writeKey, destinations, consentDecision, _mapDestinations, destinationPreferences, identifyPreferences;
|
|
@@ -37,37 +36,30 @@ export var initializeTrackingIntegrations = /*#__PURE__*/function () {
|
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
case 5:
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
// 3. Segment's copy-and-paste snippet is run to load the Segment global library
|
|
42
40
|
runSegmentSnippet(); // 4. Destination integrations for Segment are fetched
|
|
43
41
|
|
|
44
|
-
_context.next =
|
|
42
|
+
_context.next = 8;
|
|
45
43
|
return fetchDestinationsForWriteKey({
|
|
46
44
|
onError: onError,
|
|
47
45
|
writeKey: writeKey
|
|
48
46
|
});
|
|
49
47
|
|
|
50
|
-
case
|
|
48
|
+
case 8:
|
|
51
49
|
destinations = _context.sent;
|
|
52
50
|
|
|
53
51
|
if (destinations) {
|
|
54
|
-
_context.next =
|
|
52
|
+
_context.next = 11;
|
|
55
53
|
break;
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
return _context.abrupt("return");
|
|
59
57
|
|
|
60
|
-
case
|
|
61
|
-
consentDecision =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else if (typeof scope.OnetrustActiveGroups === 'string') {
|
|
66
|
-
consentDecision = scope.OnetrustActiveGroups.split(',').filter(Boolean);
|
|
67
|
-
} else if (scope.OnetrustActiveGroups) {
|
|
68
|
-
consentDecision = scope.OnetrustActiveGroups;
|
|
69
|
-
} // 5. Those integrations are compared against the user's consent decisions into a list of allowed destinations
|
|
70
|
-
|
|
58
|
+
case 11:
|
|
59
|
+
consentDecision = getConsentDecision({
|
|
60
|
+
scope: scope,
|
|
61
|
+
optedOutExternalTracking: optedOutExternalTracking
|
|
62
|
+
}); // 5. Those integrations are compared against the user's consent decisions into a list of allowed destinations
|
|
71
63
|
|
|
72
64
|
_mapDestinations = mapDestinations({
|
|
73
65
|
consentDecision: consentDecision,
|
|
@@ -82,7 +74,7 @@ export var initializeTrackingIntegrations = /*#__PURE__*/function () {
|
|
|
82
74
|
writeKey: writeKey
|
|
83
75
|
});
|
|
84
76
|
|
|
85
|
-
case
|
|
77
|
+
case 14:
|
|
86
78
|
case "end":
|
|
87
79
|
return _context.stop();
|
|
88
80
|
}
|
|
@@ -4,7 +4,3 @@ export declare type OneTrustSettings = {
|
|
|
4
4
|
scope: TrackingWindow;
|
|
5
5
|
};
|
|
6
6
|
export declare const initializeOneTrust: ({ production, scope, }: OneTrustSettings) => Promise<void>;
|
|
7
|
-
/**
|
|
8
|
-
* update OneTrust constent for
|
|
9
|
-
*/
|
|
10
|
-
export declare const updateConsentForOptedOutUsers: (scope: TrackingWindow) => void;
|
|
@@ -45,21 +45,7 @@ export var initializeOneTrust = /*#__PURE__*/function () {
|
|
|
45
45
|
return function initializeOneTrust(_x) {
|
|
46
46
|
return _ref2.apply(this, arguments);
|
|
47
47
|
};
|
|
48
|
-
}();
|
|
49
|
-
/**
|
|
50
|
-
* update OneTrust constent for
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
export var updateConsentForOptedOutUsers = function updateConsentForOptedOutUsers(scope) {
|
|
54
|
-
var _scope$dataLayer2, _scope$OneTrust, _scope$OneTrust2, _scope$OneTrust2$Upda;
|
|
55
|
-
|
|
56
|
-
(_scope$dataLayer2 = scope.dataLayer) !== null && _scope$dataLayer2 !== void 0 ? _scope$dataLayer2 : scope.dataLayer = [];
|
|
57
|
-
(_scope$OneTrust = scope.OneTrust) === null || _scope$OneTrust === void 0 ? void 0 : _scope$OneTrust.RejectAll();
|
|
58
|
-
(_scope$OneTrust2 = scope.OneTrust) === null || _scope$OneTrust2 === void 0 ? void 0 : (_scope$OneTrust2$Upda = _scope$OneTrust2.UpdateConsent) === null || _scope$OneTrust2$Upda === void 0 ? void 0 : _scope$OneTrust2$Upda.call(_scope$OneTrust2, 'Category', 'C0003:1');
|
|
59
|
-
scope.dataLayer.push({
|
|
60
|
-
user_opted_out_external_tracking: 'true'
|
|
61
|
-
});
|
|
62
|
-
}; // For now, these three values duplicate theme colors from gamut-styles
|
|
48
|
+
}(); // For now, these three values duplicate theme colors from gamut-styles
|
|
63
49
|
// We don't want to take a full dependency on that package here...
|
|
64
50
|
|
|
65
51
|
var rawStyles = "\n:root {\n --onetrust-brand-purple: #3A10E5;\n --onetrust-color-gray-500: #828285;\n --onetrust-color-white: #fff;\n}\n\n#onetrust-banner-sdk {\n padding: 1rem !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container {\n width: 100% !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n max-width: 1436px !important;\n margin: 0 auto !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row:after {\n content: none !important;\n}\n#onetrust-group-container {\n display: flex !important;\n justify-content: center;\n float: none !important;\n width: 100% !important;\n max-width: 1148px !important;\n margin-left: 0 !important;\n margin-bottom: 0.625rem !important;\n}\n#onetrust-policy,\n#onetrust-policy-text {\n margin: 0 !important;\n font-size: 0.875rem !important;\n line-height: 1.375rem !important;\n text-align: center !important;\n float: none !important;\n}\n#onetrust-policy-text a {\n text-decoration: none;\n line-height: 26px !important;\n margin-left: 0 !important;\n}\n#onetrust-button-group-parent {\n position: relative !important;\n top: initial !important;\n left: initial !important;\n transform: initial !important;\n width: 264px !important;\n margin: 0 !important;\n padding: 0 !important;\n float: none !important;\n}\n#onetrust-button-group {\n display: flex !important;\n margin: 0 !important;\n}\n#onetrust-pc-btn-handler, #onetrust-accept-btn-handler {\n min-width: initial !important;\n padding: 0.375rem 1rem !important;\n margin: 0 !important;\n opacity: 1 !important;\n border-radius: 2px !important;\n line-height: 1.5 !important;\n user-select: none !important;\n font-size: 1rem !important;\n}\n#onetrust-pc-btn-handler:focus, #onetrust-accept-btn-handler:focus {\n box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);\n text-decoration: none !important;\n outline: none !important;\n}\n#onetrust-pc-btn-handler{\n color: var(--onetrust-brand-purple) !important;\n border: 1px solid var(--onetrust-brand-purple)!important;\n background: var(--onetrust-color-white) !important\n}\n#onetrust-accept-btn-handler {\n color: var(--onetrust-color-white) !important;\n background: var(--onetrust-brand-purple)!important;\n margin-left: 1rem !important;\n}\n#onetrust-close-btn-container {\n display: none !important;\n}\n\n.pc-logo {\n display: none !important;\n}\n\n#accept-recommended-btn-handler,\n.ot-pc-refuse-all-handler,\n.save-preference-btn-handler {\n margin-left: 4px !important;\n font-size: 14px !important;\n}\n\n#accept-recommended-btn-handler:focus,\n#onetrust-pc-sdk .ot-pc-refuse-all-handler:focus,\n#onetrust-pc-sdk .save-preference-btn-handler:focus {\n box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);\n text-decoration: none !important;\n outline: none !important;\n opacity: 1 !important;\n}\n\n.ot-switch-label {\n border: 1px solid var(--onetrust-color-gray-500) !important;\n background-color: var(--onetrust-color-gray-500) !important;\n}\n\n.ot-switch-nob {\n background: var(--onetrust-color-white) !important;\n}\n\n.ot-switch-inner:before {\n background-color: var(--onetrust-brand-purple) !important;\n}\n\n.switch-checkbox:checked+.ot-switch-label .ot-switch-nob {\n border-color: var(--onetrust-brand-purple) !important;\n}\n\n.ot-pc-footer-logo {\n display: none !important;\n}\n\n#onetrust-banner-sdk>.ot-sdk-container {\n overflow: visible !important;\n}\n\n@media (max-width: 30rem) {\n #accept-recommended-btn-handler,\n .ot-pc-refuse-all-handler,\n .save-preference-btn-handler {\n width: 96% !important;\n }\n}\n\n@media (min-width: 37.5rem) {\n #onetrust-banner-sdk {\n padding: 0.875rem 1rem !important;\n }\n}\n@media (min-width: 48rem) {\n #onetrust-banner-sdk {\n padding: 0.875rem 1.25rem !important;\n }\n}\n@media (min-width: 1650px) {\n #onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {\n flex-direction: row !important;\n justify-content: space-between !important;\n }\n #onetrust-group-container {\n margin-bottom: 0 !important;\n }\n #onetrust-button-group {\n flex-direction: row !important;\n }\n}\n";
|
|
@@ -16,14 +16,9 @@ export interface SegmentDestination {
|
|
|
16
16
|
export interface SegmentAnalyticsOptions {
|
|
17
17
|
integrations: Record<string, boolean>;
|
|
18
18
|
}
|
|
19
|
-
export interface OneTrustSDK {
|
|
20
|
-
RejectAll: () => void;
|
|
21
|
-
UpdateConsent?: (category: string, code: string) => void;
|
|
22
|
-
}
|
|
23
19
|
export interface TrackingWindow {
|
|
24
20
|
analytics?: SegmentAnalytics;
|
|
25
21
|
dataLayer?: unknown[];
|
|
26
22
|
OnetrustActiveGroups?: Consent[] | string;
|
|
27
23
|
OptanonWrapper?: () => void;
|
|
28
|
-
OneTrust?: OneTrustSDK;
|
|
29
24
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codecademy/tracking",
|
|
3
3
|
"description": "Tracking library for Codecademy apps.",
|
|
4
|
-
"version": "0.25.1-alpha.
|
|
4
|
+
"version": "0.25.1-alpha.8af593.0",
|
|
5
5
|
"author": "Codecademy Engineering <dev@codecademy.com>",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "0db0023e6841b1a2fedd426947b141cc3b99a0a2"
|
|
39
39
|
}
|