@blotoutio/edgetag-sdk-js 0.25.0 → 0.26.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.
- package/index.cjs +230 -254
- package/index.d.ts +8 -7
- package/index.esm.js +230 -254
- package/internal.d.ts +5 -5
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -12,147 +12,6 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
12
12
|
get user () { return user; }
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
const getMessage = (error) => {
|
|
16
|
-
if (error instanceof Error) {
|
|
17
|
-
return error.message;
|
|
18
|
-
}
|
|
19
|
-
if (typeof error === 'string') {
|
|
20
|
-
return error;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
return JSON.stringify(error);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return error;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
const log = (data) => {
|
|
30
|
-
console.log('[EdgeTag]', getMessage(data));
|
|
31
|
-
};
|
|
32
|
-
const error = (data) => {
|
|
33
|
-
console.error('[EdgeTag]', getMessage(data));
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
let endpointUrl = '';
|
|
37
|
-
const generateUrl = (path) => {
|
|
38
|
-
const endpoint = getUrl();
|
|
39
|
-
if (!endpoint) {
|
|
40
|
-
log('URL is not valid');
|
|
41
|
-
return '';
|
|
42
|
-
}
|
|
43
|
-
return `${endpoint}${path}`;
|
|
44
|
-
};
|
|
45
|
-
const getUrl = () => {
|
|
46
|
-
return endpointUrl;
|
|
47
|
-
};
|
|
48
|
-
const setUrl = (url) => {
|
|
49
|
-
if (url == null) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
endpointUrl = url;
|
|
53
|
-
};
|
|
54
|
-
const getTagURL = () => {
|
|
55
|
-
return generateUrl('/tag');
|
|
56
|
-
};
|
|
57
|
-
const getInitURL = () => {
|
|
58
|
-
return generateUrl('/init');
|
|
59
|
-
};
|
|
60
|
-
const getConsentURL = () => {
|
|
61
|
-
return generateUrl('/consent');
|
|
62
|
-
};
|
|
63
|
-
const getUserURL = () => {
|
|
64
|
-
return generateUrl('/user');
|
|
65
|
-
};
|
|
66
|
-
const getDataURL = () => {
|
|
67
|
-
return generateUrl(`/data`);
|
|
68
|
-
};
|
|
69
|
-
const getGetDataURL = (keys) => {
|
|
70
|
-
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
71
|
-
};
|
|
72
|
-
const getKeysURL = () => {
|
|
73
|
-
return generateUrl(`/keys`);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
let allowedProvider = [];
|
|
77
|
-
let initialized = false;
|
|
78
|
-
let consentDisabled = false;
|
|
79
|
-
const providersPackages = {};
|
|
80
|
-
const setPreferences = (preferences) => {
|
|
81
|
-
var _a;
|
|
82
|
-
if (!preferences) {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
if (!preferences.edgeURL) {
|
|
86
|
-
error('Please provide URL for EdgeTag');
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
consentDisabled = !!preferences.disableConsentCheck;
|
|
90
|
-
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
91
|
-
if (!provider.name) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
providersPackages[provider.name] = provider;
|
|
95
|
-
});
|
|
96
|
-
try {
|
|
97
|
-
if (window && Array.isArray(window.edgetagProviders)) {
|
|
98
|
-
window.edgetagProviders.forEach((provider) => {
|
|
99
|
-
if (!provider.name) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
providersPackages[provider.name] = provider;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// do nothing
|
|
108
|
-
}
|
|
109
|
-
setUrl(preferences.edgeURL);
|
|
110
|
-
return true;
|
|
111
|
-
};
|
|
112
|
-
const isConsentDisabled = () => consentDisabled;
|
|
113
|
-
const getProvidersPackage = () => providersPackages;
|
|
114
|
-
const isInitialized = () => initialized;
|
|
115
|
-
const setInitialized = () => {
|
|
116
|
-
initialized = true;
|
|
117
|
-
};
|
|
118
|
-
const getAllowedProviders = () => allowedProvider;
|
|
119
|
-
const setAllowedProviders = (providers) => {
|
|
120
|
-
allowedProvider = providers;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const checkConsent = (providers) => {
|
|
124
|
-
if (isConsentDisabled()) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
const consent = getConsent();
|
|
128
|
-
if (!consent) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
const consentLength = Object.keys(consent).length;
|
|
132
|
-
if (!consentLength || (consentLength === 1 && consent['all'] === false)) {
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
const providersLength = Object.keys(providers || {}).length;
|
|
136
|
-
if (!providers ||
|
|
137
|
-
providersLength === 0 ||
|
|
138
|
-
(providersLength === 1 && providers['all'])) {
|
|
139
|
-
return (Object.values(consent).find((isAllowed) => isAllowed) || false);
|
|
140
|
-
}
|
|
141
|
-
for (const [key, value] of Object.entries(providers)) {
|
|
142
|
-
if (value === false || consent[key] === false) {
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
// we have consent
|
|
146
|
-
if (consent[key] ||
|
|
147
|
-
(consent['all'] === true && consent[key] === undefined)) {
|
|
148
|
-
// we have provider
|
|
149
|
-
if (value || (providers['all'] && providers[key] === undefined)) {
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return false;
|
|
155
|
-
};
|
|
156
15
|
const getUserAgent = () => {
|
|
157
16
|
try {
|
|
158
17
|
const nav = navigator;
|
|
@@ -210,81 +69,33 @@ const getPageTitle = () => {
|
|
|
210
69
|
return '';
|
|
211
70
|
}
|
|
212
71
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
const allProviders = getAllowedProviders();
|
|
225
|
-
const allProvidersLength = Object.keys(allProviders || {}).length;
|
|
226
|
-
if (allProvidersLength === 0) {
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
|
-
for (const provider of allProviders) {
|
|
230
|
-
if (isProviderIncluded(providers, providers[provider])) {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return false;
|
|
235
|
-
};
|
|
236
|
-
const allowProviders = (providers) => {
|
|
237
|
-
if (!providers || Object.keys(providers).length === 0 || providers['all']) {
|
|
238
|
-
return true;
|
|
72
|
+
|
|
73
|
+
const tagStorage = 'edgeTag';
|
|
74
|
+
const consentKey = 'consent';
|
|
75
|
+
const keyPrefix = `_worker`;
|
|
76
|
+
const cookieKey = 'tag_user_id';
|
|
77
|
+
|
|
78
|
+
const getMessage = (error) => {
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
return error.message;
|
|
239
81
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
let found = false;
|
|
243
|
-
Object.entries(providers).forEach(([key, value]) => {
|
|
244
|
-
if (!value) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
if (allowedProvider.includes(key)) {
|
|
248
|
-
found = true;
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
return found;
|
|
82
|
+
if (typeof error === 'string') {
|
|
83
|
+
return error;
|
|
252
84
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const allowProvider = (providerId) => {
|
|
256
|
-
if (!providerId) {
|
|
257
|
-
return true;
|
|
85
|
+
try {
|
|
86
|
+
return JSON.stringify(error);
|
|
258
87
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return allowedProvider.includes(providerId);
|
|
88
|
+
catch {
|
|
89
|
+
return error;
|
|
262
90
|
}
|
|
263
|
-
return true;
|
|
264
91
|
};
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
return false;
|
|
268
|
-
}
|
|
269
|
-
if (!checkConsent(providers)) {
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
if (providers && Object.keys(providers).length) {
|
|
273
|
-
if (!isProviderIncluded(providers, providers[providerId])) {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return true;
|
|
92
|
+
const log = (data) => {
|
|
93
|
+
console.log('[EdgeTag]', getMessage(data));
|
|
278
94
|
};
|
|
279
|
-
const
|
|
280
|
-
|
|
95
|
+
const error = (data) => {
|
|
96
|
+
console.error('[EdgeTag]', getMessage(data));
|
|
281
97
|
};
|
|
282
98
|
|
|
283
|
-
const tagStorage = 'edgeTag';
|
|
284
|
-
const consentKey = 'consent';
|
|
285
|
-
const keyPrefix = `_worker`;
|
|
286
|
-
const cookieKey = 'tag_user_id';
|
|
287
|
-
|
|
288
99
|
const initKey = `${keyPrefix}Store`;
|
|
289
100
|
const saveDataPerKey = (persistType, provider, value, key) => {
|
|
290
101
|
const storage = getData$1(persistType);
|
|
@@ -512,7 +323,7 @@ const getStandardPayload = (payload) => {
|
|
|
512
323
|
referrer: getReferrer(),
|
|
513
324
|
search: getSearch(),
|
|
514
325
|
locale: getLocale(),
|
|
515
|
-
sdkVersion: "0.
|
|
326
|
+
sdkVersion: "0.26.1" ,
|
|
516
327
|
...(payload || {}),
|
|
517
328
|
};
|
|
518
329
|
let storage = {};
|
|
@@ -555,6 +366,46 @@ async function getRequest(url, options) {
|
|
|
555
366
|
return await ajax('GET', url);
|
|
556
367
|
}
|
|
557
368
|
|
|
369
|
+
let endpointUrl = '';
|
|
370
|
+
const generateUrl = (path) => {
|
|
371
|
+
const endpoint = getUrl();
|
|
372
|
+
if (!endpoint) {
|
|
373
|
+
log('URL is not valid');
|
|
374
|
+
return '';
|
|
375
|
+
}
|
|
376
|
+
return `${endpoint}${path}`;
|
|
377
|
+
};
|
|
378
|
+
const getUrl = () => {
|
|
379
|
+
return endpointUrl;
|
|
380
|
+
};
|
|
381
|
+
const setUrl = (url) => {
|
|
382
|
+
if (url == null) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
endpointUrl = url;
|
|
386
|
+
};
|
|
387
|
+
const getTagURL = () => {
|
|
388
|
+
return generateUrl('/tag');
|
|
389
|
+
};
|
|
390
|
+
const getInitURL = () => {
|
|
391
|
+
return generateUrl('/init');
|
|
392
|
+
};
|
|
393
|
+
const getConsentURL = () => {
|
|
394
|
+
return generateUrl('/consent');
|
|
395
|
+
};
|
|
396
|
+
const getUserURL = () => {
|
|
397
|
+
return generateUrl('/user');
|
|
398
|
+
};
|
|
399
|
+
const getDataURL = () => {
|
|
400
|
+
return generateUrl(`/data`);
|
|
401
|
+
};
|
|
402
|
+
const getGetDataURL = (keys) => {
|
|
403
|
+
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
404
|
+
};
|
|
405
|
+
const getKeysURL = () => {
|
|
406
|
+
return generateUrl(`/keys`);
|
|
407
|
+
};
|
|
408
|
+
|
|
558
409
|
let memoryConsent;
|
|
559
410
|
const saveConsent = (consent) => {
|
|
560
411
|
setConsent(consent);
|
|
@@ -580,6 +431,53 @@ const getConsent = () => {
|
|
|
580
431
|
return memoryConsent;
|
|
581
432
|
};
|
|
582
433
|
|
|
434
|
+
const allowedProvider = new Set();
|
|
435
|
+
let initialized = false;
|
|
436
|
+
const providersPackages = {};
|
|
437
|
+
const setPreferences = (preferences) => {
|
|
438
|
+
var _a;
|
|
439
|
+
if (!preferences) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
if (!preferences.edgeURL) {
|
|
443
|
+
error('Please provide URL for EdgeTag');
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
!!preferences.disableConsentCheck;
|
|
447
|
+
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
448
|
+
if (!provider.name) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
providersPackages[provider.name] = provider;
|
|
452
|
+
});
|
|
453
|
+
try {
|
|
454
|
+
if (window && Array.isArray(window.edgetagProviders)) {
|
|
455
|
+
window.edgetagProviders.forEach((provider) => {
|
|
456
|
+
if (!provider.name) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
providersPackages[provider.name] = provider;
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
// do nothing
|
|
465
|
+
}
|
|
466
|
+
setUrl(preferences.edgeURL);
|
|
467
|
+
return true;
|
|
468
|
+
};
|
|
469
|
+
const getProvidersPackage = () => providersPackages;
|
|
470
|
+
const isInitialized = () => initialized;
|
|
471
|
+
const setInitialized = () => {
|
|
472
|
+
initialized = true;
|
|
473
|
+
};
|
|
474
|
+
const getAllowedProviders = () => allowedProvider;
|
|
475
|
+
const setAllowedProviders = (providers) => {
|
|
476
|
+
for (const provider of providers) {
|
|
477
|
+
allowedProvider.add(provider);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
583
481
|
const manifestVariables = {};
|
|
584
482
|
const addProviderVariable = (name, variables, tagName) => {
|
|
585
483
|
manifestVariables[name] = {
|
|
@@ -613,11 +511,60 @@ const processStubs = () => {
|
|
|
613
511
|
}
|
|
614
512
|
};
|
|
615
513
|
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
514
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
515
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
516
|
+
/**
|
|
517
|
+
* This function validates user consent for a given provider and tag name.
|
|
518
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
519
|
+
*/
|
|
520
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
521
|
+
if (!isRecord(consent)) {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
525
|
+
if (provider in consent) {
|
|
526
|
+
const providerSpecific = consent[provider];
|
|
527
|
+
if (isBool(providerSpecific)) {
|
|
528
|
+
allowed = providerSpecific;
|
|
529
|
+
}
|
|
530
|
+
else if (isRecord(providerSpecific)) {
|
|
531
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
532
|
+
allowed = providerSpecific.all;
|
|
533
|
+
}
|
|
534
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
535
|
+
allowed = providerSpecific[tagName];
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return allowed;
|
|
540
|
+
};
|
|
541
|
+
/**
|
|
542
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
543
|
+
* It should not be used to validate `UserConsent`.
|
|
544
|
+
*/
|
|
545
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
546
|
+
if (!isRecord(providersConfig)) {
|
|
547
|
+
return true;
|
|
620
548
|
}
|
|
549
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
550
|
+
if (provider in providersConfig) {
|
|
551
|
+
const providerSpecific = providersConfig[provider];
|
|
552
|
+
if (isBool(providerSpecific)) {
|
|
553
|
+
allowed = providerSpecific;
|
|
554
|
+
}
|
|
555
|
+
else if (isRecord(providerSpecific)) {
|
|
556
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
557
|
+
allowed = providerSpecific.all;
|
|
558
|
+
}
|
|
559
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
560
|
+
allowed = providerSpecific[tagName];
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return allowed;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
621
568
|
const payload = {
|
|
622
569
|
eventName,
|
|
623
570
|
eventId,
|
|
@@ -638,14 +585,6 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
638
585
|
});
|
|
639
586
|
return;
|
|
640
587
|
}
|
|
641
|
-
if (!allowProviders(providers)) {
|
|
642
|
-
log('Provider is not allowed.');
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (!allowTag(providers)) {
|
|
646
|
-
log('Consent is missing.');
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
588
|
let eventId = data['eventId'];
|
|
650
589
|
if (!eventId) {
|
|
651
590
|
eventId = generateEventId(eventName);
|
|
@@ -653,18 +592,31 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
653
592
|
const providerPackages = getProvidersPackage();
|
|
654
593
|
const userId = handleGetUserId();
|
|
655
594
|
const providerData = {};
|
|
595
|
+
const consent = getConsent();
|
|
596
|
+
const allowedProviders = getAllowedProviders();
|
|
597
|
+
let anyProviderCalled = false;
|
|
656
598
|
if (providerPackages) {
|
|
657
|
-
Object.values(providerPackages)
|
|
658
|
-
if (!pkg ||
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
return;
|
|
599
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
600
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
604
|
+
continue;
|
|
664
605
|
}
|
|
665
606
|
const variables = getProviderVariables(pkg.name);
|
|
666
607
|
const result = {};
|
|
667
|
-
|
|
608
|
+
const providerVariables = Object.entries(variables);
|
|
609
|
+
const executionContext = new Map();
|
|
610
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
611
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
612
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
616
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
anyProviderCalled = true;
|
|
668
620
|
result[tagName] = pkg.tag({
|
|
669
621
|
userId,
|
|
670
622
|
eventName,
|
|
@@ -672,10 +624,14 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
672
624
|
data: JSON.parse(JSON.stringify(data)),
|
|
673
625
|
sendTag,
|
|
674
626
|
manifestVariables: variableSet,
|
|
627
|
+
executionContext,
|
|
675
628
|
});
|
|
676
629
|
}
|
|
677
630
|
providerData[pkg.name] = result;
|
|
678
|
-
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (!anyProviderCalled) {
|
|
634
|
+
return;
|
|
679
635
|
}
|
|
680
636
|
sendTag({
|
|
681
637
|
eventName,
|
|
@@ -695,23 +651,33 @@ const handleData = (data, providers, options) => {
|
|
|
695
651
|
saveKV(data);
|
|
696
652
|
const providerPackages = getProvidersPackage();
|
|
697
653
|
const userId = handleGetUserId();
|
|
654
|
+
const consent = getConsent();
|
|
655
|
+
const allowedProviders = getAllowedProviders();
|
|
698
656
|
if (providerPackages) {
|
|
699
|
-
Object.values(providerPackages)
|
|
700
|
-
if (!pkg ||
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
657
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
658
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
662
|
+
continue;
|
|
705
663
|
}
|
|
706
664
|
const variables = getProviderVariables(pkg.name);
|
|
707
|
-
for (const variableSet of Object.
|
|
665
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
666
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
667
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
671
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
708
674
|
pkg.user({
|
|
709
675
|
userId,
|
|
710
676
|
data,
|
|
711
677
|
manifestVariables: variableSet,
|
|
712
678
|
});
|
|
713
679
|
}
|
|
714
|
-
}
|
|
680
|
+
}
|
|
715
681
|
}
|
|
716
682
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
717
683
|
};
|
|
@@ -828,16 +794,15 @@ const handleManifest = (manifest) => {
|
|
|
828
794
|
}
|
|
829
795
|
if (providerPackages) {
|
|
830
796
|
const pkg = providerPackages[provider.package];
|
|
831
|
-
if (pkg && pkg.name && pkg.init
|
|
832
|
-
|
|
797
|
+
if (pkg && pkg.name && pkg.init) {
|
|
798
|
+
pkg.init({
|
|
833
799
|
userId,
|
|
834
800
|
manifest: provider,
|
|
835
801
|
sendTag,
|
|
836
802
|
sendEdgeData: handleData,
|
|
837
803
|
getEdgeData: handleGetData,
|
|
838
804
|
keyName: `${keyPrefix}Store`,
|
|
839
|
-
};
|
|
840
|
-
pkg.init(initData);
|
|
805
|
+
});
|
|
841
806
|
}
|
|
842
807
|
}
|
|
843
808
|
});
|
|
@@ -888,25 +853,36 @@ const handleUser = (key, value, providers, options) => {
|
|
|
888
853
|
saveKV({
|
|
889
854
|
[key]: value,
|
|
890
855
|
});
|
|
856
|
+
const consent = getConsent();
|
|
857
|
+
const allowedProviders = getAllowedProviders();
|
|
891
858
|
const providerPackages = getProvidersPackage();
|
|
892
859
|
const userId = handleGetUserId();
|
|
893
860
|
if (providerPackages) {
|
|
894
|
-
Object.values(providerPackages)
|
|
895
|
-
if (!pkg ||
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
861
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
862
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
866
|
+
continue;
|
|
900
867
|
}
|
|
901
868
|
const variables = getProviderVariables(pkg.name);
|
|
902
|
-
for (const variableSet of Object.
|
|
869
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
870
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
871
|
+
// should we be logging this?
|
|
872
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
876
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
903
879
|
pkg.user({
|
|
904
880
|
userId,
|
|
905
881
|
data: { [key]: value },
|
|
906
882
|
manifestVariables: variableSet,
|
|
907
883
|
});
|
|
908
884
|
}
|
|
909
|
-
}
|
|
885
|
+
}
|
|
910
886
|
}
|
|
911
887
|
postRequest(getUserURL(), {
|
|
912
888
|
key,
|
|
@@ -929,14 +905,14 @@ const init = (preferences) => {
|
|
|
929
905
|
const tag = (name, data, providers, options) => {
|
|
930
906
|
handleTag(name, data, providers, options);
|
|
931
907
|
};
|
|
932
|
-
const consent = (
|
|
933
|
-
handleConsent(
|
|
908
|
+
const consent = (value, options) => {
|
|
909
|
+
handleConsent(value, options);
|
|
934
910
|
};
|
|
935
911
|
const user = (key, value, providers, options) => {
|
|
936
912
|
handleUser(key, value, providers, options);
|
|
937
913
|
};
|
|
938
|
-
const data = (
|
|
939
|
-
handleData(
|
|
914
|
+
const data = (value, providers, options) => {
|
|
915
|
+
handleData(value, providers, options);
|
|
940
916
|
};
|
|
941
917
|
const getData = (keys, callback) => {
|
|
942
918
|
handleGetData(keys, callback);
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// TODO this all located in '@blotoutio/shared/utility-sdk'
|
|
2
2
|
|
|
3
|
-
import { Library } from '@blotoutio/cdn/types'
|
|
3
|
+
import { Library, ProvidersConfig } from '@blotoutio/cdn/types'
|
|
4
4
|
|
|
5
5
|
type PersistType = 'local' | 'session' | 'edge'
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ export type SendTag = {
|
|
|
15
15
|
eventId: string
|
|
16
16
|
data: Data
|
|
17
17
|
providerData?: Partial<Record<Library, Record<string, Data>>>
|
|
18
|
-
providers?:
|
|
18
|
+
providers?: Possibly<ProvidersConfig>
|
|
19
19
|
options?: EventOptions
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -27,7 +27,7 @@ type ManifestRule = {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
type Manifest = {
|
|
30
|
-
package:
|
|
30
|
+
package: Library
|
|
31
31
|
tagName: string
|
|
32
32
|
variables?: Record<string, string>
|
|
33
33
|
rules: Record<string, ManifestRule[]>
|
|
@@ -46,10 +46,11 @@ type TagParams = {
|
|
|
46
46
|
data: Data
|
|
47
47
|
manifestVariables: Record<string, string>
|
|
48
48
|
sendTag: (params: SendTag) => void
|
|
49
|
+
executionContext: Map<string, unknown>
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
type ProviderInit = {
|
|
52
|
-
name?:
|
|
53
|
+
name?: Library
|
|
53
54
|
init?: (params: InitParams) => void
|
|
54
55
|
tag?: (params: TagParams) => unknown
|
|
55
56
|
}
|
|
@@ -84,7 +85,7 @@ export declare const init: (preferences: InitPreferences) => void
|
|
|
84
85
|
export declare const tag: (
|
|
85
86
|
name: string,
|
|
86
87
|
data?: Data,
|
|
87
|
-
providers?:
|
|
88
|
+
providers?: ProvidersConfig,
|
|
88
89
|
options?: EventOptions
|
|
89
90
|
) => void
|
|
90
91
|
|
|
@@ -93,13 +94,13 @@ export declare const consent: (consent: Data) => void
|
|
|
93
94
|
export declare const user: (
|
|
94
95
|
key: UserKey,
|
|
95
96
|
value: string,
|
|
96
|
-
providers?:
|
|
97
|
+
providers?: ProvidersConfig,
|
|
97
98
|
options?: EventOptions
|
|
98
99
|
) => void
|
|
99
100
|
|
|
100
101
|
export declare const data: (
|
|
101
102
|
data: Record<string, string>,
|
|
102
|
-
providers?:
|
|
103
|
+
providers?: ProvidersConfig,
|
|
103
104
|
options?: EventOptions
|
|
104
105
|
) => void
|
|
105
106
|
|
package/index.esm.js
CHANGED
|
@@ -10,147 +10,6 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
10
10
|
get user () { return user; }
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
const getMessage = (error) => {
|
|
14
|
-
if (error instanceof Error) {
|
|
15
|
-
return error.message;
|
|
16
|
-
}
|
|
17
|
-
if (typeof error === 'string') {
|
|
18
|
-
return error;
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
return JSON.stringify(error);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return error;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
const log = (data) => {
|
|
28
|
-
console.log('[EdgeTag]', getMessage(data));
|
|
29
|
-
};
|
|
30
|
-
const error = (data) => {
|
|
31
|
-
console.error('[EdgeTag]', getMessage(data));
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
let endpointUrl = '';
|
|
35
|
-
const generateUrl = (path) => {
|
|
36
|
-
const endpoint = getUrl();
|
|
37
|
-
if (!endpoint) {
|
|
38
|
-
log('URL is not valid');
|
|
39
|
-
return '';
|
|
40
|
-
}
|
|
41
|
-
return `${endpoint}${path}`;
|
|
42
|
-
};
|
|
43
|
-
const getUrl = () => {
|
|
44
|
-
return endpointUrl;
|
|
45
|
-
};
|
|
46
|
-
const setUrl = (url) => {
|
|
47
|
-
if (url == null) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
endpointUrl = url;
|
|
51
|
-
};
|
|
52
|
-
const getTagURL = () => {
|
|
53
|
-
return generateUrl('/tag');
|
|
54
|
-
};
|
|
55
|
-
const getInitURL = () => {
|
|
56
|
-
return generateUrl('/init');
|
|
57
|
-
};
|
|
58
|
-
const getConsentURL = () => {
|
|
59
|
-
return generateUrl('/consent');
|
|
60
|
-
};
|
|
61
|
-
const getUserURL = () => {
|
|
62
|
-
return generateUrl('/user');
|
|
63
|
-
};
|
|
64
|
-
const getDataURL = () => {
|
|
65
|
-
return generateUrl(`/data`);
|
|
66
|
-
};
|
|
67
|
-
const getGetDataURL = (keys) => {
|
|
68
|
-
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
69
|
-
};
|
|
70
|
-
const getKeysURL = () => {
|
|
71
|
-
return generateUrl(`/keys`);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
let allowedProvider = [];
|
|
75
|
-
let initialized = false;
|
|
76
|
-
let consentDisabled = false;
|
|
77
|
-
const providersPackages = {};
|
|
78
|
-
const setPreferences = (preferences) => {
|
|
79
|
-
var _a;
|
|
80
|
-
if (!preferences) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
if (!preferences.edgeURL) {
|
|
84
|
-
error('Please provide URL for EdgeTag');
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
consentDisabled = !!preferences.disableConsentCheck;
|
|
88
|
-
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
89
|
-
if (!provider.name) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
providersPackages[provider.name] = provider;
|
|
93
|
-
});
|
|
94
|
-
try {
|
|
95
|
-
if (window && Array.isArray(window.edgetagProviders)) {
|
|
96
|
-
window.edgetagProviders.forEach((provider) => {
|
|
97
|
-
if (!provider.name) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
providersPackages[provider.name] = provider;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
// do nothing
|
|
106
|
-
}
|
|
107
|
-
setUrl(preferences.edgeURL);
|
|
108
|
-
return true;
|
|
109
|
-
};
|
|
110
|
-
const isConsentDisabled = () => consentDisabled;
|
|
111
|
-
const getProvidersPackage = () => providersPackages;
|
|
112
|
-
const isInitialized = () => initialized;
|
|
113
|
-
const setInitialized = () => {
|
|
114
|
-
initialized = true;
|
|
115
|
-
};
|
|
116
|
-
const getAllowedProviders = () => allowedProvider;
|
|
117
|
-
const setAllowedProviders = (providers) => {
|
|
118
|
-
allowedProvider = providers;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const checkConsent = (providers) => {
|
|
122
|
-
if (isConsentDisabled()) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
const consent = getConsent();
|
|
126
|
-
if (!consent) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
const consentLength = Object.keys(consent).length;
|
|
130
|
-
if (!consentLength || (consentLength === 1 && consent['all'] === false)) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const providersLength = Object.keys(providers || {}).length;
|
|
134
|
-
if (!providers ||
|
|
135
|
-
providersLength === 0 ||
|
|
136
|
-
(providersLength === 1 && providers['all'])) {
|
|
137
|
-
return (Object.values(consent).find((isAllowed) => isAllowed) || false);
|
|
138
|
-
}
|
|
139
|
-
for (const [key, value] of Object.entries(providers)) {
|
|
140
|
-
if (value === false || consent[key] === false) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
// we have consent
|
|
144
|
-
if (consent[key] ||
|
|
145
|
-
(consent['all'] === true && consent[key] === undefined)) {
|
|
146
|
-
// we have provider
|
|
147
|
-
if (value || (providers['all'] && providers[key] === undefined)) {
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return false;
|
|
153
|
-
};
|
|
154
13
|
const getUserAgent = () => {
|
|
155
14
|
try {
|
|
156
15
|
const nav = navigator;
|
|
@@ -208,81 +67,33 @@ const getPageTitle = () => {
|
|
|
208
67
|
return '';
|
|
209
68
|
}
|
|
210
69
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
const allProviders = getAllowedProviders();
|
|
223
|
-
const allProvidersLength = Object.keys(allProviders || {}).length;
|
|
224
|
-
if (allProvidersLength === 0) {
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
227
|
-
for (const provider of allProviders) {
|
|
228
|
-
if (isProviderIncluded(providers, providers[provider])) {
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return false;
|
|
233
|
-
};
|
|
234
|
-
const allowProviders = (providers) => {
|
|
235
|
-
if (!providers || Object.keys(providers).length === 0 || providers['all']) {
|
|
236
|
-
return true;
|
|
70
|
+
|
|
71
|
+
const tagStorage = 'edgeTag';
|
|
72
|
+
const consentKey = 'consent';
|
|
73
|
+
const keyPrefix = `_worker`;
|
|
74
|
+
const cookieKey = 'tag_user_id';
|
|
75
|
+
|
|
76
|
+
const getMessage = (error) => {
|
|
77
|
+
if (error instanceof Error) {
|
|
78
|
+
return error.message;
|
|
237
79
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
let found = false;
|
|
241
|
-
Object.entries(providers).forEach(([key, value]) => {
|
|
242
|
-
if (!value) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
if (allowedProvider.includes(key)) {
|
|
246
|
-
found = true;
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
return found;
|
|
80
|
+
if (typeof error === 'string') {
|
|
81
|
+
return error;
|
|
250
82
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const allowProvider = (providerId) => {
|
|
254
|
-
if (!providerId) {
|
|
255
|
-
return true;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.stringify(error);
|
|
256
85
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return allowedProvider.includes(providerId);
|
|
86
|
+
catch {
|
|
87
|
+
return error;
|
|
260
88
|
}
|
|
261
|
-
return true;
|
|
262
89
|
};
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
if (!checkConsent(providers)) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
if (providers && Object.keys(providers).length) {
|
|
271
|
-
if (!isProviderIncluded(providers, providers[providerId])) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return true;
|
|
90
|
+
const log = (data) => {
|
|
91
|
+
console.log('[EdgeTag]', getMessage(data));
|
|
276
92
|
};
|
|
277
|
-
const
|
|
278
|
-
|
|
93
|
+
const error = (data) => {
|
|
94
|
+
console.error('[EdgeTag]', getMessage(data));
|
|
279
95
|
};
|
|
280
96
|
|
|
281
|
-
const tagStorage = 'edgeTag';
|
|
282
|
-
const consentKey = 'consent';
|
|
283
|
-
const keyPrefix = `_worker`;
|
|
284
|
-
const cookieKey = 'tag_user_id';
|
|
285
|
-
|
|
286
97
|
const initKey = `${keyPrefix}Store`;
|
|
287
98
|
const saveDataPerKey = (persistType, provider, value, key) => {
|
|
288
99
|
const storage = getData$1(persistType);
|
|
@@ -510,7 +321,7 @@ const getStandardPayload = (payload) => {
|
|
|
510
321
|
referrer: getReferrer(),
|
|
511
322
|
search: getSearch(),
|
|
512
323
|
locale: getLocale(),
|
|
513
|
-
sdkVersion: "0.
|
|
324
|
+
sdkVersion: "0.26.1" ,
|
|
514
325
|
...(payload || {}),
|
|
515
326
|
};
|
|
516
327
|
let storage = {};
|
|
@@ -553,6 +364,46 @@ async function getRequest(url, options) {
|
|
|
553
364
|
return await ajax('GET', url);
|
|
554
365
|
}
|
|
555
366
|
|
|
367
|
+
let endpointUrl = '';
|
|
368
|
+
const generateUrl = (path) => {
|
|
369
|
+
const endpoint = getUrl();
|
|
370
|
+
if (!endpoint) {
|
|
371
|
+
log('URL is not valid');
|
|
372
|
+
return '';
|
|
373
|
+
}
|
|
374
|
+
return `${endpoint}${path}`;
|
|
375
|
+
};
|
|
376
|
+
const getUrl = () => {
|
|
377
|
+
return endpointUrl;
|
|
378
|
+
};
|
|
379
|
+
const setUrl = (url) => {
|
|
380
|
+
if (url == null) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
endpointUrl = url;
|
|
384
|
+
};
|
|
385
|
+
const getTagURL = () => {
|
|
386
|
+
return generateUrl('/tag');
|
|
387
|
+
};
|
|
388
|
+
const getInitURL = () => {
|
|
389
|
+
return generateUrl('/init');
|
|
390
|
+
};
|
|
391
|
+
const getConsentURL = () => {
|
|
392
|
+
return generateUrl('/consent');
|
|
393
|
+
};
|
|
394
|
+
const getUserURL = () => {
|
|
395
|
+
return generateUrl('/user');
|
|
396
|
+
};
|
|
397
|
+
const getDataURL = () => {
|
|
398
|
+
return generateUrl(`/data`);
|
|
399
|
+
};
|
|
400
|
+
const getGetDataURL = (keys) => {
|
|
401
|
+
return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
|
|
402
|
+
};
|
|
403
|
+
const getKeysURL = () => {
|
|
404
|
+
return generateUrl(`/keys`);
|
|
405
|
+
};
|
|
406
|
+
|
|
556
407
|
let memoryConsent;
|
|
557
408
|
const saveConsent = (consent) => {
|
|
558
409
|
setConsent(consent);
|
|
@@ -578,6 +429,53 @@ const getConsent = () => {
|
|
|
578
429
|
return memoryConsent;
|
|
579
430
|
};
|
|
580
431
|
|
|
432
|
+
const allowedProvider = new Set();
|
|
433
|
+
let initialized = false;
|
|
434
|
+
const providersPackages = {};
|
|
435
|
+
const setPreferences = (preferences) => {
|
|
436
|
+
var _a;
|
|
437
|
+
if (!preferences) {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
if (!preferences.edgeURL) {
|
|
441
|
+
error('Please provide URL for EdgeTag');
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
!!preferences.disableConsentCheck;
|
|
445
|
+
(_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
|
|
446
|
+
if (!provider.name) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
providersPackages[provider.name] = provider;
|
|
450
|
+
});
|
|
451
|
+
try {
|
|
452
|
+
if (window && Array.isArray(window.edgetagProviders)) {
|
|
453
|
+
window.edgetagProviders.forEach((provider) => {
|
|
454
|
+
if (!provider.name) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
providersPackages[provider.name] = provider;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// do nothing
|
|
463
|
+
}
|
|
464
|
+
setUrl(preferences.edgeURL);
|
|
465
|
+
return true;
|
|
466
|
+
};
|
|
467
|
+
const getProvidersPackage = () => providersPackages;
|
|
468
|
+
const isInitialized = () => initialized;
|
|
469
|
+
const setInitialized = () => {
|
|
470
|
+
initialized = true;
|
|
471
|
+
};
|
|
472
|
+
const getAllowedProviders = () => allowedProvider;
|
|
473
|
+
const setAllowedProviders = (providers) => {
|
|
474
|
+
for (const provider of providers) {
|
|
475
|
+
allowedProvider.add(provider);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
581
479
|
const manifestVariables = {};
|
|
582
480
|
const addProviderVariable = (name, variables, tagName) => {
|
|
583
481
|
manifestVariables[name] = {
|
|
@@ -611,11 +509,60 @@ const processStubs = () => {
|
|
|
611
509
|
}
|
|
612
510
|
};
|
|
613
511
|
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
512
|
+
const isBool = (v) => typeof v == 'boolean';
|
|
513
|
+
const isRecord = (v) => !!v && typeof v == 'object';
|
|
514
|
+
/**
|
|
515
|
+
* This function validates user consent for a given provider and tag name.
|
|
516
|
+
* It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
|
|
517
|
+
*/
|
|
518
|
+
const hasUserConsent = (consent, provider, tagName) => {
|
|
519
|
+
if (!isRecord(consent)) {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
let allowed = isBool(consent.all) ? consent.all : false;
|
|
523
|
+
if (provider in consent) {
|
|
524
|
+
const providerSpecific = consent[provider];
|
|
525
|
+
if (isBool(providerSpecific)) {
|
|
526
|
+
allowed = providerSpecific;
|
|
527
|
+
}
|
|
528
|
+
else if (isRecord(providerSpecific)) {
|
|
529
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
530
|
+
allowed = providerSpecific.all;
|
|
531
|
+
}
|
|
532
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
533
|
+
allowed = providerSpecific[tagName];
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return allowed;
|
|
538
|
+
};
|
|
539
|
+
/**
|
|
540
|
+
* This function validates provider allowance for a given provider and tag name.
|
|
541
|
+
* It should not be used to validate `UserConsent`.
|
|
542
|
+
*/
|
|
543
|
+
const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
|
|
544
|
+
if (!isRecord(providersConfig)) {
|
|
545
|
+
return true;
|
|
618
546
|
}
|
|
547
|
+
let allowed = isBool(providersConfig.all) ? providersConfig.all : true;
|
|
548
|
+
if (provider in providersConfig) {
|
|
549
|
+
const providerSpecific = providersConfig[provider];
|
|
550
|
+
if (isBool(providerSpecific)) {
|
|
551
|
+
allowed = providerSpecific;
|
|
552
|
+
}
|
|
553
|
+
else if (isRecord(providerSpecific)) {
|
|
554
|
+
if ('all' in providerSpecific && isBool(providerSpecific.all)) {
|
|
555
|
+
allowed = providerSpecific.all;
|
|
556
|
+
}
|
|
557
|
+
if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
|
|
558
|
+
allowed = providerSpecific[tagName];
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return allowed;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
|
|
619
566
|
const payload = {
|
|
620
567
|
eventName,
|
|
621
568
|
eventId,
|
|
@@ -636,14 +583,6 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
636
583
|
});
|
|
637
584
|
return;
|
|
638
585
|
}
|
|
639
|
-
if (!allowProviders(providers)) {
|
|
640
|
-
log('Provider is not allowed.');
|
|
641
|
-
return;
|
|
642
|
-
}
|
|
643
|
-
if (!allowTag(providers)) {
|
|
644
|
-
log('Consent is missing.');
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
586
|
let eventId = data['eventId'];
|
|
648
587
|
if (!eventId) {
|
|
649
588
|
eventId = generateEventId(eventName);
|
|
@@ -651,18 +590,31 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
651
590
|
const providerPackages = getProvidersPackage();
|
|
652
591
|
const userId = handleGetUserId();
|
|
653
592
|
const providerData = {};
|
|
593
|
+
const consent = getConsent();
|
|
594
|
+
const allowedProviders = getAllowedProviders();
|
|
595
|
+
let anyProviderCalled = false;
|
|
654
596
|
if (providerPackages) {
|
|
655
|
-
Object.values(providerPackages)
|
|
656
|
-
if (!pkg ||
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
return;
|
|
597
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
598
|
+
if (!pkg || !pkg.name || !pkg.tag) {
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
602
|
+
continue;
|
|
662
603
|
}
|
|
663
604
|
const variables = getProviderVariables(pkg.name);
|
|
664
605
|
const result = {};
|
|
665
|
-
|
|
606
|
+
const providerVariables = Object.entries(variables);
|
|
607
|
+
const executionContext = new Map();
|
|
608
|
+
for (const [tagName, variableSet] of providerVariables) {
|
|
609
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
610
|
+
log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
614
|
+
log(`Consent is missing (${pkg.name}: ${tagName})`);
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
anyProviderCalled = true;
|
|
666
618
|
result[tagName] = pkg.tag({
|
|
667
619
|
userId,
|
|
668
620
|
eventName,
|
|
@@ -670,10 +622,14 @@ const handleTag = (eventName, data = {}, providers, options) => {
|
|
|
670
622
|
data: JSON.parse(JSON.stringify(data)),
|
|
671
623
|
sendTag,
|
|
672
624
|
manifestVariables: variableSet,
|
|
625
|
+
executionContext,
|
|
673
626
|
});
|
|
674
627
|
}
|
|
675
628
|
providerData[pkg.name] = result;
|
|
676
|
-
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (!anyProviderCalled) {
|
|
632
|
+
return;
|
|
677
633
|
}
|
|
678
634
|
sendTag({
|
|
679
635
|
eventName,
|
|
@@ -693,23 +649,33 @@ const handleData = (data, providers, options) => {
|
|
|
693
649
|
saveKV(data);
|
|
694
650
|
const providerPackages = getProvidersPackage();
|
|
695
651
|
const userId = handleGetUserId();
|
|
652
|
+
const consent = getConsent();
|
|
653
|
+
const allowedProviders = getAllowedProviders();
|
|
696
654
|
if (providerPackages) {
|
|
697
|
-
Object.values(providerPackages)
|
|
698
|
-
if (!pkg ||
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
655
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
656
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
660
|
+
continue;
|
|
703
661
|
}
|
|
704
662
|
const variables = getProviderVariables(pkg.name);
|
|
705
|
-
for (const variableSet of Object.
|
|
663
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
664
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
665
|
+
log(`Data not allowed for ${pkg.name} (${tagName})`);
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
669
|
+
log(`Consent is missing for ${pkg.name} (${tagName})`);
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
706
672
|
pkg.user({
|
|
707
673
|
userId,
|
|
708
674
|
data,
|
|
709
675
|
manifestVariables: variableSet,
|
|
710
676
|
});
|
|
711
677
|
}
|
|
712
|
-
}
|
|
678
|
+
}
|
|
713
679
|
}
|
|
714
680
|
postRequest(getDataURL(), { data, providers }, options).catch(error);
|
|
715
681
|
};
|
|
@@ -826,16 +792,15 @@ const handleManifest = (manifest) => {
|
|
|
826
792
|
}
|
|
827
793
|
if (providerPackages) {
|
|
828
794
|
const pkg = providerPackages[provider.package];
|
|
829
|
-
if (pkg && pkg.name && pkg.init
|
|
830
|
-
|
|
795
|
+
if (pkg && pkg.name && pkg.init) {
|
|
796
|
+
pkg.init({
|
|
831
797
|
userId,
|
|
832
798
|
manifest: provider,
|
|
833
799
|
sendTag,
|
|
834
800
|
sendEdgeData: handleData,
|
|
835
801
|
getEdgeData: handleGetData,
|
|
836
802
|
keyName: `${keyPrefix}Store`,
|
|
837
|
-
};
|
|
838
|
-
pkg.init(initData);
|
|
803
|
+
});
|
|
839
804
|
}
|
|
840
805
|
}
|
|
841
806
|
});
|
|
@@ -886,25 +851,36 @@ const handleUser = (key, value, providers, options) => {
|
|
|
886
851
|
saveKV({
|
|
887
852
|
[key]: value,
|
|
888
853
|
});
|
|
854
|
+
const consent = getConsent();
|
|
855
|
+
const allowedProviders = getAllowedProviders();
|
|
889
856
|
const providerPackages = getProvidersPackage();
|
|
890
857
|
const userId = handleGetUserId();
|
|
891
858
|
if (providerPackages) {
|
|
892
|
-
Object.values(providerPackages)
|
|
893
|
-
if (!pkg ||
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
859
|
+
for (const pkg of Object.values(providerPackages)) {
|
|
860
|
+
if (!pkg || !pkg.name || !pkg.user) {
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
if (!allowedProviders.has(pkg.name)) {
|
|
864
|
+
continue;
|
|
898
865
|
}
|
|
899
866
|
const variables = getProviderVariables(pkg.name);
|
|
900
|
-
for (const variableSet of Object.
|
|
867
|
+
for (const [tagName, variableSet] of Object.entries(variables)) {
|
|
868
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
|
|
869
|
+
// should we be logging this?
|
|
870
|
+
log(`User not allowed for ${pkg.name} (${tagName})`);
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
if (!hasUserConsent(consent, pkg.name, tagName)) {
|
|
874
|
+
log(`User doesn't have consent for ${pkg.name} (${tagName})`);
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
901
877
|
pkg.user({
|
|
902
878
|
userId,
|
|
903
879
|
data: { [key]: value },
|
|
904
880
|
manifestVariables: variableSet,
|
|
905
881
|
});
|
|
906
882
|
}
|
|
907
|
-
}
|
|
883
|
+
}
|
|
908
884
|
}
|
|
909
885
|
postRequest(getUserURL(), {
|
|
910
886
|
key,
|
|
@@ -927,14 +903,14 @@ const init = (preferences) => {
|
|
|
927
903
|
const tag = (name, data, providers, options) => {
|
|
928
904
|
handleTag(name, data, providers, options);
|
|
929
905
|
};
|
|
930
|
-
const consent = (
|
|
931
|
-
handleConsent(
|
|
906
|
+
const consent = (value, options) => {
|
|
907
|
+
handleConsent(value, options);
|
|
932
908
|
};
|
|
933
909
|
const user = (key, value, providers, options) => {
|
|
934
910
|
handleUser(key, value, providers, options);
|
|
935
911
|
};
|
|
936
|
-
const data = (
|
|
937
|
-
handleData(
|
|
912
|
+
const data = (value, providers, options) => {
|
|
913
|
+
handleData(value, providers, options);
|
|
938
914
|
};
|
|
939
915
|
const getData = (keys, callback) => {
|
|
940
916
|
handleGetData(keys, callback);
|
package/internal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Library } from '@blotoutio/cdn/types'
|
|
1
|
+
import { Library, ProvidersConfig, UserConsent } from '@blotoutio/cdn/types'
|
|
2
2
|
import { UserKey, Data } from './index'
|
|
3
3
|
|
|
4
4
|
type Navigator = {
|
|
@@ -11,22 +11,22 @@ type TagPayload = {
|
|
|
11
11
|
timestamp: number
|
|
12
12
|
providerData?: Partial<Record<Library, Record<string, Data>>>
|
|
13
13
|
data?: Data
|
|
14
|
-
providers?:
|
|
14
|
+
providers?: ProvidersConfig | null | undefined
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
type ConsentPayload = {
|
|
18
|
-
consentString:
|
|
18
|
+
consentString: UserConsent
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
type UserPayload = {
|
|
22
22
|
key: UserKey
|
|
23
23
|
value: string
|
|
24
|
-
providers?:
|
|
24
|
+
providers?: ProvidersConfig | null | undefined
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
type DataPayload = {
|
|
28
28
|
data: Record<string, string>
|
|
29
|
-
providers?:
|
|
29
|
+
providers?: ProvidersConfig | null | undefined
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
type PostPayload = {
|