@blotoutio/edgetag-sdk-js 0.51.1 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.cjs.js +601 -469
  2. package/index.d.ts +29 -6
  3. package/index.mjs +601 -469
  4. package/package.json +1 -1
package/index.cjs.js CHANGED
@@ -15,11 +15,174 @@ var api = /*#__PURE__*/Object.freeze({
15
15
  get user () { return user; }
16
16
  });
17
17
 
18
- const _config = {};
19
- const setConfig$1 = (config) => {
20
- Object.assign(_config, config);
18
+ const isBool = (v) => typeof v == 'boolean';
19
+ const isRecord = (v) => !!v && typeof v == 'object' && !Array.isArray(v);
20
+ /**
21
+ * This function validates user consent for a given provider and tag name.
22
+ * It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
23
+ */
24
+ const hasUserConsent = (consent, provider, tagName) => {
25
+ if (!isRecord(consent)) {
26
+ return false;
27
+ }
28
+ let allowed = isBool(consent.all) ? consent.all : false;
29
+ if (provider in consent) {
30
+ const providerSpecific = consent[provider];
31
+ if (isBool(providerSpecific)) {
32
+ allowed = providerSpecific;
33
+ }
34
+ else if (isRecord(providerSpecific)) {
35
+ if ('all' in providerSpecific && isBool(providerSpecific.all)) {
36
+ allowed = providerSpecific.all;
37
+ }
38
+ if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
39
+ allowed = providerSpecific[tagName];
40
+ }
41
+ }
42
+ }
43
+ return allowed;
44
+ };
45
+ /**
46
+ * This function validates user consent for a given provider type, not based on tagName.
47
+ */
48
+ const hasUserConsentForProvider = (consent, provider) => {
49
+ if (!isRecord(consent)) {
50
+ return false;
51
+ }
52
+ let allowed = isBool(consent.all) ? consent.all : false;
53
+ if (provider in consent) {
54
+ const providerSpecific = consent[provider];
55
+ if (isBool(providerSpecific)) {
56
+ allowed = providerSpecific;
57
+ }
58
+ else if (isRecord(providerSpecific)) {
59
+ return Object.keys(providerSpecific).some((instance) => providerSpecific[instance] === true);
60
+ }
61
+ }
62
+ return allowed;
63
+ };
64
+ /**
65
+ * This function validates provider allowance for a given provider and tag name.
66
+ * It should not be used to validate `UserConsent`.
67
+ */
68
+ const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
69
+ if (!isRecord(providersConfig)) {
70
+ return true;
71
+ }
72
+ if (provider in providersConfig) {
73
+ const providerSpecific = providersConfig[provider];
74
+ if (isBool(providerSpecific)) {
75
+ return providerSpecific;
76
+ }
77
+ if (isRecord(providerSpecific)) {
78
+ const tagKeys = Object.keys(providerSpecific).filter((k) => k != 'all');
79
+ if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
80
+ return providerSpecific[tagName];
81
+ }
82
+ return isBool(providerSpecific.all)
83
+ ? providerSpecific.all
84
+ : tagKeys.length == 0;
85
+ }
86
+ }
87
+ const providerKeys = Object.keys(providersConfig).filter((k) => k != 'all');
88
+ return isBool(providersConfig.all)
89
+ ? providersConfig.all
90
+ : providerKeys.length == 0;
91
+ };
92
+
93
+ const upsert = (map, key, update, createDefault) => {
94
+ const currentValue = map.has(key)
95
+ ? map.get(key)
96
+ : createDefault();
97
+ return map.set(key, update(currentValue));
98
+ };
99
+
100
+ const expand = (str) => str.split(',').flatMap((entry) => {
101
+ if (!entry.includes('-')) {
102
+ return entry;
103
+ }
104
+ const result = [];
105
+ const [start, end] = entry.split('-').map(Number);
106
+ for (let i = start; i <= end; i++) {
107
+ result.push(i.toString());
108
+ }
109
+ return result;
110
+ });
111
+ /**
112
+ * Exported from https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes
113
+ *
114
+ * In Dev Tools, select the `tbody` element containing the area codes and run the following code,
115
+ * replacing the emdash character with a simple endash:
116
+ *
117
+ * ```ts
118
+ * [...$0.querySelectorAll('td:first-child')]
119
+ * .filter(cell => cell.firstChild.nodeName != 'A')
120
+ * .map(cell => cell.textContent.trim()).join(',')
121
+ * ```
122
+ */
123
+ new Set([
124
+ ...expand('200,211,221,222,230,232,233,235,237-238,241,243,244,245,247,255,257,258-259,261,265,266,271,273,274,275,277,278,280,282,283,285-287,288,290-299'),
125
+ ...expand('300,311,322,324,327,328,333,335,338,342,344,348-349,353,355,356,357-359,362,366,369,370-379,381,382,383-384,387,388,389,390-399'),
126
+ ...expand('400,411,420,421-422,426-427,428,429,433,439,444,446,449,451-454,455,456,457,459,460,461-462,465,466,467,471,476,477,481-483,485-486,487,488,489,490-499'),
127
+ ...expand('511,532,535,536,537,538,542-543,545-547,549-550,552-554,555,556,558,560,565,568,569,576,578,583,589,590-599'),
128
+ ...expand('611,621,624,625,627,632,633,634-635,637-638,642-643,644,648,652-654,655,663,665,666,668,673-676,677,679,685,686,687,688,690-699'),
129
+ ...expand('711,722,723,729,733,735-736,739,741,744,745-746,748,749-751,752,755,756,759,761,764,766,768,776,777,783,788,789,790-799'),
130
+ ...expand('811,821,822,823-824,827,834,836,841-842,846,851,852-853,871,874-875,879,880-887,889,890-899'),
131
+ ...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
132
+ ]);
133
+
134
+ // eslint-disable-next-line @nx/enforce-module-boundaries
135
+ let edgeTagSettings;
136
+ const initSettings = (destination, options) => {
137
+ if (!edgeTagSettings) {
138
+ edgeTagSettings = {};
139
+ }
140
+ edgeTagSettings[destination] = {
141
+ destination,
142
+ initialized: false,
143
+ stubs: [],
144
+ channels: new Map(),
145
+ ...options,
146
+ };
147
+ };
148
+ const setSetting = (options, destination) => {
149
+ if (!edgeTagSettings) {
150
+ return;
151
+ }
152
+ if (!destination) {
153
+ Object.keys(edgeTagSettings).forEach((key) => {
154
+ edgeTagSettings[key] = {
155
+ ...edgeTagSettings[key],
156
+ ...options,
157
+ };
158
+ });
159
+ return;
160
+ }
161
+ edgeTagSettings[destination] = {
162
+ ...edgeTagSettings[destination],
163
+ ...options,
164
+ };
165
+ };
166
+ const getSetting = (destination, key) => {
167
+ var _a;
168
+ return (_a = edgeTagSettings === null || edgeTagSettings === void 0 ? void 0 : edgeTagSettings[destination]) === null || _a === void 0 ? void 0 : _a[key];
169
+ };
170
+ const getInstances = () => {
171
+ return Object.keys(edgeTagSettings || {});
172
+ };
173
+ const addChannel = (destination, pkg, tagName) => upsert(getSetting(destination, 'channels'), pkg, (names) => names.add(tagName), () => new Set());
174
+ const getProviderVariables = (destination, packageId) => {
175
+ const setting = getSetting(destination, 'packages');
176
+ if (!setting) {
177
+ return [];
178
+ }
179
+ return (setting
180
+ .filter((pkg) => pkg.package === packageId)
181
+ .map((pkg) => ({
182
+ tagName: pkg.tagName,
183
+ variableSet: pkg.variables || {},
184
+ })) || []);
21
185
  };
22
- const getConfig = () => _config;
23
186
 
24
187
  const getUserAgent = () => {
25
188
  try {
@@ -30,11 +193,11 @@ const getUserAgent = () => {
30
193
  return '';
31
194
  }
32
195
  };
33
- const getReferrer = () => {
196
+ const getReferrer = (destination) => {
34
197
  let referrer = '';
35
198
  try {
36
199
  const referrerUrl = new URL(document.referrer);
37
- const pageUrl = new URL(getPageUrl());
200
+ const pageUrl = new URL(getPageUrl(destination));
38
201
  if (referrerUrl.host !== pageUrl.host) {
39
202
  referrer = referrerUrl.href;
40
203
  }
@@ -44,22 +207,22 @@ const getReferrer = () => {
44
207
  return referrer;
45
208
  }
46
209
  };
47
- const getPageUrl = () => {
210
+ const getPageUrl = (destination) => {
48
211
  try {
49
212
  // we need to leave this one in for existing Custom pixel customers
50
213
  if (window.edgetagData && window.edgetagData['pageUrl']) {
51
214
  return window.edgetagData['pageUrl'];
52
215
  }
53
- const { pageUrl } = getConfig();
54
- return pageUrl || window.location.href;
216
+ const config = getSetting(destination, 'config');
217
+ return (config === null || config === void 0 ? void 0 : config.pageUrl) || window.location.href;
55
218
  }
56
219
  catch {
57
220
  return '';
58
221
  }
59
222
  };
60
- const getSearch = () => {
223
+ const getSearch = (destination) => {
61
224
  try {
62
- return new URL(getPageUrl()).search;
225
+ return new URL(getPageUrl(destination)).search;
63
226
  }
64
227
  catch {
65
228
  return '';
@@ -112,7 +275,6 @@ const areEqual = (a, b) => {
112
275
  const tagStorage = 'edgeTag';
113
276
  const consentKey = 'consent';
114
277
  const keyPrefix = `_worker`;
115
- const cookieKey = 'tag_user_id';
116
278
 
117
279
  const getMessage = (error) => {
118
280
  if (error instanceof Error) {
@@ -146,9 +308,9 @@ const error = (data) => {
146
308
  console.error('[EdgeTag]', getMessage(data));
147
309
  };
148
310
 
149
- const initKey = `${keyPrefix}Store`;
150
- const saveDataPerKey = (persistType, provider, value, key) => {
151
- const storage = getData$1(persistType);
311
+ const initKey = `${keyPrefix}StoreMultiple`;
312
+ const saveDataPerKey = (destination, persistType, provider, value, key) => {
313
+ const storage = getData$1(destination, persistType);
152
314
  if (!storage['data']) {
153
315
  storage['data'] = {};
154
316
  }
@@ -156,49 +318,54 @@ const saveDataPerKey = (persistType, provider, value, key) => {
156
318
  storage['data'][provider] = {};
157
319
  }
158
320
  storage['data'][provider][key] = value;
159
- saveData(persistType, storage);
321
+ saveData(destination, persistType, storage);
322
+ };
323
+ const saveKV = (destination, data) => {
324
+ const currentSession = getData$1(destination, 'session');
325
+ if (!currentSession['kv']) {
326
+ currentSession['kv'] = {};
327
+ }
328
+ currentSession['kv'] = {
329
+ ...currentSession['kv'],
330
+ ...data,
331
+ };
332
+ saveData(destination, 'session', currentSession);
160
333
  };
161
- const savePerKey = (persistType, provider, value, key) => {
162
- const storage = getData$1(persistType);
334
+ const savePerKey = (destination, persistType, provider, value, key) => {
335
+ const storage = getData$1(destination, persistType);
163
336
  if (!storage[provider]) {
164
337
  storage[provider] = {};
165
338
  }
166
339
  storage[provider][key] = value;
167
- saveData(persistType, storage);
340
+ saveData(destination, persistType, storage);
168
341
  };
169
- const getDataPerKey = (persistType, provider, key) => {
170
- const storage = getData$1(persistType);
342
+ const getDataPerKey = (destination, persistType, provider, key) => {
343
+ const storage = getData$1(destination, persistType);
171
344
  if (!storage[provider]) {
172
345
  return undefined;
173
346
  }
174
347
  return storage[provider][key];
175
348
  };
176
- const saveData = (persistType, value, key = initKey) => {
349
+ const saveData = (destination, persistType, value, key = initKey) => {
177
350
  if (persistType === 'session') {
178
- saveSession(value, key);
351
+ const data = getSession(key);
352
+ data[destination] = value;
353
+ saveSession(data, key);
179
354
  return;
180
355
  }
181
- saveLocal(value, key);
356
+ const data = getLocal(key);
357
+ data[destination] = value;
358
+ saveLocal(data, key);
182
359
  };
183
- const getData$1 = (persistType, key = initKey) => {
360
+ const getData$1 = (destination, persistType, key = initKey) => {
361
+ let data;
184
362
  if (persistType === 'session') {
185
- return getSession(key);
363
+ data = getSession(key);
186
364
  }
187
- return getLocal(key);
188
- };
189
- const saveKV = (data) => {
190
- let currentSession = getData$1('session');
191
- if (!currentSession) {
192
- currentSession = {};
193
- }
194
- if (!currentSession['kv']) {
195
- currentSession['kv'] = {};
365
+ else {
366
+ data = getLocal(key);
196
367
  }
197
- currentSession['kv'] = {
198
- ...currentSession['kv'],
199
- ...data,
200
- };
201
- saveData('session', currentSession);
368
+ return (data === null || data === void 0 ? void 0 : data[destination]) || {};
202
369
  };
203
370
  const saveLocal = (value, key) => {
204
371
  try {
@@ -253,85 +420,19 @@ const getSession = (key) => {
253
420
  }
254
421
  };
255
422
 
256
- const encodeString = (name) => {
257
- if (typeof btoa === 'undefined') {
258
- return Buffer.from(name).toString('base64');
259
- }
260
- return btoa(name);
261
- };
262
- const getBasicRandomNumber = () => {
263
- return parseInt((Math.random() * 10000000000).toString(), 10);
264
- };
265
- const generateUUID = () => {
266
- let id = '';
267
- try {
268
- id = crypto.randomUUID();
269
- if (!id) {
270
- const array = new Uint32Array(20);
271
- const numbers = crypto.getRandomValues(array);
272
- for (let i = 0; i < 5; i++) {
273
- const y = i * 3;
274
- if (i !== 0) {
275
- id += '-';
276
- }
277
- const sum = numbers[y + 1] + numbers[y + 2] + numbers[y + 3];
278
- id += sum.toString();
279
- }
280
- }
281
- }
282
- catch {
283
- id = `${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}`;
284
- console.log('[EdgeTag] Crypto module not found');
285
- }
286
- return id;
287
- };
288
- const generateEventId = (name) => {
289
- let time = Date.now().toString();
290
- if (typeof performance !== 'undefined' &&
291
- typeof performance.now === 'function') {
292
- const perf = performance.now();
293
- if (perf) {
294
- time = perf.toFixed(4);
295
- }
296
- }
297
- return `${encodeString(name)}-${generateUUID()}-${time}`;
423
+ const getUserId$1 = (destination) => {
424
+ return getSetting(destination, 'userId');
298
425
  };
299
-
300
- const getCookieValue = (key) => {
301
- try {
302
- if (!document || !document.cookie) {
303
- return '';
304
- }
305
- const name = `${key}=`;
306
- const decodedCookie = decodeURIComponent(document.cookie);
307
- const ca = decodedCookie.split(';');
308
- for (let i = 0; i < ca.length; i++) {
309
- let c = ca[i];
310
- while (c.charAt(0) === ' ') {
311
- c = c.substring(1);
312
- }
313
- if (c.indexOf(name) === 0) {
314
- return c.substring(name.length, c.length);
315
- }
316
- }
317
- return '';
426
+ const handleGetUserId = (options) => {
427
+ if (options === null || options === void 0 ? void 0 : options.destination) {
428
+ return getUserId$1(options.destination);
318
429
  }
319
- catch {
320
- return '';
430
+ const instances = getInstances();
431
+ if (instances.length > 1) {
432
+ error('Multiple instances detected! Please provide a destination.');
433
+ return null;
321
434
  }
322
- };
323
-
324
- let initUserId = '';
325
- const handleGetUserId = () => {
326
- if (initUserId) {
327
- return initUserId;
328
- }
329
- // leaving this for backward compatibility as worker was maybe not updated yet
330
- // reference https://github.com/blotoutio/solutions/issues/1960
331
- return getCookieValue(cookieKey);
332
- };
333
- const setUserId = (userId) => {
334
- initUserId = userId;
435
+ return getUserId$1(instances[0]);
335
436
  };
336
437
 
337
438
  const beacon = (url, payload) => {
@@ -346,12 +447,12 @@ const beacon = (url, payload) => {
346
447
  return Promise.reject(new Error('Beacon not supported.'));
347
448
  }
348
449
  };
349
- const ajax = (method, url, payload) => fetch(url, {
450
+ const ajax = (destination, method, url, payload) => fetch(url, {
350
451
  method,
351
452
  headers: {
352
453
  'Content-type': 'application/json; charset=utf-8',
353
454
  Accept: 'application/json; charset=utf-8',
354
- EdgeTagUserId: handleGetUserId(),
455
+ EdgeTagUserId: getUserId$1(destination),
355
456
  },
356
457
  body: JSON.stringify(payload),
357
458
  credentials: 'include',
@@ -365,26 +466,26 @@ const ajax = (method, url, payload) => fetch(url, {
365
466
  }
366
467
  return Promise.resolve(body);
367
468
  });
368
- const getStandardPayload = (payload) => {
469
+ const getStandardPayload = (destination, payload) => {
369
470
  const data = {
370
- pageUrl: getPageUrl(),
471
+ pageUrl: getPageUrl(destination),
371
472
  pageTitle: getPageTitle(),
372
473
  userAgent: getUserAgent(),
373
- referrer: getReferrer(),
374
- search: getSearch(),
474
+ referrer: getReferrer(destination),
475
+ search: getSearch(destination),
375
476
  locale: getLocale(),
376
- sdkVersion: "0.51.1" ,
477
+ sdkVersion: "0.52.0" ,
377
478
  ...(payload || {}),
378
479
  };
379
480
  let storage = {};
380
- const session = getData$1('session');
481
+ const session = getData$1(destination, 'session');
381
482
  if (session) {
382
483
  storage = {
383
484
  ...storage,
384
485
  ...session,
385
486
  };
386
487
  }
387
- const local = getData$1('local');
488
+ const local = getData$1(destination, 'local');
388
489
  if (local) {
389
490
  storage = {
390
491
  ...storage,
@@ -398,11 +499,13 @@ async function postRequest(url, data, options) {
398
499
  if (!url) {
399
500
  return Promise.reject(new Error('URL is empty.'));
400
501
  }
401
- const payload = getStandardPayload(data);
502
+ const parsedUrl = new URL(url);
503
+ const destination = parsedUrl.origin;
504
+ const payload = getStandardPayload(destination, data);
402
505
  if (options && options.method === 'beacon') {
403
506
  return Promise.resolve(beacon(url, payload));
404
507
  }
405
- return await ajax('POST', url, payload);
508
+ return await ajax(destination, 'POST', url, payload);
406
509
  }
407
510
  async function getRequest(url, options) {
408
511
  if (!url) {
@@ -413,170 +516,44 @@ async function getRequest(url, options) {
413
516
  result: Promise.resolve(beacon(url)),
414
517
  };
415
518
  }
416
- return await ajax('GET', url);
519
+ const parsedUrl = new URL(url);
520
+ const destination = parsedUrl.origin;
521
+ return await ajax(destination, 'GET', url);
417
522
  }
418
523
 
419
- let endpointUrl = '';
420
- const generateUrl = (path) => {
421
- const endpoint = getUrl();
422
- if (!endpoint) {
524
+ const generateUrl = (destination, path) => {
525
+ if (!destination) {
423
526
  log('URL is not valid');
424
527
  return '';
425
528
  }
426
- return `${endpoint}${path}`;
427
- };
428
- const getUrl = () => {
429
- return endpointUrl;
529
+ return `${destination}${path}`;
430
530
  };
431
- const setUrl = (url) => {
432
- if (url == null) {
433
- return;
434
- }
435
- endpointUrl = url;
436
- };
437
- const getTagURL = (options) => {
438
- const url = new URL(generateUrl('/tag'));
531
+ const getTagURL = (destination, options) => {
532
+ const parsedUrl = new URL(generateUrl(destination, '/tag'));
439
533
  if (options === null || options === void 0 ? void 0 : options.sync) {
440
- url.searchParams.set('sync', 'true');
534
+ parsedUrl.searchParams.set('sync', 'true');
441
535
  }
442
- return url.toString();
536
+ return parsedUrl.toString();
443
537
  };
444
- const getInitURL = () => {
445
- return generateUrl('/init');
538
+ const getInitURL = (destination) => {
539
+ return generateUrl(destination, '/init');
446
540
  };
447
- const getConsentURL = () => {
448
- return generateUrl('/consent');
541
+ const getConsentURL = (destination) => {
542
+ return generateUrl(destination, '/consent');
449
543
  };
450
- const getUserURL = () => {
451
- return generateUrl('/user');
544
+ const getUserURL = (destination) => {
545
+ return generateUrl(destination, '/user');
452
546
  };
453
- const getDataURL = () => {
454
- return generateUrl(`/data`);
547
+ const getDataURL = (destination) => {
548
+ return generateUrl(destination, `/data`);
455
549
  };
456
- const getGetDataURL = (keys) => {
457
- return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
550
+ const getGetDataURL = (destination, keys) => {
551
+ return generateUrl(destination, `/data?keys=${encodeURIComponent(keys.join(','))}`);
458
552
  };
459
- const getKeysURL = () => {
460
- return generateUrl(`/keys`);
553
+ const getKeysURL = (destination) => {
554
+ return generateUrl(destination, `/keys`);
461
555
  };
462
556
 
463
- const isBool = (v) => typeof v == 'boolean';
464
- const isRecord = (v) => !!v && typeof v == 'object' && !Array.isArray(v);
465
- /**
466
- * This function validates user consent for a given provider and tag name.
467
- * It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
468
- */
469
- const hasUserConsent = (consent, provider, tagName) => {
470
- if (!isRecord(consent)) {
471
- return false;
472
- }
473
- let allowed = isBool(consent.all) ? consent.all : false;
474
- if (provider in consent) {
475
- const providerSpecific = consent[provider];
476
- if (isBool(providerSpecific)) {
477
- allowed = providerSpecific;
478
- }
479
- else if (isRecord(providerSpecific)) {
480
- if ('all' in providerSpecific && isBool(providerSpecific.all)) {
481
- allowed = providerSpecific.all;
482
- }
483
- if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
484
- allowed = providerSpecific[tagName];
485
- }
486
- }
487
- }
488
- return allowed;
489
- };
490
- /**
491
- * This function validates user consent for a given provider type, not based on tagName.
492
- */
493
- const hasUserConsentForProvider = (consent, provider) => {
494
- if (!isRecord(consent)) {
495
- return false;
496
- }
497
- let allowed = isBool(consent.all) ? consent.all : false;
498
- if (provider in consent) {
499
- const providerSpecific = consent[provider];
500
- if (isBool(providerSpecific)) {
501
- allowed = providerSpecific;
502
- }
503
- else if (isRecord(providerSpecific)) {
504
- return Object.keys(providerSpecific).some((instance) => providerSpecific[instance] === true);
505
- }
506
- }
507
- return allowed;
508
- };
509
- /**
510
- * This function validates provider allowance for a given provider and tag name.
511
- * It should not be used to validate `UserConsent`.
512
- */
513
- const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
514
- if (!isRecord(providersConfig)) {
515
- return true;
516
- }
517
- if (provider in providersConfig) {
518
- const providerSpecific = providersConfig[provider];
519
- if (isBool(providerSpecific)) {
520
- return providerSpecific;
521
- }
522
- if (isRecord(providerSpecific)) {
523
- const tagKeys = Object.keys(providerSpecific).filter((k) => k != 'all');
524
- if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
525
- return providerSpecific[tagName];
526
- }
527
- return isBool(providerSpecific.all)
528
- ? providerSpecific.all
529
- : tagKeys.length == 0;
530
- }
531
- }
532
- const providerKeys = Object.keys(providersConfig).filter((k) => k != 'all');
533
- return isBool(providersConfig.all)
534
- ? providersConfig.all
535
- : providerKeys.length == 0;
536
- };
537
-
538
- const upsert = (map, key, update, createDefault) => {
539
- const currentValue = map.has(key)
540
- ? map.get(key)
541
- : createDefault();
542
- return map.set(key, update(currentValue));
543
- };
544
-
545
- const expand = (str) => str.split(',').flatMap((entry) => {
546
- if (!entry.includes('-')) {
547
- return entry;
548
- }
549
- const result = [];
550
- const [start, end] = entry.split('-').map(Number);
551
- for (let i = start; i <= end; i++) {
552
- result.push(i.toString());
553
- }
554
- return result;
555
- });
556
- /**
557
- * Exported from https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes
558
- *
559
- * In Dev Tools, select the `tbody` element containing the area codes and run the following code,
560
- * replacing the emdash character with a simple endash:
561
- *
562
- * ```ts
563
- * [...$0.querySelectorAll('td:first-child')]
564
- * .filter(cell => cell.firstChild.nodeName != 'A')
565
- * .map(cell => cell.textContent.trim()).join(',')
566
- * ```
567
- */
568
- new Set([
569
- ...expand('200,211,221,222,230,232,233,235,237-238,241,243,244,245,247,255,257,258-259,261,265,266,271,273,274,275,277,278,280,282,283,285-287,288,290-299'),
570
- ...expand('300,311,322,324,327,328,333,335,338,342,344,348-349,353,355,356,357-359,362,366,369,370-379,381,382,383-384,387,388,389,390-399'),
571
- ...expand('400,411,420,421-422,426-427,428,429,433,439,444,446,449,451-454,455,456,457,459,460,461-462,465,466,467,471,476,477,481-483,485-486,487,488,489,490-499'),
572
- ...expand('511,532,535,536,537,538,542-543,545-547,549-550,552-554,555,556,558,560,565,568,569,576,578,583,589,590-599'),
573
- ...expand('611,621,624,625,627,632,633,634-635,637-638,642-643,644,648,652-654,655,663,665,666,668,673-676,677,679,685,686,687,688,690-699'),
574
- ...expand('711,722,723,729,733,735-736,739,741,744,745-746,748,749-751,752,755,756,759,761,764,766,768,776,777,783,788,789,790-799'),
575
- ...expand('811,821,822,823-824,827,834,836,841-842,846,851,852-853,871,874-875,879,880-887,889,890-899'),
576
- ...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
577
- ]);
578
-
579
- let initialized = false;
580
557
  const providersPackages = {};
581
558
  const setPreferences = (preferences) => {
582
559
  var _a;
@@ -587,7 +564,6 @@ const setPreferences = (preferences) => {
587
564
  error('Please provide URL for EdgeTag');
588
565
  return false;
589
566
  }
590
- !!preferences.disableConsentCheck;
591
567
  (_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
592
568
  if (!provider.name) {
593
569
  return;
@@ -607,52 +583,122 @@ const setPreferences = (preferences) => {
607
583
  catch {
608
584
  // do nothing
609
585
  }
610
- setUrl(preferences.edgeURL);
586
+ initSettings(preferences.edgeURL, {
587
+ disableConsent: !!preferences.disableConsentCheck,
588
+ });
611
589
  return true;
612
590
  };
613
- const getProvidersPackage = () => providersPackages;
614
- const isInitialized = () => initialized;
615
- const setInitialized = () => {
616
- initialized = true;
591
+ const getProvidersPackage = (destination) => {
592
+ const packages = getSetting(destination, 'packages');
593
+ const providers = [];
594
+ packages === null || packages === void 0 ? void 0 : packages.forEach((pkg) => {
595
+ const provider = providersPackages[pkg.package];
596
+ if (!provider) {
597
+ return;
598
+ }
599
+ providers.push(provider);
600
+ });
601
+ return providers;
617
602
  };
618
- const configuredTags = new Map();
619
- const addConfiguredTag = (pkg, tagName) => upsert(configuredTags, pkg, (names) => names.add(tagName), () => new Set());
620
- const getConfiguredTags = () => configuredTags;
621
603
 
622
- const manifestVariables = {};
623
- const addProviderVariable = (name, variables, tagName) => {
624
- manifestVariables[name] = {
625
- ...manifestVariables[name],
626
- [tagName]: variables || {},
627
- };
604
+ const encodeString = (name) => {
605
+ if (typeof btoa === 'undefined') {
606
+ return Buffer.from(name).toString('base64');
607
+ }
608
+ return btoa(name);
628
609
  };
629
- const getProviderVariables = (name) => {
630
- if (!name) {
631
- return {};
610
+ const getBasicRandomNumber = () => {
611
+ return parseInt((Math.random() * 10000000000).toString(), 10);
612
+ };
613
+ const generateUUID = () => {
614
+ let id = '';
615
+ try {
616
+ id = crypto.randomUUID();
617
+ if (!id) {
618
+ const array = new Uint32Array(20);
619
+ const numbers = crypto.getRandomValues(array);
620
+ for (let i = 0; i < 5; i++) {
621
+ const y = i * 3;
622
+ if (i !== 0) {
623
+ id += '-';
624
+ }
625
+ const sum = numbers[y + 1] + numbers[y + 2] + numbers[y + 3];
626
+ id += sum.toString();
627
+ }
628
+ }
629
+ }
630
+ catch {
631
+ id = `${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}`;
632
+ console.log('[EdgeTag] Crypto module not found');
633
+ }
634
+ return id;
635
+ };
636
+ const generateEventId = (name) => {
637
+ let time = Date.now().toString();
638
+ if (typeof performance !== 'undefined' &&
639
+ typeof performance.now === 'function') {
640
+ const perf = performance.now();
641
+ if (perf) {
642
+ time = perf.toFixed(4);
643
+ }
632
644
  }
633
- return manifestVariables[name] || {};
645
+ return `${encodeString(name)}-${generateUUID()}-${time}`;
634
646
  };
635
647
 
636
- let stubs = [];
637
- const addStubs = (newStubs) => {
638
- stubs = [...stubs, ...newStubs];
648
+ const getCookieValue = (key) => {
649
+ try {
650
+ if (!document || !document.cookie) {
651
+ return '';
652
+ }
653
+ const name = `${key}=`;
654
+ const decodedCookie = decodeURIComponent(document.cookie);
655
+ const ca = decodedCookie.split(';');
656
+ for (let i = 0; i < ca.length; i++) {
657
+ let c = ca[i];
658
+ while (c.charAt(0) === ' ') {
659
+ c = c.substring(1);
660
+ }
661
+ if (c.indexOf(name) === 0) {
662
+ return c.substring(name.length, c.length);
663
+ }
664
+ }
665
+ return '';
666
+ }
667
+ catch {
668
+ return '';
669
+ }
639
670
  };
640
- const addStub = (stub) => {
641
- stubs.push(stub);
671
+
672
+ const getConsent$1 = (destination) => {
673
+ const storageConsent = getDataPerKey(destination, 'local', tagStorage, consentKey);
674
+ if (storageConsent) {
675
+ return storageConsent;
676
+ }
677
+ return getSetting(destination, 'consent');
642
678
  };
643
- const processStubs = () => {
679
+
680
+ const processStubs = (destination) => {
644
681
  try {
682
+ const stubs = getSetting(destination, 'stubs');
645
683
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
646
684
  // @ts-ignore
647
685
  stubs.forEach((stub) => api[stub.name](...(stub.arguments || [])));
648
- stubs = [];
686
+ setSetting({
687
+ stubs: [],
688
+ }, destination);
649
689
  }
650
690
  catch (e) {
651
691
  error(e);
652
692
  }
653
693
  };
694
+ const addStub = (destination, stub) => {
695
+ const otherStubs = getSetting(destination, 'stubs') || [];
696
+ setSetting({
697
+ stubs: [...otherStubs, stub],
698
+ }, destination);
699
+ };
654
700
 
655
- const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
701
+ const sendTag = (destination, { eventName, eventId, data, providerData, providers, options }) => {
656
702
  const payload = {
657
703
  eventName,
658
704
  eventId,
@@ -663,11 +709,11 @@ const sendTag = ({ eventName, eventId, data, providerData, providers, options, }
663
709
  if (providers) {
664
710
  payload.providers = providers;
665
711
  }
666
- postRequest(getTagURL(options), payload, options).catch(error);
712
+ postRequest(getTagURL(destination, options), payload, options).catch(error);
667
713
  };
668
- const handleTag = (eventName, data = {}, providers, options) => {
669
- if (!isInitialized()) {
670
- addStub({
714
+ const processTag = (destination, eventName, data = {}, providers, options) => {
715
+ if (!getSetting(destination, 'initialized')) {
716
+ addStub(destination, {
671
717
  name: 'tag',
672
718
  arguments: [eventName, data, providers, options],
673
719
  });
@@ -677,11 +723,11 @@ const handleTag = (eventName, data = {}, providers, options) => {
677
723
  if (!eventId) {
678
724
  eventId = generateEventId(eventName);
679
725
  }
680
- const providerPackages = getProvidersPackage();
681
- const configuredTags = getConfiguredTags();
682
- const userId = handleGetUserId();
726
+ const providerPackages = getProvidersPackage(destination);
727
+ const configuredTags = getSetting(destination, 'channels');
728
+ const userId = getUserId$1(destination);
683
729
  const providerData = {};
684
- const consent = getConsent$1();
730
+ const consent = getConsent$1(destination);
685
731
  for (const pkg of Object.values(providerPackages)) {
686
732
  if (!pkg || !pkg.name || !pkg.tag) {
687
733
  continue;
@@ -690,26 +736,25 @@ const handleTag = (eventName, data = {}, providers, options) => {
690
736
  log(`Provider ${pkg.name} is not in allow list`);
691
737
  continue;
692
738
  }
693
- const variables = getProviderVariables(pkg.name);
739
+ const variables = getProviderVariables(destination, pkg.name);
694
740
  const result = {};
695
- const providerVariables = Object.entries(variables);
696
741
  const executionContext = new Map();
697
- for (const [tagName, variableSet] of providerVariables) {
698
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
699
- log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
742
+ for (const variable of variables) {
743
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
744
+ log(`Provider instance is not allowed (${pkg.name}: ${variable.tagName})`);
700
745
  continue;
701
746
  }
702
- if (!hasUserConsent(consent, pkg.name, tagName)) {
703
- log(`Consent is missing (${pkg.name}: ${tagName})`);
747
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
748
+ log(`Consent is missing (${pkg.name}: ${variable.tagName})`);
704
749
  continue;
705
750
  }
706
- result[tagName] = pkg.tag({
751
+ result[variable.tagName] = pkg.tag({
707
752
  userId,
708
753
  eventName,
709
754
  eventId,
710
755
  data: JSON.parse(JSON.stringify(data)),
711
- sendTag,
712
- manifestVariables: variableSet,
756
+ sendTag: sendTag.bind(null, destination),
757
+ manifestVariables: variable.variableSet,
713
758
  executionContext,
714
759
  });
715
760
  }
@@ -718,7 +763,7 @@ const handleTag = (eventName, data = {}, providers, options) => {
718
763
  if (!hasAllowedManifestTags(configuredTags, consent, providers)) {
719
764
  return;
720
765
  }
721
- sendTag({
766
+ sendTag(destination, {
722
767
  eventName,
723
768
  eventId,
724
769
  data,
@@ -727,6 +772,15 @@ const handleTag = (eventName, data = {}, providers, options) => {
727
772
  options,
728
773
  });
729
774
  };
775
+ const handleTag = (eventName, data = {}, providers, options) => {
776
+ if (options === null || options === void 0 ? void 0 : options.destination) {
777
+ processTag(options.destination, eventName, data, providers, options);
778
+ return;
779
+ }
780
+ getInstances().forEach((instance) => {
781
+ processTag(instance, eventName, data, providers, options);
782
+ });
783
+ };
730
784
  const hasAllowedManifestTags = (tags, consent, providersConfig) => {
731
785
  for (const [pkg, tagNames] of tags) {
732
786
  for (const tagName of tagNames) {
@@ -739,28 +793,37 @@ const hasAllowedManifestTags = (tags, consent, providersConfig) => {
739
793
  return false;
740
794
  };
741
795
 
742
- const handleGetData = (keys, callback) => {
743
- if (!keys || keys.length === 0) {
744
- error('Provide keys for get data API.');
745
- return;
746
- }
747
- getRequest(getGetDataURL(keys))
796
+ const processGetData = (destination, keys, callback) => {
797
+ getRequest(getGetDataURL(destination, keys))
748
798
  .then((result) => {
749
799
  callback((result === null || result === void 0 ? void 0 : result.result) || {});
750
800
  })
751
801
  .catch(error);
752
802
  };
753
-
754
- const handleData = (data, providers, options) => {
755
- if (!data || Object.keys(data).length === 0) {
756
- error('Provide data for data API.');
803
+ const handleGetData = (keys, callback, options) => {
804
+ if (!keys || keys.length === 0) {
805
+ error('Provide keys for get data API.');
806
+ return;
807
+ }
808
+ if (options === null || options === void 0 ? void 0 : options.destination) {
809
+ processGetData(options.destination, keys, callback);
810
+ return;
811
+ }
812
+ const instances = getInstances();
813
+ if (instances.length > 1) {
814
+ error('Multiple instances found! Please provide destination.');
815
+ callback({});
757
816
  return;
758
817
  }
759
- saveKV(data);
760
- const providerPackages = getProvidersPackage();
761
- const configuredTags = getConfiguredTags();
762
- const userId = handleGetUserId();
763
- const consent = getConsent$1();
818
+ processGetData(instances[0], keys, callback);
819
+ };
820
+
821
+ const processData = (destination, data, providers, options) => {
822
+ saveKV(destination, data);
823
+ const providerPackages = getProvidersPackage(destination);
824
+ const configuredTags = getSetting(destination, 'channels');
825
+ const userId = getUserId$1(destination);
826
+ const consent = getConsent$1(destination);
764
827
  for (const pkg of Object.values(providerPackages)) {
765
828
  if (!pkg || !pkg.user || !pkg.name) {
766
829
  continue;
@@ -769,70 +832,92 @@ const handleData = (data, providers, options) => {
769
832
  log(`Provider ${pkg.name} is not in allow list`);
770
833
  continue;
771
834
  }
772
- const variables = getProviderVariables(pkg.name);
773
- for (const [tagName, variableSet] of Object.entries(variables)) {
774
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
775
- log(`Data not allowed for ${pkg.name} (${tagName})`);
835
+ const variables = getProviderVariables(destination, pkg.name);
836
+ for (const variable of variables) {
837
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
838
+ log(`Data not allowed for ${pkg.name} (${variable.tagName})`);
776
839
  continue;
777
840
  }
778
- if (!hasUserConsent(consent, pkg.name, tagName)) {
779
- log(`Consent is missing for ${pkg.name} (${tagName})`);
841
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
842
+ log(`Consent is missing for ${pkg.name} (${variable.tagName})`);
780
843
  continue;
781
844
  }
782
845
  pkg.user({
783
846
  userId,
784
847
  data,
785
- manifestVariables: variableSet,
848
+ manifestVariables: variable.variableSet,
786
849
  });
787
850
  }
788
851
  }
789
- postRequest(getDataURL(), { data, providers }, options).catch(error);
852
+ postRequest(getDataURL(destination), { data, providers }, options).catch(error);
790
853
  };
791
-
792
- let memoryConsent;
793
- const saveConsent = (consent) => {
794
- setConsent(consent);
795
- savePerKey('local', tagStorage, consent, consentKey);
854
+ const handleData = (data, providers, options) => {
855
+ if (!data || Object.keys(data).length === 0) {
856
+ error('Provide data for data API.');
857
+ return;
858
+ }
859
+ if (options === null || options === void 0 ? void 0 : options.destination) {
860
+ processData(options.destination, data, providers, options);
861
+ return;
862
+ }
863
+ getInstances().forEach((destination) => {
864
+ processData(destination, data, providers, options);
865
+ });
796
866
  };
867
+
797
868
  const handleConsent = (consent, options) => {
798
- const existingConsent = getConsent$1();
869
+ if (options === null || options === void 0 ? void 0 : options.destination) {
870
+ processConsent(options.destination, consent, options === null || options === void 0 ? void 0 : options.localSave);
871
+ return;
872
+ }
873
+ getInstances().forEach((destination) => {
874
+ processConsent(destination, consent, options === null || options === void 0 ? void 0 : options.localSave);
875
+ });
876
+ };
877
+ const saveConsent = (destination, consent) => {
878
+ setSetting({
879
+ consent,
880
+ }, destination);
881
+ savePerKey(destination, 'local', tagStorage, consent, consentKey);
882
+ };
883
+ const processConsent = (destination, consent, localSave) => {
884
+ const existingConsent = getConsent$1(destination);
799
885
  if (areEqual(existingConsent, consent)) {
800
886
  return;
801
887
  }
802
888
  const payload = {
803
889
  consentString: consent,
804
890
  };
805
- saveConsent(consent);
806
- if (!(options === null || options === void 0 ? void 0 : options.localSave)) {
807
- postRequest(getConsentURL(), payload).catch(error);
891
+ saveConsent(destination, consent);
892
+ if (!localSave) {
893
+ postRequest(getConsentURL(destination), payload).catch(error);
808
894
  }
809
- const userId = handleGetUserId();
810
- const providerPackages = getProvidersPackage();
895
+ const userId = getUserId$1(destination);
896
+ const providerPackages = getProvidersPackage(destination);
811
897
  const executionContext = new Map();
812
898
  /* Calling Init for all provider instances based on consent check */
813
899
  for (const pkg of Object.values(providerPackages)) {
814
900
  if (!pkg || !pkg.name || !pkg.init) {
815
901
  continue;
816
902
  }
817
- const variables = getProviderVariables(pkg.name);
818
- const providerVariables = Object.entries(variables);
819
- for (const [tagName, variablesSet] of providerVariables) {
820
- const hasConsent = hasUserConsent(consent, pkg.name, tagName);
903
+ const variables = getProviderVariables(destination, pkg.name);
904
+ for (const variable of variables) {
905
+ const hasConsent = hasUserConsent(consent, pkg.name, variable.tagName);
821
906
  if (!hasConsent) {
822
907
  continue;
823
908
  }
824
909
  pkg.init({
825
910
  userId,
826
911
  isNewUser: false,
827
- baseUrl: getUrl(),
912
+ baseUrl: destination,
828
913
  manifest: {
829
- tagName,
830
- variables: variablesSet,
914
+ tagName: variable.tagName,
915
+ variables: variable.variableSet,
831
916
  package: pkg.name,
832
917
  },
833
- sendTag,
834
- sendEdgeData: handleData,
835
- getEdgeData: handleGetData,
918
+ sendTag: sendTag.bind(null, destination),
919
+ sendEdgeData: processData.bind(null, destination),
920
+ getEdgeData: processGetData.bind(null, destination),
836
921
  keyName: `${keyPrefix}Store`,
837
922
  executionContext,
838
923
  session: null,
@@ -842,6 +927,7 @@ const handleConsent = (consent, options) => {
842
927
  try {
843
928
  window.dispatchEvent(new CustomEvent('edgetag-consent', {
844
929
  detail: {
930
+ destination,
845
931
  oldConsent: existingConsent,
846
932
  newConsent: consent,
847
933
  },
@@ -860,20 +946,10 @@ const handleConsent = (consent, options) => {
860
946
  pkg.consent({ hasConsent });
861
947
  }
862
948
  };
863
- const setConsent = (newConsent) => {
864
- memoryConsent = newConsent;
865
- };
866
- const getConsent$1 = () => {
867
- const storageConsent = getDataPerKey('local', tagStorage, consentKey);
868
- if (storageConsent) {
869
- return storageConsent;
870
- }
871
- return memoryConsent;
872
- };
873
949
 
874
950
  const cacheKey = `${keyPrefix}Cache`;
875
951
  const identity = (v) => v;
876
- const saveDataToEdge = (key, value, provider) => {
952
+ const saveDataToEdge = (destination, key, value, provider) => {
877
953
  if (!value) {
878
954
  return;
879
955
  }
@@ -887,9 +963,11 @@ const saveDataToEdge = (key, value, provider) => {
887
963
  return;
888
964
  }
889
965
  }
890
- handleData({ [`${provider}::${key}`]: updatedValue });
966
+ handleData({ [`${provider}::${key}`]: updatedValue }, undefined, {
967
+ destination,
968
+ });
891
969
  };
892
- const handleCaptureQuery = (provider, key, persistType, map) => {
970
+ const handleCaptureQuery = (destination, provider, key, persistType, map) => {
893
971
  try {
894
972
  if (!window) {
895
973
  return;
@@ -898,7 +976,7 @@ const handleCaptureQuery = (provider, key, persistType, map) => {
898
976
  catch {
899
977
  return;
900
978
  }
901
- const params = new URLSearchParams(getSearch());
979
+ const params = new URLSearchParams(getSearch(destination));
902
980
  if (!params || !params.get(key)) {
903
981
  return;
904
982
  }
@@ -907,27 +985,29 @@ const handleCaptureQuery = (provider, key, persistType, map) => {
907
985
  return;
908
986
  }
909
987
  if (persistType === 'edge') {
910
- saveDataToEdge(key, data, provider);
988
+ saveDataToEdge(destination, key, data, provider);
911
989
  return;
912
990
  }
913
- saveDataPerKey(persistType, provider, data, key);
991
+ saveDataPerKey(destination, persistType, provider, data, key);
914
992
  };
915
- const getFromCache = (persistType, provider, key) => {
993
+ const getFromCache = (destination, persistType, provider, key) => {
916
994
  var _a;
917
- const cache = getData$1(persistType === 'edge' ? 'local' : persistType, cacheKey);
995
+ const type = persistType === 'edge' ? 'local' : persistType;
996
+ const cache = getData$1(destination, type, cacheKey);
918
997
  return (_a = cache[provider]) === null || _a === void 0 ? void 0 : _a[key];
919
998
  };
920
- const saveToCache = (persistType, provider, key, value) => {
921
- const cache = getData$1(persistType === 'edge' ? 'local' : persistType, cacheKey);
999
+ const saveToCache = (destination, persistType, provider, key, value) => {
1000
+ const type = persistType === 'edge' ? 'local' : persistType;
1001
+ const cache = getData$1(destination, type, cacheKey);
922
1002
  if (!cache[provider]) {
923
1003
  cache[provider] = { [key]: value };
924
1004
  }
925
1005
  else {
926
1006
  cache[provider][key] = value;
927
1007
  }
928
- saveData(persistType === 'edge' ? 'local' : persistType, cache, cacheKey);
1008
+ saveData(destination, type, cache, cacheKey);
929
1009
  };
930
- const handleCaptureStorage = (provider, key, persistType, location, map) => {
1010
+ const handleCaptureStorage = (destination, provider, key, persistType, location, map) => {
931
1011
  let data;
932
1012
  try {
933
1013
  switch (location) {
@@ -950,44 +1030,43 @@ const handleCaptureStorage = (provider, key, persistType, location, map) => {
950
1030
  if (!data) {
951
1031
  return;
952
1032
  }
953
- const cachedKey = `${handleGetUserId()}/${key}`;
954
- const cachedValue = getFromCache(persistType, provider, cachedKey);
1033
+ const cachedKey = `${getUserId$1(destination)}/${key}`;
1034
+ const cachedValue = getFromCache(destination, persistType, provider, cachedKey);
955
1035
  if (persistType === 'edge' && cachedValue !== data) {
956
- saveDataToEdge(key, data, provider);
957
- saveToCache(persistType, provider, cachedKey, data);
1036
+ saveDataToEdge(destination, key, data, provider);
1037
+ saveToCache(destination, persistType, provider, cachedKey, data);
958
1038
  return;
959
1039
  }
960
- saveDataPerKey(persistType, provider, data, key);
1040
+ saveDataPerKey(destination, persistType, provider, data, key);
961
1041
  };
962
- const handleCapture = (provider, params, capture) => {
1042
+ const handleCapture = (destination, provider, params, capture) => {
963
1043
  params.forEach((param) => {
964
1044
  switch (param.type) {
965
1045
  case 'query': {
966
- handleCaptureQuery(provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
1046
+ handleCaptureQuery(destination, provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
967
1047
  break;
968
1048
  }
969
1049
  case 'storage': {
970
- handleCaptureStorage(provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
1050
+ handleCaptureStorage(destination, provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
971
1051
  break;
972
1052
  }
973
1053
  }
974
1054
  });
975
1055
  };
976
1056
 
977
- const handleManifest = (response, consent) => {
978
- const providerPackages = getProvidersPackage();
979
- const userId = handleGetUserId();
1057
+ const handleManifest = (destination, response) => {
1058
+ const providerPackages = getProvidersPackage(destination);
1059
+ const userId = getUserId$1(destination);
980
1060
  const executionContext = new Map();
981
1061
  const manifest = response.result;
982
1062
  manifest.forEach((provider) => {
983
- addConfiguredTag(provider.package, provider.tagName);
984
- addProviderVariable(provider.package, provider.variables, provider.tagName);
1063
+ addChannel(destination, provider.package, provider.tagName);
985
1064
  const pkg = providerPackages[provider.package];
986
1065
  if (provider.rules) {
987
1066
  Object.entries(provider.rules).forEach(([name, recipe]) => {
988
1067
  switch (name) {
989
1068
  case 'capture': {
990
- handleCapture(provider.package, recipe, pkg === null || pkg === void 0 ? void 0 : pkg.capture);
1069
+ handleCapture(destination, provider.package, recipe, pkg === null || pkg === void 0 ? void 0 : pkg.capture);
991
1070
  return;
992
1071
  }
993
1072
  }
@@ -995,36 +1074,27 @@ const handleManifest = (response, consent) => {
995
1074
  }
996
1075
  if (pkg && pkg.name && pkg.init) {
997
1076
  /* this defines if the consent is given for a specific instance of a provider */
998
- const hasConsent = hasUserConsent(consent, pkg.name, provider.tagName);
1077
+ const hasConsent = hasUserConsent(getSetting(destination, 'consent'), pkg.name, provider.tagName);
999
1078
  if (hasConsent) {
1000
1079
  pkg.init({
1001
1080
  userId,
1002
1081
  isNewUser: !!response.isNewUser,
1003
1082
  session: response.session,
1004
- baseUrl: getUrl(),
1083
+ baseUrl: destination,
1005
1084
  manifest: provider,
1006
- sendTag,
1007
- sendEdgeData: handleData,
1008
- getEdgeData: handleGetData,
1085
+ sendTag: sendTag.bind(null, destination),
1086
+ sendEdgeData: processData.bind(null, destination),
1087
+ getEdgeData: processGetData.bind(null, destination),
1009
1088
  keyName: `${keyPrefix}Store`,
1010
1089
  executionContext,
1011
1090
  });
1012
1091
  }
1013
1092
  }
1014
1093
  });
1015
- setInitialized();
1016
- processStubs();
1017
- };
1018
-
1019
- let initIsNewUser = undefined;
1020
- const handleIsNewUser = () => {
1021
- if (initIsNewUser !== undefined) {
1022
- return initIsNewUser;
1023
- }
1024
- return undefined;
1025
- };
1026
- const setIsNewUSer = (isNewUser) => {
1027
- initIsNewUser = isNewUser;
1094
+ setSetting({
1095
+ initialized: true,
1096
+ }, destination);
1097
+ processStubs(destination);
1028
1098
  };
1029
1099
 
1030
1100
  const handleInit = (preferences) => {
@@ -1033,15 +1103,17 @@ const handleInit = (preferences) => {
1033
1103
  return;
1034
1104
  }
1035
1105
  if (preferences.afterManifestEvents) {
1036
- addStubs(preferences.afterManifestEvents);
1106
+ setSetting({
1107
+ stubs: preferences.afterManifestEvents,
1108
+ }, preferences.edgeURL);
1037
1109
  }
1038
- const url = new URL(getInitURL());
1110
+ const url = new URL(getInitURL(preferences.edgeURL));
1039
1111
  if (preferences.disableConsentCheck) {
1040
1112
  url.searchParams.set('consentDisabled', 'true');
1041
- saveConsent({ all: true });
1113
+ saveConsent(preferences.edgeURL, { all: true });
1042
1114
  }
1043
1115
  if (preferences.userId) {
1044
- setUserId(preferences.userId);
1116
+ setSetting({ userId: preferences.userId }, preferences.edgeURL);
1045
1117
  url.searchParams.set('userId', preferences.userId);
1046
1118
  }
1047
1119
  getRequest(url.href)
@@ -1050,18 +1122,17 @@ const handleInit = (preferences) => {
1050
1122
  error('Initialization failed');
1051
1123
  return;
1052
1124
  }
1053
- if (result.userId) {
1054
- setUserId(result.userId);
1055
- }
1056
- const consent = getConsent$1();
1057
- if (result.consent && !consent) {
1058
- saveConsent(result.consent);
1059
- }
1060
- setIsNewUSer(result.isNewUser);
1061
- handleManifest(result, consent || result.consent);
1125
+ setSetting({
1126
+ isNewUser: result.isNewUser,
1127
+ consent: getConsent$1(preferences.edgeURL) || result.consent,
1128
+ userId: result.userId,
1129
+ packages: result.result,
1130
+ }, preferences.edgeURL);
1131
+ handleManifest(preferences.edgeURL, result);
1062
1132
  try {
1063
1133
  window.dispatchEvent(new CustomEvent('edgetag-initialized', {
1064
1134
  detail: {
1135
+ destination: preferences.edgeURL,
1065
1136
  userId: result.userId,
1066
1137
  isNewUser: result.isNewUser,
1067
1138
  consent: result.consent,
@@ -1077,18 +1148,14 @@ const handleInit = (preferences) => {
1077
1148
  .catch(error);
1078
1149
  };
1079
1150
 
1080
- const handleUser = (key, value, providers, options) => {
1081
- if (!key || !value) {
1082
- error('Key or Value is missing in user API.');
1083
- return;
1084
- }
1085
- saveKV({
1151
+ const processUser = (destination, key, value, providers, options) => {
1152
+ saveKV(destination, {
1086
1153
  [key]: value,
1087
1154
  });
1088
- const providerPackages = getProvidersPackage();
1089
- const configuredTags = getConfiguredTags();
1090
- const consent = getConsent$1();
1091
- const userId = handleGetUserId();
1155
+ const providerPackages = getProvidersPackage(destination);
1156
+ const configuredTags = getSetting(destination, 'channels');
1157
+ const consent = getConsent$1(destination);
1158
+ const userId = getUserId$1(destination);
1092
1159
  for (const pkg of Object.values(providerPackages)) {
1093
1160
  if (!pkg || !pkg.name || !pkg.user) {
1094
1161
  continue;
@@ -1097,47 +1164,73 @@ const handleUser = (key, value, providers, options) => {
1097
1164
  log(`Provider ${pkg.name} is not in allow list`);
1098
1165
  continue;
1099
1166
  }
1100
- const variables = getProviderVariables(pkg.name);
1101
- for (const [tagName, variableSet] of Object.entries(variables)) {
1102
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
1103
- log(`User not allowed for ${pkg.name} (${tagName})`);
1167
+ const variables = getProviderVariables(destination, pkg.name);
1168
+ for (const variable of variables) {
1169
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
1170
+ log(`User not allowed for ${pkg.name} (${variable.tagName})`);
1104
1171
  continue;
1105
1172
  }
1106
- if (!hasUserConsent(consent, pkg.name, tagName)) {
1107
- log(`User doesn't have consent for ${pkg.name} (${tagName})`);
1173
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
1174
+ log(`User doesn't have consent for ${pkg.name} (${variable.tagName})`);
1108
1175
  continue;
1109
1176
  }
1110
1177
  pkg.user({
1111
1178
  userId,
1112
1179
  data: { [key]: value },
1113
- manifestVariables: variableSet,
1180
+ manifestVariables: variable.variableSet,
1114
1181
  });
1115
1182
  }
1116
1183
  }
1117
- postRequest(getUserURL(), {
1184
+ postRequest(getUserURL(destination), {
1118
1185
  key,
1119
1186
  value,
1120
1187
  providers,
1121
1188
  }, options).catch(error);
1122
1189
  };
1190
+ const handleUser = (key, value, providers, options) => {
1191
+ if (!key || !value) {
1192
+ error('Key or Value is missing in user API.');
1193
+ return;
1194
+ }
1195
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1196
+ processUser(options.destination, key, value, providers, options);
1197
+ return;
1198
+ }
1199
+ getInstances().forEach((destination) => {
1200
+ processUser(destination, key, value, providers, options);
1201
+ });
1202
+ };
1123
1203
 
1124
- const handleKeys = (callback) => {
1125
- getRequest(getKeysURL())
1204
+ const processKeys = (destination, callback) => {
1205
+ getRequest(getKeysURL(destination))
1126
1206
  .then((result) => {
1127
1207
  callback((result === null || result === void 0 ? void 0 : result.result) || []);
1128
1208
  })
1129
1209
  .catch(error);
1130
1210
  };
1211
+ const handleKeys = (callback, options) => {
1212
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1213
+ processKeys(options.destination, callback);
1214
+ return;
1215
+ }
1216
+ const instances = getInstances();
1217
+ if (instances.length > 1) {
1218
+ error('Multiple instances found! Please provide destination.');
1219
+ callback([]);
1220
+ return;
1221
+ }
1222
+ processKeys(instances[0], callback);
1223
+ };
1131
1224
 
1132
- const handleGetConsent = (callback) => {
1133
- getRequest(getConsentURL())
1225
+ const processGetConsent = (destination, callback) => {
1226
+ getRequest(getConsentURL(destination))
1134
1227
  .then((result) => {
1135
1228
  // this will try to return the consent data stored in Edge
1136
1229
  return result === null || result === void 0 ? void 0 : result.result;
1137
1230
  })
1138
1231
  .catch(() => undefined)
1139
1232
  .then((result) => {
1140
- const consent = result !== null && result !== void 0 ? result : getConsent$1(); // this is a default value i.e. value from local storage and memory incase Edge doesn't have consent
1233
+ const consent = result !== null && result !== void 0 ? result : getConsent$1(destination); // this is a default value i.e. value from local storage and memory incase Edge doesn't have consent
1141
1234
  if (consent) {
1142
1235
  callback(consent);
1143
1236
  }
@@ -1146,9 +1239,48 @@ const handleGetConsent = (callback) => {
1146
1239
  }
1147
1240
  });
1148
1241
  };
1242
+ const handleGetConsent = (callback, options) => {
1243
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1244
+ processGetConsent(options.destination, callback);
1245
+ return;
1246
+ }
1247
+ const instances = getInstances();
1248
+ if (instances.length > 1) {
1249
+ callback(null, new Error('Multiple instances found! Please provide destination.'));
1250
+ return;
1251
+ }
1252
+ processGetConsent(instances[0], callback);
1253
+ };
1149
1254
 
1150
- const handleConfig = (config) => {
1151
- setConfig$1(config);
1255
+ const handleIsNewUser = (options) => {
1256
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1257
+ return getSetting(options.destination, 'isNewUser');
1258
+ }
1259
+ const instances = getInstances();
1260
+ if (instances.length > 1) {
1261
+ error('Multiple instances found! Please provide destination.');
1262
+ return undefined;
1263
+ }
1264
+ return getSetting(instances[0], 'isNewUser');
1265
+ };
1266
+
1267
+ const processConfig = (destination, config) => {
1268
+ const existingConfig = getSetting(destination, 'config');
1269
+ setSetting({
1270
+ config: {
1271
+ ...existingConfig,
1272
+ ...config,
1273
+ },
1274
+ }, destination);
1275
+ };
1276
+ const handleConfig = (config, options) => {
1277
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1278
+ processConfig(options.destination, config);
1279
+ return;
1280
+ }
1281
+ getInstances().forEach((destination) => {
1282
+ processConfig(destination, config);
1283
+ });
1152
1284
  };
1153
1285
 
1154
1286
  const init = (preferences) => {
@@ -1166,23 +1298,23 @@ const user = (key, value, providers, options) => {
1166
1298
  const data = (value, providers, options) => {
1167
1299
  handleData(value, providers, options);
1168
1300
  };
1169
- const getData = (keys, callback) => {
1170
- handleGetData(keys, callback);
1301
+ const getData = (keys, callback, options) => {
1302
+ handleGetData(keys, callback, options);
1171
1303
  };
1172
- const keys = (callback) => {
1173
- handleKeys(callback);
1304
+ const keys = (callback, options) => {
1305
+ handleKeys(callback, options);
1174
1306
  };
1175
- const getUserId = () => {
1176
- return handleGetUserId();
1307
+ const getUserId = (options) => {
1308
+ return handleGetUserId(options);
1177
1309
  };
1178
- const getConsent = (callback) => {
1179
- handleGetConsent(callback);
1310
+ const getConsent = (callback, options) => {
1311
+ handleGetConsent(callback, options);
1180
1312
  };
1181
- const isNewUser = () => {
1182
- return handleIsNewUser();
1313
+ const isNewUser = (options) => {
1314
+ return handleIsNewUser(options);
1183
1315
  };
1184
- const setConfig = (config) => {
1185
- return handleConfig(config);
1316
+ const setConfig = (config, options) => {
1317
+ handleConfig(config, options);
1186
1318
  };
1187
1319
 
1188
1320
  exports.consent = consent;