c15t 0.0.1-rc.3

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 (86) hide show
  1. package/.turbo/turbo-build.log +54 -0
  2. package/.turbo/turbo-fmt.log +6 -0
  3. package/.turbo/turbo-lint.log +288 -0
  4. package/.turbo/turbo-test.log +33 -0
  5. package/CHANGELOG.md +20 -0
  6. package/LICENSE.md +595 -0
  7. package/README.md +28 -0
  8. package/dist/index.cjs +118 -0
  9. package/dist/index.d.ts +27 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +19 -0
  12. package/dist/libs/__tests__/tracking-blocker.test.cjs +269 -0
  13. package/dist/libs/__tests__/tracking-blocker.test.d.ts +2 -0
  14. package/dist/libs/__tests__/tracking-blocker.test.d.ts.map +1 -0
  15. package/dist/libs/__tests__/tracking-blocker.test.js +267 -0
  16. package/dist/libs/consent-utils.cjs +68 -0
  17. package/dist/libs/consent-utils.d.ts +49 -0
  18. package/dist/libs/consent-utils.d.ts.map +1 -0
  19. package/dist/libs/consent-utils.js +23 -0
  20. package/dist/libs/tracking-blocker.cjs +167 -0
  21. package/dist/libs/tracking-blocker.d.ts +33 -0
  22. package/dist/libs/tracking-blocker.d.ts.map +1 -0
  23. package/dist/libs/tracking-blocker.js +108 -0
  24. package/dist/libs/tracking-domains.cjs +188 -0
  25. package/dist/libs/tracking-domains.d.ts +7 -0
  26. package/dist/libs/tracking-domains.d.ts.map +1 -0
  27. package/dist/libs/tracking-domains.js +146 -0
  28. package/dist/store.cjs +248 -0
  29. package/dist/store.d.ts +58 -0
  30. package/dist/store.d.ts.map +1 -0
  31. package/dist/store.initial-state.cjs +105 -0
  32. package/dist/store.initial-state.d.ts +43 -0
  33. package/dist/store.initial-state.d.ts.map +1 -0
  34. package/dist/store.initial-state.js +66 -0
  35. package/dist/store.js +219 -0
  36. package/dist/store.type.cjs +22 -0
  37. package/dist/store.type.d.ts +159 -0
  38. package/dist/store.type.d.ts.map +1 -0
  39. package/dist/store.type.js +0 -0
  40. package/dist/translations/en.cjs +96 -0
  41. package/dist/translations/en.d.ts +3 -0
  42. package/dist/translations/en.d.ts.map +1 -0
  43. package/dist/translations/en.js +54 -0
  44. package/dist/translations/index.cjs +51 -0
  45. package/dist/translations/index.d.ts +3 -0
  46. package/dist/translations/index.d.ts.map +1 -0
  47. package/dist/translations/index.js +9 -0
  48. package/dist/types/callbacks.cjs +22 -0
  49. package/dist/types/callbacks.d.ts +146 -0
  50. package/dist/types/callbacks.d.ts.map +1 -0
  51. package/dist/types/callbacks.js +0 -0
  52. package/dist/types/compliance.cjs +22 -0
  53. package/dist/types/compliance.d.ts +196 -0
  54. package/dist/types/compliance.d.ts.map +1 -0
  55. package/dist/types/compliance.js +0 -0
  56. package/dist/types/gdpr.cjs +86 -0
  57. package/dist/types/gdpr.d.ts +168 -0
  58. package/dist/types/gdpr.d.ts.map +1 -0
  59. package/dist/types/gdpr.js +44 -0
  60. package/dist/types/index.cjs +44 -0
  61. package/dist/types/index.d.ts +141 -0
  62. package/dist/types/index.d.ts.map +1 -0
  63. package/dist/types/index.js +4 -0
  64. package/dist/types/translations.cjs +22 -0
  65. package/dist/types/translations.d.ts +52 -0
  66. package/dist/types/translations.d.ts.map +1 -0
  67. package/dist/types/translations.js +0 -0
  68. package/package.json +33 -0
  69. package/rslib.config.ts +28 -0
  70. package/src/index.ts +31 -0
  71. package/src/libs/__tests__/tracking-blocker.test.ts +271 -0
  72. package/src/libs/consent-utils.ts +70 -0
  73. package/src/libs/tracking-blocker.ts +202 -0
  74. package/src/libs/tracking-domains.ts +158 -0
  75. package/src/store.initial-state.ts +123 -0
  76. package/src/store.ts +450 -0
  77. package/src/store.type.ts +187 -0
  78. package/src/translations/en.ts +55 -0
  79. package/src/translations/index.ts +10 -0
  80. package/src/types/callbacks.ts +152 -0
  81. package/src/types/compliance.ts +205 -0
  82. package/src/types/gdpr.ts +217 -0
  83. package/src/types/index.ts +148 -0
  84. package/src/types/translations.ts +60 -0
  85. package/tsconfig.json +12 -0
  86. package/vitest.config.ts +15 -0
@@ -0,0 +1,267 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE_vitest__ from 'vitest';
2
+ import * as __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__ from '../tracking-blocker.js';
3
+ var __webpack_require__ = {};
4
+ (() => {
5
+ __webpack_require__.g = (function () {
6
+ if ('object' == typeof globalThis) return globalThis;
7
+ try {
8
+ return this || new Function('return this')();
9
+ } catch (e) {
10
+ if ('object' == typeof window) return window;
11
+ }
12
+ })();
13
+ })();
14
+ const BLOCKED_CONSENT = {
15
+ experience: false,
16
+ functionality: false,
17
+ marketing: false,
18
+ measurement: false,
19
+ necessary: true,
20
+ };
21
+ const ALLOWED_CONSENT = {
22
+ ...BLOCKED_CONSENT,
23
+ measurement: true,
24
+ };
25
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.describe)('TrackingBlocker', () => {
26
+ const originalFetch = __webpack_require__.g.fetch;
27
+ const originalXHR = __webpack_require__.g.XMLHttpRequest;
28
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.beforeAll)(() => {
29
+ __webpack_require__.g.fetch = __WEBPACK_EXTERNAL_MODULE_vitest__.vi
30
+ .fn()
31
+ .mockImplementation(() => Promise.resolve(new Response()));
32
+ if (!__webpack_require__.g.XMLHttpRequest)
33
+ __webpack_require__.g.XMLHttpRequest = originalXHR;
34
+ });
35
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.afterAll)(() => {
36
+ __webpack_require__.g.fetch = originalFetch;
37
+ __webpack_require__.g.XMLHttpRequest = originalXHR;
38
+ });
39
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.beforeEach)(() => {
40
+ __WEBPACK_EXTERNAL_MODULE_vitest__.vi.clearAllMocks();
41
+ __WEBPACK_EXTERNAL_MODULE_vitest__.vi.restoreAllMocks();
42
+ __webpack_require__.g.fetch = __WEBPACK_EXTERNAL_MODULE_vitest__.vi
43
+ .fn()
44
+ .mockImplementation(() => Promise.resolve(new Response()));
45
+ window.fetch = __webpack_require__.g.fetch;
46
+ window.XMLHttpRequest = originalXHR;
47
+ __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(document, 'dispatchEvent');
48
+ });
49
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
50
+ 'blocks fetch requests to tracking domains when consent not granted',
51
+ async () => {
52
+ (0,
53
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
54
+ {},
55
+ BLOCKED_CONSENT
56
+ );
57
+ await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
58
+ fetch('https://www.google-analytics.com/analytics.js')
59
+ ).rejects.toThrow(
60
+ 'Request to https://www.google-analytics.com/analytics.js blocked due to missing consent'
61
+ );
62
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
63
+ document.dispatchEvent
64
+ ).toHaveBeenCalledWith(
65
+ __WEBPACK_EXTERNAL_MODULE_vitest__.expect.objectContaining({
66
+ type: 'ConsentBlockedRequest',
67
+ detail: {
68
+ url: 'https://www.google-analytics.com/analytics.js',
69
+ },
70
+ })
71
+ );
72
+ }
73
+ );
74
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
75
+ 'blocks XMLHttpRequest to tracking domains when consent not granted',
76
+ () => {
77
+ (0,
78
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
79
+ {},
80
+ BLOCKED_CONSENT
81
+ );
82
+ const xhr = new XMLHttpRequest();
83
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
84
+ xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
85
+ }).toThrow(
86
+ 'Request to https://www.google-analytics.com/analytics.js blocked due to missing consent'
87
+ );
88
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
89
+ document.dispatchEvent
90
+ ).toHaveBeenCalledWith(
91
+ __WEBPACK_EXTERNAL_MODULE_vitest__.expect.objectContaining({
92
+ type: 'ConsentBlockedRequest',
93
+ detail: {
94
+ url: 'https://www.google-analytics.com/analytics.js',
95
+ },
96
+ })
97
+ );
98
+ }
99
+ );
100
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
101
+ 'allows fetch requests to tracking domains after consent granted',
102
+ async () => {
103
+ window.fetch = __webpack_require__.g.fetch;
104
+ const trackingBlocker = (0,
105
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
106
+ {},
107
+ ALLOWED_CONSENT
108
+ );
109
+ const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
110
+ window,
111
+ 'fetch'
112
+ );
113
+ await fetch('https://www.google-analytics.com/analytics.js');
114
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
115
+ fetchSpy
116
+ ).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
117
+ trackingBlocker.destroy();
118
+ }
119
+ );
120
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
121
+ 'allows XMLHttpRequest to tracking domains after consent granted',
122
+ () => {
123
+ (0,
124
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
125
+ {},
126
+ ALLOWED_CONSENT
127
+ );
128
+ const xhr = new XMLHttpRequest();
129
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
130
+ xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
131
+ }).not.toThrow();
132
+ }
133
+ );
134
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
135
+ 'allows requests to non-tracking domains regardless of consent',
136
+ async () => {
137
+ (0,
138
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
139
+ {},
140
+ BLOCKED_CONSENT
141
+ );
142
+ const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
143
+ window,
144
+ 'fetch'
145
+ );
146
+ await fetch('https://api.example.com/data');
147
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
148
+ fetchSpy
149
+ ).toHaveBeenCalledWith('https://api.example.com/data');
150
+ const xhr = new XMLHttpRequest();
151
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
152
+ xhr.open('GET', 'https://api.example.com/data');
153
+ }).not.toThrow();
154
+ }
155
+ );
156
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
157
+ 'handles custom domain consent map',
158
+ async () => {
159
+ const trackingBlocker = (0,
160
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
161
+ {
162
+ overrideDomainConsentMap: true,
163
+ domainConsentMap: {
164
+ 'custom-analytics.example.com': 'measurement',
165
+ },
166
+ },
167
+ BLOCKED_CONSENT
168
+ );
169
+ await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
170
+ fetch('https://custom-analytics.example.com/track')
171
+ ).rejects.toThrow(
172
+ 'Request to https://custom-analytics.example.com/track blocked due to missing consent'
173
+ );
174
+ trackingBlocker.updateConsents({
175
+ experience: false,
176
+ functionality: false,
177
+ marketing: false,
178
+ measurement: true,
179
+ necessary: true,
180
+ });
181
+ const fetchSpy = __WEBPACK_EXTERNAL_MODULE_vitest__.vi.spyOn(
182
+ window,
183
+ 'fetch'
184
+ );
185
+ await fetch('https://custom-analytics.example.com/track');
186
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
187
+ fetchSpy
188
+ ).toHaveBeenCalledWith('https://custom-analytics.example.com/track');
189
+ }
190
+ );
191
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
192
+ 'handles subdomains correctly',
193
+ async () => {
194
+ (0,
195
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
196
+ {},
197
+ BLOCKED_CONSENT
198
+ );
199
+ await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
200
+ fetch('https://subdomain.google-analytics.com/track')
201
+ ).rejects.toThrow(
202
+ 'Request to https://subdomain.google-analytics.com/track blocked due to missing consent'
203
+ );
204
+ }
205
+ );
206
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
207
+ 'can be disabled via config',
208
+ async () => {
209
+ (0,
210
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
211
+ {
212
+ disableAutomaticBlocking: true,
213
+ },
214
+ BLOCKED_CONSENT
215
+ );
216
+ await fetch('https://www.google-analytics.com/analytics.js');
217
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
218
+ fetch
219
+ ).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
220
+ }
221
+ );
222
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
223
+ 'cleanup restores original fetch and XMLHttpRequest functionality',
224
+ async () => {
225
+ const trackingBlocker = (0,
226
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
227
+ {},
228
+ BLOCKED_CONSENT
229
+ );
230
+ await (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
231
+ fetch('https://www.google-analytics.com/analytics.js')
232
+ ).rejects.toThrow();
233
+ trackingBlocker.destroy();
234
+ await fetch('https://www.google-analytics.com/analytics.js');
235
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
236
+ fetch
237
+ ).toHaveBeenCalledWith('https://www.google-analytics.com/analytics.js');
238
+ const xhr = new XMLHttpRequest();
239
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(() => {
240
+ xhr.open('GET', 'https://www.google-analytics.com/analytics.js');
241
+ }).not.toThrow();
242
+ }
243
+ );
244
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.test)(
245
+ 'handles multiple concurrent requests correctly',
246
+ async () => {
247
+ (0,
248
+ __WEBPACK_EXTERNAL_MODULE__tracking_blocker_js_d038b07a__.createTrackingBlocker)(
249
+ {},
250
+ BLOCKED_CONSENT
251
+ );
252
+ const requests = Promise.all([
253
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
254
+ fetch('https://www.google-analytics.com/analytics.js')
255
+ ).rejects.toThrow(),
256
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
257
+ fetch('https://www.google-analytics.com/collect')
258
+ ).rejects.toThrow(),
259
+ fetch('https://api.example.com/data'),
260
+ ]);
261
+ await requests;
262
+ (0, __WEBPACK_EXTERNAL_MODULE_vitest__.expect)(
263
+ document.dispatchEvent
264
+ ).toHaveBeenCalledTimes(6);
265
+ }
266
+ );
267
+ });
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+ var __webpack_require__ = {};
3
+ (() => {
4
+ __webpack_require__.d = function (exports1, definition) {
5
+ for (var key in definition)
6
+ if (
7
+ __webpack_require__.o(definition, key) &&
8
+ !__webpack_require__.o(exports1, key)
9
+ )
10
+ Object.defineProperty(exports1, key, {
11
+ enumerable: true,
12
+ get: definition[key],
13
+ });
14
+ };
15
+ })();
16
+ (() => {
17
+ __webpack_require__.o = function (obj, prop) {
18
+ return Object.prototype.hasOwnProperty.call(obj, prop);
19
+ };
20
+ })();
21
+ (() => {
22
+ __webpack_require__.r = function (exports1) {
23
+ if ('undefined' != typeof Symbol && Symbol.toStringTag)
24
+ Object.defineProperty(exports1, Symbol.toStringTag, {
25
+ value: 'Module',
26
+ });
27
+ Object.defineProperty(exports1, '__esModule', {
28
+ value: true,
29
+ });
30
+ };
31
+ })();
32
+ var __webpack_exports__ = {};
33
+ __webpack_require__.r(__webpack_exports__);
34
+ __webpack_require__.d(__webpack_exports__, {
35
+ getEffectiveConsents: () => getEffectiveConsents,
36
+ hasConsentFor: () => hasConsentFor,
37
+ hasConsented: () => hasConsented,
38
+ isConsentEnabled: () => isConsentEnabled,
39
+ });
40
+ function getEffectiveConsents(consents, honorDoNotTrack) {
41
+ if (
42
+ honorDoNotTrack &&
43
+ 'undefined' != typeof window &&
44
+ '1' === window.navigator.doNotTrack
45
+ )
46
+ return Object.keys(consents).reduce((acc, key) => {
47
+ if (key in consents) acc[key] = 'necessary' === key;
48
+ return acc;
49
+ }, {});
50
+ return consents;
51
+ }
52
+ function hasConsentFor(consentType, consents, honorDoNotTrack) {
53
+ const effectiveConsents = getEffectiveConsents(consents, honorDoNotTrack);
54
+ return effectiveConsents[consentType] || false;
55
+ }
56
+ function hasConsented(consentInfo) {
57
+ return null !== consentInfo;
58
+ }
59
+ function isConsentEnabled(consentType, consents) {
60
+ return consents[consentType] || false;
61
+ }
62
+ var __webpack_export_target__ = exports;
63
+ for (var __webpack_i__ in __webpack_exports__)
64
+ __webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
65
+ if (__webpack_exports__.__esModule)
66
+ Object.defineProperty(__webpack_export_target__, '__esModule', {
67
+ value: true,
68
+ });
@@ -0,0 +1,49 @@
1
+ import type { AllConsentNames, ConsentState } from '../types';
2
+ /**
3
+ * Determines the effective consents based on the user's Do Not Track setting.
4
+ *
5
+ * @param consents - The current state of user consents.
6
+ * @param honorDoNotTrack - Whether to respect the user's Do Not Track setting.
7
+ * @returns The effective consents after considering Do Not Track.
8
+ */
9
+ export declare function getEffectiveConsents(
10
+ consents: ConsentState,
11
+ honorDoNotTrack: boolean
12
+ ): ConsentState;
13
+ /**
14
+ * Checks if the user has given consent for a specific type.
15
+ *
16
+ * @param consentType - The type of consent to check.
17
+ * @param consents - The current state of user consents.
18
+ * @param honorDoNotTrack - Whether to respect the user's Do Not Track setting.
19
+ * @returns True if consent is given, false otherwise.
20
+ */
21
+ export declare function hasConsentFor(
22
+ consentType: AllConsentNames,
23
+ consents: ConsentState,
24
+ honorDoNotTrack: boolean
25
+ ): boolean;
26
+ /**
27
+ * Determines if the user has consented based on consent information.
28
+ *
29
+ * @param consentInfo - The consent information.
30
+ * @returns True if the user has consented, false otherwise.
31
+ */
32
+ export declare function hasConsented(
33
+ consentInfo: {
34
+ time: number;
35
+ type: 'all' | 'custom' | 'necessary';
36
+ } | null
37
+ ): boolean;
38
+ /**
39
+ * Checks if a specific consent type is enabled.
40
+ *
41
+ * @param consentType - The type of consent to check.
42
+ * @param consents - The current state of user consents.
43
+ * @returns True if the consent type is enabled, false otherwise.
44
+ */
45
+ export declare function isConsentEnabled(
46
+ consentType: AllConsentNames,
47
+ consents: ConsentState
48
+ ): boolean;
49
+ //# sourceMappingURL=consent-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-utils.d.ts","sourceRoot":"","sources":["../../src/libs/consent-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,OAAO,GACtB,YAAY,CAcd;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC5B,WAAW,EAAE,eAAe,EAC5B,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,OAAO,GACtB,OAAO,CAGT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAA;CAAE,GAAG,IAAI,GACxE,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,WAAW,EAAE,eAAe,EAC5B,QAAQ,EAAE,YAAY,GACpB,OAAO,CAET"}
@@ -0,0 +1,23 @@
1
+ function getEffectiveConsents(consents, honorDoNotTrack) {
2
+ if (
3
+ honorDoNotTrack &&
4
+ 'undefined' != typeof window &&
5
+ '1' === window.navigator.doNotTrack
6
+ )
7
+ return Object.keys(consents).reduce((acc, key) => {
8
+ if (key in consents) acc[key] = 'necessary' === key;
9
+ return acc;
10
+ }, {});
11
+ return consents;
12
+ }
13
+ function hasConsentFor(consentType, consents, honorDoNotTrack) {
14
+ const effectiveConsents = getEffectiveConsents(consents, honorDoNotTrack);
15
+ return effectiveConsents[consentType] || false;
16
+ }
17
+ function hasConsented(consentInfo) {
18
+ return null !== consentInfo;
19
+ }
20
+ function isConsentEnabled(consentType, consents) {
21
+ return consents[consentType] || false;
22
+ }
23
+ export { getEffectiveConsents, hasConsentFor, hasConsented, isConsentEnabled };
@@ -0,0 +1,167 @@
1
+ 'use strict';
2
+ var __webpack_require__ = {};
3
+ (() => {
4
+ __webpack_require__.n = function (module) {
5
+ var getter =
6
+ module && module.__esModule
7
+ ? function () {
8
+ return module['default'];
9
+ }
10
+ : function () {
11
+ return module;
12
+ };
13
+ __webpack_require__.d(getter, {
14
+ a: getter,
15
+ });
16
+ return getter;
17
+ };
18
+ })();
19
+ (() => {
20
+ __webpack_require__.d = function (exports1, definition) {
21
+ for (var key in definition)
22
+ if (
23
+ __webpack_require__.o(definition, key) &&
24
+ !__webpack_require__.o(exports1, key)
25
+ )
26
+ Object.defineProperty(exports1, key, {
27
+ enumerable: true,
28
+ get: definition[key],
29
+ });
30
+ };
31
+ })();
32
+ (() => {
33
+ __webpack_require__.o = function (obj, prop) {
34
+ return Object.prototype.hasOwnProperty.call(obj, prop);
35
+ };
36
+ })();
37
+ (() => {
38
+ __webpack_require__.r = function (exports1) {
39
+ if ('undefined' != typeof Symbol && Symbol.toStringTag)
40
+ Object.defineProperty(exports1, Symbol.toStringTag, {
41
+ value: 'Module',
42
+ });
43
+ Object.defineProperty(exports1, '__esModule', {
44
+ value: true,
45
+ });
46
+ };
47
+ })();
48
+ var __webpack_exports__ = {};
49
+ __webpack_require__.r(__webpack_exports__);
50
+ __webpack_require__.d(__webpack_exports__, {
51
+ createTrackingBlocker: () => createTrackingBlocker,
52
+ });
53
+ const external_tracking_domains_cjs_namespaceObject = require('./tracking-domains.cjs');
54
+ var external_tracking_domains_cjs_default = /*#__PURE__*/ __webpack_require__.n(
55
+ external_tracking_domains_cjs_namespaceObject
56
+ );
57
+ function createDefaultConsentState() {
58
+ return {
59
+ experience: false,
60
+ functionality: false,
61
+ marketing: false,
62
+ measurement: false,
63
+ necessary: true,
64
+ };
65
+ }
66
+ function createTrackingBlocker(config = {}, initialConsents) {
67
+ const blockerConfig = {
68
+ disableAutomaticBlocking: false,
69
+ ...config,
70
+ domainConsentMap: config.overrideDomainConsentMap
71
+ ? config.domainConsentMap
72
+ : {
73
+ ...external_tracking_domains_cjs_default(),
74
+ ...config.domainConsentMap,
75
+ },
76
+ };
77
+ let consents = initialConsents || createDefaultConsentState();
78
+ const originalFetch = window.fetch;
79
+ const originalXHR = window.XMLHttpRequest;
80
+ function normalizeDomain(domain) {
81
+ return domain
82
+ .toLowerCase()
83
+ .replace(/^www\./, '')
84
+ .replace(/:\d+$/, '')
85
+ .trim();
86
+ }
87
+ function findMatchingDomain(domain, domainMap) {
88
+ const normalizedDomain = normalizeDomain(domain);
89
+ const directMatch = domainMap[normalizedDomain];
90
+ if (directMatch) return directMatch;
91
+ for (const [mapDomain, consent] of Object.entries(domainMap)) {
92
+ const normalizedMapDomain = normalizeDomain(mapDomain);
93
+ if (
94
+ normalizedDomain.endsWith(`.${normalizedMapDomain}`) ||
95
+ normalizedDomain === normalizedMapDomain
96
+ )
97
+ return consent;
98
+ }
99
+ }
100
+ function isRequestAllowed(url) {
101
+ try {
102
+ const domain = new URL(url).hostname;
103
+ const requiredConsent = findMatchingDomain(
104
+ domain,
105
+ blockerConfig.domainConsentMap || {}
106
+ );
107
+ if (!requiredConsent) return true;
108
+ const isAllowed = true === consents[requiredConsent];
109
+ return isAllowed;
110
+ } catch (error) {
111
+ return true;
112
+ }
113
+ }
114
+ function dispatchConsentBlockedEvent(url) {
115
+ document.dispatchEvent(
116
+ new CustomEvent('ConsentBlockedRequest', {
117
+ detail: {
118
+ url,
119
+ },
120
+ })
121
+ );
122
+ }
123
+ function interceptNetworkRequests() {
124
+ if (window.fetch === originalFetch)
125
+ window.fetch = async (input, init) => {
126
+ const url = input instanceof Request ? input.url : input.toString();
127
+ if (!isRequestAllowed(url)) {
128
+ dispatchConsentBlockedEvent(url);
129
+ return Promise.reject(
130
+ new Error(`Request to ${url} blocked due to missing consent`)
131
+ );
132
+ }
133
+ return await originalFetch.call(window, input, init);
134
+ };
135
+ if (window.XMLHttpRequest === originalXHR)
136
+ window.XMLHttpRequest = class extends originalXHR {
137
+ open(method, url, async = true, username, password) {
138
+ if (!isRequestAllowed(url.toString())) {
139
+ dispatchConsentBlockedEvent(url.toString());
140
+ throw new Error(`Request to ${url} blocked due to missing consent`);
141
+ }
142
+ super.open(method, url, async, username, password);
143
+ }
144
+ };
145
+ }
146
+ function restoreOriginalRequests() {
147
+ if (window.fetch !== originalFetch) window.fetch = originalFetch;
148
+ if (window.XMLHttpRequest !== originalXHR)
149
+ window.XMLHttpRequest = originalXHR;
150
+ }
151
+ if (!blockerConfig.disableAutomaticBlocking) interceptNetworkRequests();
152
+ return {
153
+ updateConsents: (newConsents) => {
154
+ consents = newConsents;
155
+ },
156
+ destroy: () => {
157
+ restoreOriginalRequests();
158
+ },
159
+ };
160
+ }
161
+ var __webpack_export_target__ = exports;
162
+ for (var __webpack_i__ in __webpack_exports__)
163
+ __webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
164
+ if (__webpack_exports__.__esModule)
165
+ Object.defineProperty(__webpack_export_target__, '__esModule', {
166
+ value: true,
167
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Implements automatic blocking of tracking scripts and network requests until user consent is granted.
4
+ *
5
+ * IMPORTANT: This module overrides global `fetch` and `XMLHttpRequest` APIs to enforce consent requirements.
6
+ * While this approach is necessary for proper consent management, it may conflict with other libraries that
7
+ * also modify these APIs. This implementation takes precedence to ensure compliance.
8
+ */
9
+ import type { AllConsentNames, ConsentState } from '../types';
10
+ /**
11
+ * Configuration options for the tracking blocker
12
+ */
13
+ export interface TrackingBlockerConfig {
14
+ /** Whether to disable automatic blocking (defaults to false) */
15
+ disableAutomaticBlocking?: boolean;
16
+ /** Override the default domain consent map */
17
+ overrideDomainConsentMap?: boolean;
18
+ /** Map of domains to their required consent types */
19
+ domainConsentMap?: Record<string, AllConsentNames>;
20
+ }
21
+ interface TrackingBlocker {
22
+ updateConsents: (newConsents: ConsentState) => void;
23
+ destroy: () => void;
24
+ }
25
+ /**
26
+ * Creates a tracking blocker instance that handles blocking of tracking scripts and network requests
27
+ */
28
+ export declare function createTrackingBlocker(
29
+ config?: TrackingBlockerConfig,
30
+ initialConsents?: ConsentState
31
+ ): TrackingBlocker;
32
+ export {};
33
+ //# sourceMappingURL=tracking-blocker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking-blocker.d.ts","sourceRoot":"","sources":["../../src/libs/tracking-blocker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,gEAAgE;IAChE,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC,8CAA8C;IAC9C,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACnD;AAeD,UAAU,eAAe;IACxB,cAAc,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;IACpD,OAAO,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,GAAE,qBAA0B,EAClC,eAAe,CAAC,EAAE,YAAY,GAC5B,eAAe,CAuJjB"}