@blotoutio/edgetag-sdk-browser 1.73.0 → 1.74.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.js +217 -167
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1498,7 +1498,7 @@
|
|
|
1498
1498
|
referrer: getReferrer(destination),
|
|
1499
1499
|
search: getSearch(destination),
|
|
1500
1500
|
locale: getLocale(),
|
|
1501
|
-
sdkVersion: "1.
|
|
1501
|
+
sdkVersion: "1.74.1" ,
|
|
1502
1502
|
...(payload || {}),
|
|
1503
1503
|
};
|
|
1504
1504
|
let storage = {};
|
|
@@ -1620,6 +1620,216 @@
|
|
|
1620
1620
|
});
|
|
1621
1621
|
};
|
|
1622
1622
|
|
|
1623
|
+
const processData = (destination, data, providers, options) => {
|
|
1624
|
+
saveKV(destination, data);
|
|
1625
|
+
updateUserProperties(destination, data);
|
|
1626
|
+
const providerPackages = getSetting(destination, 'browserPackages');
|
|
1627
|
+
const configuredTags = getSetting(destination, 'channels');
|
|
1628
|
+
const userId = getUserId$1(destination);
|
|
1629
|
+
const requestCountry = getSetting(destination, 'geoCountry') || null;
|
|
1630
|
+
const requestRegion = getSetting(destination, 'geoRegion') || null;
|
|
1631
|
+
const isEURequest = getSetting(destination, 'isEURequest') || false;
|
|
1632
|
+
const consentChannel = getConsent$1(destination);
|
|
1633
|
+
const consentCategory = getConsentCategories(destination);
|
|
1634
|
+
const consentSettings = getSetting(destination, 'consentSetting');
|
|
1635
|
+
const userConsent = { consentChannel, consentCategory, consentSettings };
|
|
1636
|
+
for (const pkg of providerPackages) {
|
|
1637
|
+
if (!pkg || !pkg.user || !pkg.name) {
|
|
1638
|
+
continue;
|
|
1639
|
+
}
|
|
1640
|
+
if (!configuredTags.has(pkg.name)) {
|
|
1641
|
+
logger.log(`Provider ${pkg.name} is not in allow list`);
|
|
1642
|
+
continue;
|
|
1643
|
+
}
|
|
1644
|
+
const variables = getProviderVariables(destination, pkg.name);
|
|
1645
|
+
for (const variable of variables) {
|
|
1646
|
+
if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
|
|
1647
|
+
logger.log(`Data not allowed for ${pkg.name} (${variable.tagName})`);
|
|
1648
|
+
continue;
|
|
1649
|
+
}
|
|
1650
|
+
if (!hasUserConsent(userConsent, pkg.name, variable.tagName)) {
|
|
1651
|
+
logger.log(`Consent is missing for ${pkg.name} (${variable.tagName})`);
|
|
1652
|
+
continue;
|
|
1653
|
+
}
|
|
1654
|
+
if (!doesGeoRequestMatchList(requestCountry, requestRegion, isEURequest, variable.geoRegions)) {
|
|
1655
|
+
logger.log(`GEO request region does not match list, skipping`);
|
|
1656
|
+
continue;
|
|
1657
|
+
}
|
|
1658
|
+
pkg.user({
|
|
1659
|
+
userId,
|
|
1660
|
+
data,
|
|
1661
|
+
manifestVariables: variable.variableSet,
|
|
1662
|
+
destination,
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
postRequest(getDataURL(destination), { data, providers }, options).catch(logger.error);
|
|
1667
|
+
};
|
|
1668
|
+
const handleData = (data, providers, options) => {
|
|
1669
|
+
if (!data || Object.keys(data).length === 0) {
|
|
1670
|
+
logger.error('Provide data for data API.');
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
if (options === null || options === void 0 ? void 0 : options.destination) {
|
|
1674
|
+
processData(options.destination, data, providers, options);
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
getInstances().forEach((destination) => {
|
|
1678
|
+
processData(destination, data, providers, options);
|
|
1679
|
+
});
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
const cacheKey = `${keyPrefix}Cache`;
|
|
1683
|
+
const identity = (v) => v;
|
|
1684
|
+
const saveDataToEdge = (destination, key, value, provider) => {
|
|
1685
|
+
if (!value) {
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
let updatedValue = value;
|
|
1689
|
+
if (typeof value !== 'string') {
|
|
1690
|
+
try {
|
|
1691
|
+
updatedValue = JSON.stringify(value);
|
|
1692
|
+
}
|
|
1693
|
+
catch {
|
|
1694
|
+
logger.log('Error stringify value.');
|
|
1695
|
+
return;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
handleData({ [`${provider}::${key}`]: updatedValue }, undefined, {
|
|
1699
|
+
destination,
|
|
1700
|
+
});
|
|
1701
|
+
};
|
|
1702
|
+
const handleCaptureQuery = (destination, provider, key, persistType, map) => {
|
|
1703
|
+
try {
|
|
1704
|
+
if (!window) {
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
catch {
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
const params = new URLSearchParams(getSearch(destination));
|
|
1712
|
+
if (!params || !params.get(key)) {
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
const data = (map !== null && map !== void 0 ? map : identity)(params.get(key));
|
|
1716
|
+
if (!data) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
if (persistType === 'edge') {
|
|
1720
|
+
saveDataToEdge(destination, key, data, provider);
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1723
|
+
saveDataPerKey(destination, persistType, provider, data, key);
|
|
1724
|
+
};
|
|
1725
|
+
const getFromCache = (destination, persistType, provider, key) => {
|
|
1726
|
+
var _a;
|
|
1727
|
+
const type = persistType === 'edge' ? 'local' : persistType;
|
|
1728
|
+
const cache = getData$1(destination, type, cacheKey);
|
|
1729
|
+
return (_a = cache[provider]) === null || _a === void 0 ? void 0 : _a[key];
|
|
1730
|
+
};
|
|
1731
|
+
const saveToCache = (destination, persistType, provider, key, value) => {
|
|
1732
|
+
const type = persistType === 'edge' ? 'local' : persistType;
|
|
1733
|
+
const cache = getData$1(destination, type, cacheKey);
|
|
1734
|
+
if (!cache[provider]) {
|
|
1735
|
+
cache[provider] = { [key]: value };
|
|
1736
|
+
}
|
|
1737
|
+
else {
|
|
1738
|
+
cache[provider][key] = value;
|
|
1739
|
+
}
|
|
1740
|
+
saveData(destination, type, cache, cacheKey);
|
|
1741
|
+
};
|
|
1742
|
+
const handleCaptureStorage = (destination, provider, key, persistType, location, map, replay = false) => {
|
|
1743
|
+
let data;
|
|
1744
|
+
try {
|
|
1745
|
+
switch (location) {
|
|
1746
|
+
case 'cookie': {
|
|
1747
|
+
data = (map !== null && map !== void 0 ? map : identity)(getCookieValue(key));
|
|
1748
|
+
break;
|
|
1749
|
+
}
|
|
1750
|
+
case 'local': {
|
|
1751
|
+
data = (map !== null && map !== void 0 ? map : identity)(localStorage.getItem(key));
|
|
1752
|
+
break;
|
|
1753
|
+
}
|
|
1754
|
+
case 'session': {
|
|
1755
|
+
data = (map !== null && map !== void 0 ? map : identity)(sessionStorage.getItem(key));
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
catch {
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
if (!data) {
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
const cachedKey = `${getUserId$1(destination)}/${key}`;
|
|
1766
|
+
const cachedValue = getFromCache(destination, persistType, provider, cachedKey);
|
|
1767
|
+
if (persistType === 'edge' && cachedValue !== data) {
|
|
1768
|
+
saveDataToEdge(destination, key, data, provider);
|
|
1769
|
+
saveToCache(destination, persistType, provider, cachedKey, data);
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
// A cache hit means this rule's value has not moved since it was last
|
|
1773
|
+
// written, so a replay has nothing left to do: saveDataPerKey is a getItem +
|
|
1774
|
+
// JSON.parse + JSON.stringify + setItem, per storage rule, per event, on
|
|
1775
|
+
// every tag in the fleet that has one. The boot path always falls through, so
|
|
1776
|
+
// the value is written at least once per page.
|
|
1777
|
+
if (replay && cachedValue === data) {
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
saveDataPerKey(destination, persistType, provider, data, key);
|
|
1781
|
+
// Cached for every persist type, not just 'edge' — the guard above is what
|
|
1782
|
+
// keeps a non-edge rule (trade-desk's uc_tcf) off the read/parse/write cycle
|
|
1783
|
+
// on every event of the visit.
|
|
1784
|
+
saveToCache(destination, persistType, provider, cachedKey, data);
|
|
1785
|
+
};
|
|
1786
|
+
const registry = new Map();
|
|
1787
|
+
// A manifest pass is the authoritative provider set for the destination, and
|
|
1788
|
+
// handleCapture only replaces the entry for the provider it is called with.
|
|
1789
|
+
// Without this, a channel dropped from a later pass (SPA re-init, manifest
|
|
1790
|
+
// refresh, channel removed) keeps replaying its storage rules for the rest of
|
|
1791
|
+
// the page lifetime. handleManifest calls this once, before its provider loop.
|
|
1792
|
+
const resetCaptures = (destination) => {
|
|
1793
|
+
registry.delete(destination);
|
|
1794
|
+
};
|
|
1795
|
+
const handleCapture = (destination, provider, params, capture) => {
|
|
1796
|
+
var _a;
|
|
1797
|
+
const existing = ((_a = registry.get(destination)) !== null && _a !== void 0 ? _a : []).filter((registration) => registration.provider !== provider);
|
|
1798
|
+
registry.set(destination, [...existing, { provider, params, capture }]);
|
|
1799
|
+
params.forEach((param) => {
|
|
1800
|
+
switch (param.type) {
|
|
1801
|
+
case 'query': {
|
|
1802
|
+
handleCaptureQuery(destination, provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
|
|
1803
|
+
break;
|
|
1804
|
+
}
|
|
1805
|
+
case 'storage': {
|
|
1806
|
+
handleCaptureStorage(destination, provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
|
|
1807
|
+
break;
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
};
|
|
1812
|
+
// A storage capture rule reads a slot the provider's own pixel may not have
|
|
1813
|
+
// written yet: handleManifest calls handleCapture before pkg.init(), and
|
|
1814
|
+
// Customers.ai's pixel is injected async, so on a first visit the read always
|
|
1815
|
+
// loses. Re-read per event so a value that appears later is still captured for
|
|
1816
|
+
// that pageview.
|
|
1817
|
+
//
|
|
1818
|
+
// Opt-in per rule (`replay: true`) and storage rules only, so a provider pays
|
|
1819
|
+
// the per-event read only where a late-writing pixel makes the boot read
|
|
1820
|
+
// unreliable.
|
|
1821
|
+
const replayStorageCaptures = (destination) => {
|
|
1822
|
+
var _a;
|
|
1823
|
+
(_a = registry.get(destination)) === null || _a === void 0 ? void 0 : _a.forEach(({ provider, params, capture }) => {
|
|
1824
|
+
params.forEach((param) => {
|
|
1825
|
+
if (param.type !== 'storage' || !param.replay) {
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
handleCaptureStorage(destination, provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param), true);
|
|
1829
|
+
});
|
|
1830
|
+
});
|
|
1831
|
+
};
|
|
1832
|
+
|
|
1623
1833
|
const preparePayloadWithConversion = (payloadData, currencySettings) => {
|
|
1624
1834
|
const currency = payloadData['currency'];
|
|
1625
1835
|
if (!currency || !currencySettings) {
|
|
@@ -1943,6 +2153,9 @@
|
|
|
1943
2153
|
});
|
|
1944
2154
|
return;
|
|
1945
2155
|
}
|
|
2156
|
+
// Capture rules run once at boot, before the providers' own pixels load —
|
|
2157
|
+
// see replayStorageCaptures.
|
|
2158
|
+
replayStorageCaptures(destination);
|
|
1946
2159
|
let eventId = data['eventId'];
|
|
1947
2160
|
if (!eventId) {
|
|
1948
2161
|
eventId = generateEventId(currentEventName);
|
|
@@ -2177,65 +2390,6 @@
|
|
|
2177
2390
|
});
|
|
2178
2391
|
};
|
|
2179
2392
|
|
|
2180
|
-
const processData = (destination, data, providers, options) => {
|
|
2181
|
-
saveKV(destination, data);
|
|
2182
|
-
updateUserProperties(destination, data);
|
|
2183
|
-
const providerPackages = getSetting(destination, 'browserPackages');
|
|
2184
|
-
const configuredTags = getSetting(destination, 'channels');
|
|
2185
|
-
const userId = getUserId$1(destination);
|
|
2186
|
-
const requestCountry = getSetting(destination, 'geoCountry') || null;
|
|
2187
|
-
const requestRegion = getSetting(destination, 'geoRegion') || null;
|
|
2188
|
-
const isEURequest = getSetting(destination, 'isEURequest') || false;
|
|
2189
|
-
const consentChannel = getConsent$1(destination);
|
|
2190
|
-
const consentCategory = getConsentCategories(destination);
|
|
2191
|
-
const consentSettings = getSetting(destination, 'consentSetting');
|
|
2192
|
-
const userConsent = { consentChannel, consentCategory, consentSettings };
|
|
2193
|
-
for (const pkg of providerPackages) {
|
|
2194
|
-
if (!pkg || !pkg.user || !pkg.name) {
|
|
2195
|
-
continue;
|
|
2196
|
-
}
|
|
2197
|
-
if (!configuredTags.has(pkg.name)) {
|
|
2198
|
-
logger.log(`Provider ${pkg.name} is not in allow list`);
|
|
2199
|
-
continue;
|
|
2200
|
-
}
|
|
2201
|
-
const variables = getProviderVariables(destination, pkg.name);
|
|
2202
|
-
for (const variable of variables) {
|
|
2203
|
-
if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
|
|
2204
|
-
logger.log(`Data not allowed for ${pkg.name} (${variable.tagName})`);
|
|
2205
|
-
continue;
|
|
2206
|
-
}
|
|
2207
|
-
if (!hasUserConsent(userConsent, pkg.name, variable.tagName)) {
|
|
2208
|
-
logger.log(`Consent is missing for ${pkg.name} (${variable.tagName})`);
|
|
2209
|
-
continue;
|
|
2210
|
-
}
|
|
2211
|
-
if (!doesGeoRequestMatchList(requestCountry, requestRegion, isEURequest, variable.geoRegions)) {
|
|
2212
|
-
logger.log(`GEO request region does not match list, skipping`);
|
|
2213
|
-
continue;
|
|
2214
|
-
}
|
|
2215
|
-
pkg.user({
|
|
2216
|
-
userId,
|
|
2217
|
-
data,
|
|
2218
|
-
manifestVariables: variable.variableSet,
|
|
2219
|
-
destination,
|
|
2220
|
-
});
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
postRequest(getDataURL(destination), { data, providers }, options).catch(logger.error);
|
|
2224
|
-
};
|
|
2225
|
-
const handleData = (data, providers, options) => {
|
|
2226
|
-
if (!data || Object.keys(data).length === 0) {
|
|
2227
|
-
logger.error('Provide data for data API.');
|
|
2228
|
-
return;
|
|
2229
|
-
}
|
|
2230
|
-
if (options === null || options === void 0 ? void 0 : options.destination) {
|
|
2231
|
-
processData(options.destination, data, providers, options);
|
|
2232
|
-
return;
|
|
2233
|
-
}
|
|
2234
|
-
getInstances().forEach((destination) => {
|
|
2235
|
-
processData(destination, data, providers, options);
|
|
2236
|
-
});
|
|
2237
|
-
};
|
|
2238
|
-
|
|
2239
2393
|
const handleConsent = (consent, consentCategories, options) => {
|
|
2240
2394
|
if (options === null || options === void 0 ? void 0 : options.destination) {
|
|
2241
2395
|
processConsent(options.destination, consent, consentCategories, options);
|
|
@@ -2400,113 +2554,6 @@
|
|
|
2400
2554
|
return providersPackages;
|
|
2401
2555
|
};
|
|
2402
2556
|
|
|
2403
|
-
const cacheKey = `${keyPrefix}Cache`;
|
|
2404
|
-
const identity = (v) => v;
|
|
2405
|
-
const saveDataToEdge = (destination, key, value, provider) => {
|
|
2406
|
-
if (!value) {
|
|
2407
|
-
return;
|
|
2408
|
-
}
|
|
2409
|
-
let updatedValue = value;
|
|
2410
|
-
if (typeof value !== 'string') {
|
|
2411
|
-
try {
|
|
2412
|
-
updatedValue = JSON.stringify(value);
|
|
2413
|
-
}
|
|
2414
|
-
catch {
|
|
2415
|
-
logger.log('Error stringify value.');
|
|
2416
|
-
return;
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
handleData({ [`${provider}::${key}`]: updatedValue }, undefined, {
|
|
2420
|
-
destination,
|
|
2421
|
-
});
|
|
2422
|
-
};
|
|
2423
|
-
const handleCaptureQuery = (destination, provider, key, persistType, map) => {
|
|
2424
|
-
try {
|
|
2425
|
-
if (!window) {
|
|
2426
|
-
return;
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
catch {
|
|
2430
|
-
return;
|
|
2431
|
-
}
|
|
2432
|
-
const params = new URLSearchParams(getSearch(destination));
|
|
2433
|
-
if (!params || !params.get(key)) {
|
|
2434
|
-
return;
|
|
2435
|
-
}
|
|
2436
|
-
const data = (map !== null && map !== void 0 ? map : identity)(params.get(key));
|
|
2437
|
-
if (!data) {
|
|
2438
|
-
return;
|
|
2439
|
-
}
|
|
2440
|
-
if (persistType === 'edge') {
|
|
2441
|
-
saveDataToEdge(destination, key, data, provider);
|
|
2442
|
-
return;
|
|
2443
|
-
}
|
|
2444
|
-
saveDataPerKey(destination, persistType, provider, data, key);
|
|
2445
|
-
};
|
|
2446
|
-
const getFromCache = (destination, persistType, provider, key) => {
|
|
2447
|
-
var _a;
|
|
2448
|
-
const type = persistType === 'edge' ? 'local' : persistType;
|
|
2449
|
-
const cache = getData$1(destination, type, cacheKey);
|
|
2450
|
-
return (_a = cache[provider]) === null || _a === void 0 ? void 0 : _a[key];
|
|
2451
|
-
};
|
|
2452
|
-
const saveToCache = (destination, persistType, provider, key, value) => {
|
|
2453
|
-
const type = persistType === 'edge' ? 'local' : persistType;
|
|
2454
|
-
const cache = getData$1(destination, type, cacheKey);
|
|
2455
|
-
if (!cache[provider]) {
|
|
2456
|
-
cache[provider] = { [key]: value };
|
|
2457
|
-
}
|
|
2458
|
-
else {
|
|
2459
|
-
cache[provider][key] = value;
|
|
2460
|
-
}
|
|
2461
|
-
saveData(destination, type, cache, cacheKey);
|
|
2462
|
-
};
|
|
2463
|
-
const handleCaptureStorage = (destination, provider, key, persistType, location, map) => {
|
|
2464
|
-
let data;
|
|
2465
|
-
try {
|
|
2466
|
-
switch (location) {
|
|
2467
|
-
case 'cookie': {
|
|
2468
|
-
data = (map !== null && map !== void 0 ? map : identity)(getCookieValue(key));
|
|
2469
|
-
break;
|
|
2470
|
-
}
|
|
2471
|
-
case 'local': {
|
|
2472
|
-
data = (map !== null && map !== void 0 ? map : identity)(localStorage.getItem(key));
|
|
2473
|
-
break;
|
|
2474
|
-
}
|
|
2475
|
-
case 'session': {
|
|
2476
|
-
data = (map !== null && map !== void 0 ? map : identity)(sessionStorage.getItem(key));
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
catch {
|
|
2481
|
-
return;
|
|
2482
|
-
}
|
|
2483
|
-
if (!data) {
|
|
2484
|
-
return;
|
|
2485
|
-
}
|
|
2486
|
-
const cachedKey = `${getUserId$1(destination)}/${key}`;
|
|
2487
|
-
const cachedValue = getFromCache(destination, persistType, provider, cachedKey);
|
|
2488
|
-
if (persistType === 'edge' && cachedValue !== data) {
|
|
2489
|
-
saveDataToEdge(destination, key, data, provider);
|
|
2490
|
-
saveToCache(destination, persistType, provider, cachedKey, data);
|
|
2491
|
-
return;
|
|
2492
|
-
}
|
|
2493
|
-
saveDataPerKey(destination, persistType, provider, data, key);
|
|
2494
|
-
};
|
|
2495
|
-
const handleCapture = (destination, provider, params, capture) => {
|
|
2496
|
-
params.forEach((param) => {
|
|
2497
|
-
switch (param.type) {
|
|
2498
|
-
case 'query': {
|
|
2499
|
-
handleCaptureQuery(destination, provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
|
|
2500
|
-
break;
|
|
2501
|
-
}
|
|
2502
|
-
case 'storage': {
|
|
2503
|
-
handleCaptureStorage(destination, provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
|
|
2504
|
-
break;
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
});
|
|
2508
|
-
};
|
|
2509
|
-
|
|
2510
2557
|
const keyName = `${keyPrefix}Store`;
|
|
2511
2558
|
const handleManifest = (destination, response) => {
|
|
2512
2559
|
const providerPackages = getSetting(destination, 'browserPackages');
|
|
@@ -2517,6 +2564,9 @@
|
|
|
2517
2564
|
const consentCategory = getConsentCategories(destination);
|
|
2518
2565
|
const consentSettings = getSetting(destination, 'consentSetting');
|
|
2519
2566
|
const userConsent = { consentChannel, consentCategory, consentSettings };
|
|
2567
|
+
// This manifest is the full provider set: drop the previous pass's capture
|
|
2568
|
+
// registrations so a channel that is no longer in it stops replaying.
|
|
2569
|
+
resetCaptures(destination);
|
|
2520
2570
|
manifest.forEach((provider) => {
|
|
2521
2571
|
addChannel(destination, provider.package, provider.tagName);
|
|
2522
2572
|
const pkg = providerPackages.find((pkg) => pkg.name === provider.package);
|