@blotoutio/edgetag-sdk-browser 1.58.0 → 1.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +230 -154
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -508,74 +508,6 @@
|
|
|
508
508
|
['US-VI', 'Virgin Islands, U.S.'],
|
|
509
509
|
]);
|
|
510
510
|
new Set([...isoCountries.keys(), ...usStates.keys()]);
|
|
511
|
-
/**
|
|
512
|
-
* ISO 3166-1 alpha-2 codes for EU member states (as of 2024)
|
|
513
|
-
*/
|
|
514
|
-
const EU_COUNTRY_CODES = new Set([
|
|
515
|
-
'AT', // Austria
|
|
516
|
-
'BE', // Belgium
|
|
517
|
-
'BG', // Bulgaria
|
|
518
|
-
'CY', // Cyprus
|
|
519
|
-
'CZ', // Czech Republic
|
|
520
|
-
'DE', // Germany
|
|
521
|
-
'DK', // Denmark
|
|
522
|
-
'EE', // Estonia
|
|
523
|
-
'ES', // Spain
|
|
524
|
-
'FI', // Finland
|
|
525
|
-
'FR', // France
|
|
526
|
-
'GR', // Greece
|
|
527
|
-
'HR', // Croatia
|
|
528
|
-
'HU', // Hungary
|
|
529
|
-
'IE', // Ireland
|
|
530
|
-
'IT', // Italy
|
|
531
|
-
'LT', // Lithuania
|
|
532
|
-
'LU', // Luxembourg
|
|
533
|
-
'LV', // Latvia
|
|
534
|
-
'MT', // Malta
|
|
535
|
-
'NL', // Netherlands
|
|
536
|
-
'PL', // Poland
|
|
537
|
-
'PT', // Portugal
|
|
538
|
-
'RO', // Romania
|
|
539
|
-
'SE', // Sweden
|
|
540
|
-
'SI', // Slovenia
|
|
541
|
-
'SK', // Slovakia
|
|
542
|
-
]);
|
|
543
|
-
/**
|
|
544
|
-
* Returns true if the request originates from the EU or the UK (GB).
|
|
545
|
-
* Cloudflare's isEUCountry flag excludes the UK post-Brexit, so GB is
|
|
546
|
-
* checked explicitly alongside the EU member set.
|
|
547
|
-
*
|
|
548
|
-
* Fails closed: when the country cannot be resolved, the request is treated
|
|
549
|
-
* as EU/UK. This is the safe default for the compliance-sensitive Grey Switch
|
|
550
|
-
* (an unknown visitor may be in the EU/UK, so it must not slip through when
|
|
551
|
-
* the EU/UK toggle is off).
|
|
552
|
-
*/
|
|
553
|
-
const isEuUkRegion = (country, isEURequest) => {
|
|
554
|
-
if (isEURequest) {
|
|
555
|
-
return true;
|
|
556
|
-
}
|
|
557
|
-
if (!country) {
|
|
558
|
-
return true;
|
|
559
|
-
}
|
|
560
|
-
const upper = country.toUpperCase();
|
|
561
|
-
return upper === 'GB' || EU_COUNTRY_CODES.has(upper);
|
|
562
|
-
};
|
|
563
|
-
/**
|
|
564
|
-
* Grey Switch fire rule, shared by the SDK and the CDN worker so both stay in
|
|
565
|
-
* sync. When Grey Switch is on, EdgeTag fires server-side events for
|
|
566
|
-
* non-consented users. The EU/UK toggle is off by default, which keeps EU/UK
|
|
567
|
-
* visitors on normal consent unless the merchant explicitly opts those regions
|
|
568
|
-
* in. Returns whether a server-side event should fire for a non-consented user.
|
|
569
|
-
*/
|
|
570
|
-
const greySwitchAllowsServerEvent = ({ greySwitch, greySwitchEuUk, country, isEURequest, }) => {
|
|
571
|
-
if (!greySwitch) {
|
|
572
|
-
return false;
|
|
573
|
-
}
|
|
574
|
-
if (greySwitchEuUk) {
|
|
575
|
-
return true;
|
|
576
|
-
}
|
|
577
|
-
return !isEuUkRegion(country, isEURequest);
|
|
578
|
-
};
|
|
579
511
|
const parseCache = new Map();
|
|
580
512
|
const parseRegions = (regionString) => {
|
|
581
513
|
const include = new Set();
|
|
@@ -1539,7 +1471,7 @@
|
|
|
1539
1471
|
referrer: getReferrer(destination),
|
|
1540
1472
|
search: getSearch(destination),
|
|
1541
1473
|
locale: getLocale(),
|
|
1542
|
-
sdkVersion: "1.
|
|
1474
|
+
sdkVersion: "1.59.0" ,
|
|
1543
1475
|
...(payload || {}),
|
|
1544
1476
|
};
|
|
1545
1477
|
let storage = {};
|
|
@@ -1727,6 +1659,72 @@
|
|
|
1727
1659
|
}
|
|
1728
1660
|
postRequest(getTagURL(destination, eventName, options), payload, options).catch(logger.error);
|
|
1729
1661
|
};
|
|
1662
|
+
// Scope (scripts/providers allow-lists) is delivered per plugin via /init, keyed
|
|
1663
|
+
// by the plugin's identity `${providerId}||${name}` (which is carried in the
|
|
1664
|
+
// plugin object's `name`). A missing scope means the plugin is global.
|
|
1665
|
+
//
|
|
1666
|
+
// Mirrors the edge getAllowedPlugins per-item logic: at instance level the
|
|
1667
|
+
// scripts allow-list wins, otherwise fall back to the providers allow-list.
|
|
1668
|
+
const isPluginAllowed = (scope, providerId, instanceName) => {
|
|
1669
|
+
if (!scope) {
|
|
1670
|
+
return true;
|
|
1671
|
+
}
|
|
1672
|
+
if (instanceName && scope.scripts.length > 0) {
|
|
1673
|
+
return scope.scripts.includes(`${providerId}||${instanceName}`);
|
|
1674
|
+
}
|
|
1675
|
+
return scope.providers.length === 0 || scope.providers.includes(providerId);
|
|
1676
|
+
};
|
|
1677
|
+
// Mirrors the edge processPluginsRoot skip scope: a global plugin (no scope)
|
|
1678
|
+
// skips every browser instance (null), a scoped plugin skips only the instances
|
|
1679
|
+
// its scripts/providers allow-lists resolve to.
|
|
1680
|
+
const getScopedPluginSkipKeys = (scope, configuredTags) => {
|
|
1681
|
+
if (!scope || (scope.scripts.length === 0 && scope.providers.length === 0)) {
|
|
1682
|
+
return null;
|
|
1683
|
+
}
|
|
1684
|
+
const result = new Set();
|
|
1685
|
+
for (const script of scope.scripts) {
|
|
1686
|
+
result.add(script);
|
|
1687
|
+
}
|
|
1688
|
+
for (const providerId of scope.providers) {
|
|
1689
|
+
const instances = configuredTags.get(providerId);
|
|
1690
|
+
if (!instances)
|
|
1691
|
+
continue;
|
|
1692
|
+
for (const instanceName of instances) {
|
|
1693
|
+
result.add(`${providerId}||${instanceName}`);
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
return result;
|
|
1697
|
+
};
|
|
1698
|
+
// Mirrors the edge getProviderLimits: an additional event emitted by a scoped
|
|
1699
|
+
// plugin is restricted to that plugin's channels/instances; a global plugin
|
|
1700
|
+
// imposes no restriction (undefined).
|
|
1701
|
+
const getPluginProviderLimits = (scope) => {
|
|
1702
|
+
if (!scope || (scope.scripts.length === 0 && scope.providers.length === 0)) {
|
|
1703
|
+
return undefined;
|
|
1704
|
+
}
|
|
1705
|
+
const limited = {};
|
|
1706
|
+
for (const script of scope.scripts) {
|
|
1707
|
+
const separator = script.indexOf('||');
|
|
1708
|
+
if (separator === -1) {
|
|
1709
|
+
continue;
|
|
1710
|
+
}
|
|
1711
|
+
const provider = script.slice(0, separator);
|
|
1712
|
+
const instance = script.slice(separator + 2);
|
|
1713
|
+
const existing = limited[provider];
|
|
1714
|
+
if (existing && existing !== true) {
|
|
1715
|
+
existing[instance] = true;
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
limited[provider] = { [instance]: true };
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
for (const provider of scope.providers) {
|
|
1722
|
+
if (!(provider in limited)) {
|
|
1723
|
+
limited[provider] = true;
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
return limited;
|
|
1727
|
+
};
|
|
1730
1728
|
const getPlugins = (destination) => {
|
|
1731
1729
|
var _a, _b, _c;
|
|
1732
1730
|
try {
|
|
@@ -1737,7 +1735,19 @@
|
|
|
1737
1735
|
return [];
|
|
1738
1736
|
}
|
|
1739
1737
|
};
|
|
1740
|
-
|
|
1738
|
+
// Dispatches a plugin's additional events. Mirrors the edge: each event is
|
|
1739
|
+
// stamped with the emitting plugin (so it cannot reprocess itself) and limited
|
|
1740
|
+
// to that plugin's scope.
|
|
1741
|
+
const dispatchAdditionalEvents = (plugin, pluginScopes, events) => {
|
|
1742
|
+
const providerLimits = getPluginProviderLimits(pluginScopes === null || pluginScopes === void 0 ? void 0 : pluginScopes[plugin.name]);
|
|
1743
|
+
for (const evt of events) {
|
|
1744
|
+
handleTag(evt.eventName, evt.data, providerLimits, undefined, plugin.name);
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
// Runs a channel/instance hook chain. The emitting plugin is excluded by the
|
|
1748
|
+
// caller's allow-list filter; additional events fire before any skip is applied
|
|
1749
|
+
// (matching the edge), and a skip is reported without mutating the final tag.
|
|
1750
|
+
const runPluginHook = async (plugins, hookName, pluginScopes, baseParams) => {
|
|
1741
1751
|
var _a, _b;
|
|
1742
1752
|
const payload = baseParams['payload'];
|
|
1743
1753
|
let currentEventName = payload['eventName'];
|
|
@@ -1758,6 +1768,9 @@
|
|
|
1758
1768
|
},
|
|
1759
1769
|
variables: plugin.variables || {},
|
|
1760
1770
|
});
|
|
1771
|
+
if (result === null || result === void 0 ? void 0 : result.additionalEvents) {
|
|
1772
|
+
dispatchAdditionalEvents(plugin, pluginScopes, result.additionalEvents);
|
|
1773
|
+
}
|
|
1761
1774
|
if (result === null || result === void 0 ? void 0 : result.skipEvent) {
|
|
1762
1775
|
skip = true;
|
|
1763
1776
|
break;
|
|
@@ -1771,24 +1784,87 @@
|
|
|
1771
1784
|
if ((result === null || result === void 0 ? void 0 : result.providers) !== undefined) {
|
|
1772
1785
|
currentProviders = result.providers;
|
|
1773
1786
|
}
|
|
1787
|
+
}
|
|
1788
|
+
catch (e) {
|
|
1789
|
+
logger.error(`Plugin ${plugin.name} ${hookName} error: ${e}`);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
return {
|
|
1793
|
+
eventName: currentEventName,
|
|
1794
|
+
data: currentData,
|
|
1795
|
+
providers: currentProviders,
|
|
1796
|
+
skip,
|
|
1797
|
+
};
|
|
1798
|
+
};
|
|
1799
|
+
// Root hooks mirror the edge processPluginsRoot: every plugin runs (except the
|
|
1800
|
+
// one that emitted this event), additional events are dispatched before any
|
|
1801
|
+
// skip is applied, and skips are scoped — a global plugin marks every browser
|
|
1802
|
+
// instance, a scoped one only its resolved instances. The skip is a marker:
|
|
1803
|
+
// channel/instance hooks still run and only the final tag is suppressed.
|
|
1804
|
+
const runRootPluginHooks = async (plugins, baseParams, pluginScopes, configuredTags, pluginSource) => {
|
|
1805
|
+
var _a, _b;
|
|
1806
|
+
const payload = baseParams['payload'];
|
|
1807
|
+
let currentEventName = payload['eventName'];
|
|
1808
|
+
let currentData = payload['data'];
|
|
1809
|
+
let currentProviders = baseParams['providers'];
|
|
1810
|
+
const skippedInstances = new Set();
|
|
1811
|
+
for (const plugin of plugins) {
|
|
1812
|
+
if (plugin.name === pluginSource)
|
|
1813
|
+
continue;
|
|
1814
|
+
const hook = plugin.rules.tagRoot;
|
|
1815
|
+
if (!hook)
|
|
1816
|
+
continue;
|
|
1817
|
+
try {
|
|
1818
|
+
const result = await hook({
|
|
1819
|
+
...baseParams,
|
|
1820
|
+
payload: {
|
|
1821
|
+
...payload,
|
|
1822
|
+
eventName: currentEventName,
|
|
1823
|
+
data: jsonClone(currentData),
|
|
1824
|
+
},
|
|
1825
|
+
variables: plugin.variables || {},
|
|
1826
|
+
});
|
|
1774
1827
|
if (result === null || result === void 0 ? void 0 : result.additionalEvents) {
|
|
1775
|
-
|
|
1776
|
-
|
|
1828
|
+
dispatchAdditionalEvents(plugin, pluginScopes, result.additionalEvents);
|
|
1829
|
+
}
|
|
1830
|
+
if (result === null || result === void 0 ? void 0 : result.skipEvent) {
|
|
1831
|
+
const scopeSkipKeys = getScopedPluginSkipKeys(pluginScopes === null || pluginScopes === void 0 ? void 0 : pluginScopes[plugin.name], configuredTags);
|
|
1832
|
+
if (scopeSkipKeys === null) {
|
|
1833
|
+
// Global plugin: skip every configured browser instance.
|
|
1834
|
+
for (const [provider, instances] of configuredTags) {
|
|
1835
|
+
for (const instanceName of instances) {
|
|
1836
|
+
skippedInstances.add(`${provider}||${instanceName}`);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1777
1839
|
}
|
|
1840
|
+
else {
|
|
1841
|
+
for (const key of scopeSkipKeys) {
|
|
1842
|
+
skippedInstances.add(key);
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
if ((_a = result === null || result === void 0 ? void 0 : result.payload) === null || _a === void 0 ? void 0 : _a.eventName) {
|
|
1847
|
+
currentEventName = result.payload.eventName;
|
|
1848
|
+
}
|
|
1849
|
+
if ((_b = result === null || result === void 0 ? void 0 : result.payload) === null || _b === void 0 ? void 0 : _b.data) {
|
|
1850
|
+
currentData = result.payload.data;
|
|
1851
|
+
}
|
|
1852
|
+
if ((result === null || result === void 0 ? void 0 : result.providers) !== undefined) {
|
|
1853
|
+
currentProviders = result.providers;
|
|
1778
1854
|
}
|
|
1779
1855
|
}
|
|
1780
1856
|
catch (e) {
|
|
1781
|
-
logger.error(`Plugin ${plugin.name}
|
|
1857
|
+
logger.error(`Plugin ${plugin.name} tagRoot error: ${e}`);
|
|
1782
1858
|
}
|
|
1783
1859
|
}
|
|
1784
1860
|
return {
|
|
1785
1861
|
eventName: currentEventName,
|
|
1786
1862
|
data: currentData,
|
|
1787
1863
|
providers: currentProviders,
|
|
1788
|
-
|
|
1864
|
+
skippedInstances,
|
|
1789
1865
|
};
|
|
1790
1866
|
};
|
|
1791
|
-
const processTag = async (destination, eventName, data = {}, providers, options) => {
|
|
1867
|
+
const processTag = async (destination, eventName, data = {}, providers, options, pluginSource) => {
|
|
1792
1868
|
var _a, _b;
|
|
1793
1869
|
let currentEventName = eventName;
|
|
1794
1870
|
if (!getSetting(destination, 'initialized')) {
|
|
@@ -1815,15 +1891,6 @@
|
|
|
1815
1891
|
const consentCategory = getConsentCategories(destination);
|
|
1816
1892
|
const consentSettings = getSetting(destination, 'consentSetting');
|
|
1817
1893
|
const userConsent = { consentChannel, consentCategory, consentSettings };
|
|
1818
|
-
// Grey Switch: when enabled, still send the event to the server for
|
|
1819
|
-
// non-consented users. Browser pixels remain gated by hasUserConsent below,
|
|
1820
|
-
// so nothing fires client-side.
|
|
1821
|
-
const greySwitchAllows = greySwitchAllowsServerEvent({
|
|
1822
|
-
greySwitch: getSetting(destination, 'greySwitch') || false,
|
|
1823
|
-
greySwitchEuUk: getSetting(destination, 'greySwitchEuUk') || false,
|
|
1824
|
-
country: requestCountry,
|
|
1825
|
-
isEURequest,
|
|
1826
|
-
});
|
|
1827
1894
|
const ip = getSetting(destination, 'ip') || null;
|
|
1828
1895
|
const userProperties = getSetting(destination, 'userProperties');
|
|
1829
1896
|
if (skipZeroPurchaseEvent && isZeroPurchaseEvent({ eventName, data })) {
|
|
@@ -1844,6 +1911,7 @@
|
|
|
1844
1911
|
providers = rulesResult.updatedProviders;
|
|
1845
1912
|
}
|
|
1846
1913
|
const plugins = getPlugins(destination);
|
|
1914
|
+
const pluginScopes = getSetting(destination, 'pluginScopes');
|
|
1847
1915
|
const pluginSettings = {
|
|
1848
1916
|
userId,
|
|
1849
1917
|
sessionId,
|
|
@@ -1859,26 +1927,15 @@
|
|
|
1859
1927
|
const pluginUtilities = {
|
|
1860
1928
|
getIsNewCustomerFlag: () => getIsNewCustomerFlag(processGetData.bind(null, destination)),
|
|
1861
1929
|
};
|
|
1930
|
+
let rootSkippedInstances = new Set();
|
|
1862
1931
|
if (plugins.length > 0) {
|
|
1863
|
-
const rootResult = await
|
|
1932
|
+
const rootResult = await runRootPluginHooks(plugins, {
|
|
1864
1933
|
payload: { eventName: currentEventName, data, eventId },
|
|
1865
1934
|
context: pluginContext,
|
|
1866
1935
|
providers,
|
|
1867
1936
|
settings: pluginSettings,
|
|
1868
1937
|
utilities: pluginUtilities,
|
|
1869
|
-
});
|
|
1870
|
-
if (rootResult.skip) {
|
|
1871
|
-
sendTag(destination, {
|
|
1872
|
-
configuratorProcessed: true,
|
|
1873
|
-
eventName: currentEventName,
|
|
1874
|
-
eventId,
|
|
1875
|
-
data,
|
|
1876
|
-
providerData: {},
|
|
1877
|
-
providers,
|
|
1878
|
-
options,
|
|
1879
|
-
});
|
|
1880
|
-
return;
|
|
1881
|
-
}
|
|
1938
|
+
}, pluginScopes, configuredTags, pluginSource);
|
|
1882
1939
|
if (rootResult.providers !== undefined) {
|
|
1883
1940
|
// eslint-disable-next-line no-param-reassign
|
|
1884
1941
|
providers = rootResult.providers;
|
|
@@ -1886,6 +1943,7 @@
|
|
|
1886
1943
|
currentEventName = rootResult.eventName;
|
|
1887
1944
|
// eslint-disable-next-line no-param-reassign
|
|
1888
1945
|
data = rootResult.data;
|
|
1946
|
+
rootSkippedInstances = rootResult.skippedInstances;
|
|
1889
1947
|
}
|
|
1890
1948
|
if (!rulesResult.skipBrowserEvent) {
|
|
1891
1949
|
const currencySettings = getSetting(destination, 'currency');
|
|
@@ -1897,69 +1955,96 @@
|
|
|
1897
1955
|
logger.log(`Provider ${pkg.name} is not in allow list`);
|
|
1898
1956
|
continue;
|
|
1899
1957
|
}
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
providerId: pkg.name,
|
|
1912
|
-
utilities: pluginUtilities,
|
|
1958
|
+
const providerId = pkg.name;
|
|
1959
|
+
const variables = getProviderVariables(destination, pkg.name);
|
|
1960
|
+
// Per-instance state, mirroring the edge PluginData array: each instance
|
|
1961
|
+
// carries its own payload and skip marker (seeded from the root skip
|
|
1962
|
+
// scope). A skip never short-circuits the hooks — only the final tag.
|
|
1963
|
+
const instanceStates = new Map();
|
|
1964
|
+
for (const variable of variables) {
|
|
1965
|
+
instanceStates.set(variable.tagName, {
|
|
1966
|
+
eventName: currentEventName,
|
|
1967
|
+
data,
|
|
1968
|
+
skipped: rootSkippedInstances.has(`${providerId}||${variable.tagName}`),
|
|
1913
1969
|
});
|
|
1914
|
-
if (channelResult.skip)
|
|
1915
|
-
continue;
|
|
1916
|
-
providerEventName = channelResult.eventName;
|
|
1917
|
-
channelData = channelResult.data;
|
|
1918
1970
|
}
|
|
1919
|
-
|
|
1971
|
+
// Channel phase (processPluginsChannel): tagChannel runs once per
|
|
1972
|
+
// instance, regardless of skip/consent/geo, so its side effects and
|
|
1973
|
+
// additional events still fire on skipped instances.
|
|
1974
|
+
const channelPlugins = plugins.filter((plugin) => plugin.name !== pluginSource &&
|
|
1975
|
+
isPluginAllowed(pluginScopes === null || pluginScopes === void 0 ? void 0 : pluginScopes[plugin.name], providerId, null));
|
|
1976
|
+
if (channelPlugins.length > 0) {
|
|
1977
|
+
for (const variable of variables) {
|
|
1978
|
+
const state = instanceStates.get(variable.tagName);
|
|
1979
|
+
const channelResult = await runPluginHook(channelPlugins, 'tagChannel', pluginScopes, {
|
|
1980
|
+
payload: {
|
|
1981
|
+
eventName: state.eventName,
|
|
1982
|
+
data: state.data,
|
|
1983
|
+
eventId,
|
|
1984
|
+
},
|
|
1985
|
+
context: pluginContext,
|
|
1986
|
+
settings: pluginSettings,
|
|
1987
|
+
providerId,
|
|
1988
|
+
utilities: pluginUtilities,
|
|
1989
|
+
});
|
|
1990
|
+
if (channelResult.skip) {
|
|
1991
|
+
state.skipped = true;
|
|
1992
|
+
}
|
|
1993
|
+
state.eventName = channelResult.eventName;
|
|
1994
|
+
state.data = channelResult.data;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
// Instance phase (processPluginsInstance + tag send): consent/geo gate,
|
|
1998
|
+
// run tagInstance, then suppress only the final tag when skipped.
|
|
1920
1999
|
const result = {};
|
|
1921
2000
|
const executionContext = new Map();
|
|
1922
2001
|
for (const variable of variables) {
|
|
1923
|
-
|
|
1924
|
-
|
|
2002
|
+
const state = instanceStates.get(variable.tagName);
|
|
2003
|
+
if (!isProviderInstanceAllowed(providers, providerId, variable.tagName)) {
|
|
2004
|
+
logger.log(`Provider instance is not allowed (${providerId}: ${variable.tagName})`);
|
|
1925
2005
|
continue;
|
|
1926
2006
|
}
|
|
1927
|
-
if (!hasUserConsent(userConsent,
|
|
1928
|
-
logger.log(`Consent is missing (${
|
|
2007
|
+
if (!hasUserConsent(userConsent, providerId, variable.tagName)) {
|
|
2008
|
+
logger.log(`Consent is missing (${providerId}: ${variable.tagName})`);
|
|
1929
2009
|
continue;
|
|
1930
2010
|
}
|
|
1931
2011
|
if (!doesGeoRequestMatchList(requestCountry, requestRegion, isEURequest, variable.geoRegions)) {
|
|
1932
2012
|
logger.log('GEO request region does not match the filter, skipping');
|
|
1933
2013
|
continue;
|
|
1934
2014
|
}
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
if (
|
|
1938
|
-
const instanceResult = await runPluginHook(
|
|
2015
|
+
const instancePlugins = plugins.filter((plugin) => plugin.name !== pluginSource &&
|
|
2016
|
+
isPluginAllowed(pluginScopes === null || pluginScopes === void 0 ? void 0 : pluginScopes[plugin.name], providerId, variable.tagName));
|
|
2017
|
+
if (instancePlugins.length > 0) {
|
|
2018
|
+
const instanceResult = await runPluginHook(instancePlugins, 'tagInstance', pluginScopes, {
|
|
1939
2019
|
payload: {
|
|
1940
|
-
eventName:
|
|
1941
|
-
data:
|
|
2020
|
+
eventName: state.eventName,
|
|
2021
|
+
data: state.data,
|
|
1942
2022
|
eventId,
|
|
1943
2023
|
},
|
|
1944
2024
|
context: pluginContext,
|
|
1945
2025
|
settings: pluginSettings,
|
|
1946
|
-
providerId
|
|
2026
|
+
providerId,
|
|
1947
2027
|
utilities: pluginUtilities,
|
|
1948
2028
|
});
|
|
1949
|
-
if (instanceResult.skip)
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
2029
|
+
if (instanceResult.skip) {
|
|
2030
|
+
state.skipped = true;
|
|
2031
|
+
}
|
|
2032
|
+
state.eventName = instanceResult.eventName;
|
|
2033
|
+
state.data = instanceResult.data;
|
|
2034
|
+
}
|
|
2035
|
+
if (state.skipped) {
|
|
2036
|
+
logger.log(`Skipping event due to plugin condition (${providerId}: ${variable.tagName})`);
|
|
2037
|
+
continue;
|
|
1953
2038
|
}
|
|
1954
|
-
const conversion = preparePayloadWithConversion(jsonClone(
|
|
2039
|
+
const conversion = preparePayloadWithConversion(jsonClone(state.data), currencySettings);
|
|
1955
2040
|
const payload = ((_a = conversion === null || conversion === void 0 ? void 0 : conversion.providers) === null || _a === void 0 ? void 0 : _a.length) === 0 ||
|
|
1956
|
-
((_b = conversion === null || conversion === void 0 ? void 0 : conversion.providers) === null || _b === void 0 ? void 0 : _b.includes(
|
|
2041
|
+
((_b = conversion === null || conversion === void 0 ? void 0 : conversion.providers) === null || _b === void 0 ? void 0 : _b.includes(providerId))
|
|
1957
2042
|
? conversion.payload
|
|
1958
|
-
:
|
|
2043
|
+
: state.data;
|
|
1959
2044
|
result[variable.tagName] = pkg.tag({
|
|
1960
2045
|
userId,
|
|
1961
2046
|
sessionId,
|
|
1962
|
-
eventName:
|
|
2047
|
+
eventName: state.eventName,
|
|
1963
2048
|
eventId,
|
|
1964
2049
|
data: jsonClone(payload),
|
|
1965
2050
|
sendTag: sendTag.bind(null, destination),
|
|
@@ -1974,16 +2059,17 @@
|
|
|
1974
2059
|
pageUrl: getPageUrl(destination),
|
|
1975
2060
|
});
|
|
1976
2061
|
}
|
|
1977
|
-
|
|
2062
|
+
if (Object.keys(result).length > 0) {
|
|
2063
|
+
providerData[providerId] = result;
|
|
2064
|
+
}
|
|
1978
2065
|
}
|
|
1979
2066
|
}
|
|
1980
2067
|
else {
|
|
1981
2068
|
logger.log('Browser events skipped by event rules, sending tag to server only');
|
|
1982
2069
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
}
|
|
2070
|
+
// The server event is always forwarded to EdgeTag regardless of consent or
|
|
2071
|
+
// provider config; the CDN re-runs this logic server-side. Browser tags are
|
|
2072
|
+
// still individually gated by consent/geo/provider above.
|
|
1987
2073
|
sendTag(destination, {
|
|
1988
2074
|
configuratorProcessed: true,
|
|
1989
2075
|
eventName: currentEventName,
|
|
@@ -2002,26 +2088,15 @@
|
|
|
2002
2088
|
handleTag(additionalEventName, jsonClone(originalData || {}), originalProviders, options);
|
|
2003
2089
|
}
|
|
2004
2090
|
};
|
|
2005
|
-
const handleTag = (eventName, data = {}, providers, options) => {
|
|
2091
|
+
const handleTag = (eventName, data = {}, providers, options, pluginSource) => {
|
|
2006
2092
|
if (options === null || options === void 0 ? void 0 : options.destination) {
|
|
2007
|
-
processTag(options.destination, eventName, data, providers, options).catch(logger.error);
|
|
2093
|
+
processTag(options.destination, eventName, data, providers, options, pluginSource).catch(logger.error);
|
|
2008
2094
|
return;
|
|
2009
2095
|
}
|
|
2010
2096
|
getInstances().forEach((instance) => {
|
|
2011
|
-
processTag(instance, eventName, data, providers, options).catch(logger.error);
|
|
2097
|
+
processTag(instance, eventName, data, providers, options, pluginSource).catch(logger.error);
|
|
2012
2098
|
});
|
|
2013
2099
|
};
|
|
2014
|
-
const hasAllowedManifestTags = (tags, consent, providersConfig) => {
|
|
2015
|
-
for (const [pkg, tagNames] of tags) {
|
|
2016
|
-
for (const tagName of tagNames) {
|
|
2017
|
-
if (hasUserConsent(consent, pkg, tagName) &&
|
|
2018
|
-
isProviderInstanceAllowed(providersConfig, pkg, tagName)) {
|
|
2019
|
-
return true;
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
}
|
|
2023
|
-
return false;
|
|
2024
|
-
};
|
|
2025
2100
|
|
|
2026
2101
|
const processData = (destination, data, providers, options) => {
|
|
2027
2102
|
saveKV(destination, data);
|
|
@@ -2561,6 +2636,7 @@
|
|
|
2561
2636
|
configuratorSetting: result.configuratorSetting,
|
|
2562
2637
|
userProperties: result.userProperties,
|
|
2563
2638
|
ip: result.ip,
|
|
2639
|
+
pluginScopes: result.pluginScopes,
|
|
2564
2640
|
});
|
|
2565
2641
|
if (result.storageId != null) {
|
|
2566
2642
|
savePerKey(preferences.edgeURL, 'local', tagStorage, result.storageId, storageIdKey);
|