diff --git a/integrationExamples/gpt/prebidServer_native_example.html b/integrationExamples/gpt/prebidServer_native_example.html
index c590f0bcee5..a5fb0ffa894 100644
--- a/integrationExamples/gpt/prebidServer_native_example.html
+++ b/integrationExamples/gpt/prebidServer_native_example.html
@@ -114,7 +114,7 @@
s2sConfig: {
accountId: '1',
enabled: true, //default value set to false
- bidders: ['appnexus'],
+ bidders: ['appnexuspsp'],
timeout: 1000, //default value is 1000
adapter: 'prebidServer', //if we have any other s2s adapter, default value is s2s
endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
diff --git a/integrationExamples/noadserver/native_noadserver.html b/integrationExamples/noadserver/native_noadserver.html
new file mode 100755
index 00000000000..81c71d2acfd
--- /dev/null
+++ b/integrationExamples/noadserver/native_noadserver.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ##hb_native_brand##
+
+
+
+
+
+Prebid Native
+
+
+
+
+
+
+
+
+
diff --git a/libraries/appnexusKeywords/anKeywords.js b/libraries/appnexusUtils/anKeywords.js
similarity index 91%
rename from libraries/appnexusKeywords/anKeywords.js
rename to libraries/appnexusUtils/anKeywords.js
index 5dc0b453253..d6714dacc21 100644
--- a/libraries/appnexusKeywords/anKeywords.js
+++ b/libraries/appnexusUtils/anKeywords.js
@@ -1,4 +1,4 @@
-import {_each, deepAccess, getValueString, isArray, isStr, mergeDeep, isNumber} from '../../src/utils.js';
+import {_each, deepAccess, isArray, isNumber, isStr, mergeDeep, logWarn} from '../../src/utils.js';
import {getAllOrtbKeywords} from '../keywords/keywords.js';
import {CLIENT_SECTIONS} from '../../src/fpd/oneClient.js';
@@ -12,6 +12,19 @@ const ORTB_SEG_PATHS = ['user.data'].concat(
CLIENT_SECTIONS.map((prefix) => `${prefix}.content.data`)
);
+function getValueString(param, val, defaultValue) {
+ if (val === undefined || val === null) {
+ return defaultValue;
+ }
+ if (isStr(val)) {
+ return val;
+ }
+ if (isNumber(val)) {
+ return val.toString();
+ }
+ logWarn('Unsuported type for param: ' + param + ' required type: String');
+}
+
/**
* Converts an object of arrays (either strings or numbers) into an array of objects containing key and value properties
* normally read from bidder params
diff --git a/libraries/appnexusUtils/anUtils.js b/libraries/appnexusUtils/anUtils.js
new file mode 100644
index 00000000000..9b55cd5c2a4
--- /dev/null
+++ b/libraries/appnexusUtils/anUtils.js
@@ -0,0 +1,25 @@
+/**
+ * Converts a string value in camel-case to underscore eg 'placementId' becomes 'placement_id'
+ * @param {string} value string value to convert
+ */
+import {deepClone, isPlainObject} from '../../src/utils.js';
+
+export function convertCamelToUnderscore(value) {
+ return value.replace(/(?:^|\.?)([A-Z])/g, function (x, y) {
+ return '_' + y.toLowerCase();
+ }).replace(/^_/, '');
+}
+
+/**
+ * Creates an array of n length and fills each item with the given value
+ */
+export function fill(value, length) {
+ let newArray = [];
+
+ for (let i = 0; i < length; i++) {
+ let valueToPush = isPlainObject(value) ? deepClone(value) : value;
+ newArray.push(valueToPush);
+ }
+
+ return newArray;
+}
diff --git a/libraries/chunk/chunk.js b/libraries/chunk/chunk.js
new file mode 100644
index 00000000000..57be7bd5016
--- /dev/null
+++ b/libraries/chunk/chunk.js
@@ -0,0 +1,19 @@
+/**
+ * http://npm.im/chunk
+ * Returns an array with *size* chunks from given array
+ *
+ * Example:
+ * ['a', 'b', 'c', 'd', 'e'] chunked by 2 =>
+ * [['a', 'b'], ['c', 'd'], ['e']]
+ */
+export function chunk(array, size) {
+ let newArray = [];
+
+ for (let i = 0; i < Math.ceil(array.length / size); i++) {
+ let start = i * size;
+ let end = start + size;
+ newArray.push(array.slice(start, end));
+ }
+
+ return newArray;
+}
diff --git a/libraries/gptUtils/gptUtils.js b/libraries/gptUtils/gptUtils.js
new file mode 100644
index 00000000000..950f28c618f
--- /dev/null
+++ b/libraries/gptUtils/gptUtils.js
@@ -0,0 +1,37 @@
+import {find} from '../../src/polyfill.js';
+import {compareCodeAndSlot, isGptPubadsDefined} from '../../src/utils.js';
+
+/**
+ * Returns filter function to match adUnitCode in slot
+ * @param {string} adUnitCode AdUnit code
+ * @return {function} filter function
+ */
+export function isSlotMatchingAdUnitCode(adUnitCode) {
+ return (slot) => compareCodeAndSlot(slot, adUnitCode);
+}
+
+/**
+ * @summary Uses the adUnit's code in order to find a matching gpt slot object on the page
+ */
+export function getGptSlotForAdUnitCode(adUnitCode) {
+ let matchingSlot;
+ if (isGptPubadsDefined()) {
+ // find the first matching gpt slot on the page
+ matchingSlot = find(window.googletag.pubads().getSlots(), isSlotMatchingAdUnitCode(adUnitCode));
+ }
+ return matchingSlot;
+}
+
+/**
+ * @summary Uses the adUnit's code in order to find a matching gptSlot on the page
+ */
+export function getGptSlotInfoForAdUnitCode(adUnitCode) {
+ const matchingSlot = getGptSlotForAdUnitCode(adUnitCode);
+ if (matchingSlot) {
+ return {
+ gptSlot: matchingSlot.getAdUnitPath(),
+ divId: matchingSlot.getSlotElementId()
+ };
+ }
+ return {};
+}
diff --git a/libraries/htmlEscape/htmlEscape.js b/libraries/htmlEscape/htmlEscape.js
new file mode 100644
index 00000000000..f0952c02e3c
--- /dev/null
+++ b/libraries/htmlEscape/htmlEscape.js
@@ -0,0 +1,26 @@
+/**
+ * Encode a string for inclusion in HTML.
+ * See https://pragmaticwebsecurity.com/articles/spasecurity/json-stringify-xss.html and
+ * https://codeql.github.com/codeql-query-help/javascript/js-bad-code-sanitization/
+ * @return {string}
+ */
+export const escapeUnsafeChars = (() => {
+ const escapes = {
+ '<': '\\u003C',
+ '>': '\\u003E',
+ '/': '\\u002F',
+ '\\': '\\\\',
+ '\b': '\\b',
+ '\f': '\\f',
+ '\n': '\\n',
+ '\r': '\\r',
+ '\t': '\\t',
+ '\0': '\\0',
+ '\u2028': '\\u2028',
+ '\u2029': '\\u2029'
+ };
+
+ return function (str) {
+ return str.replace(/[<>\b\f\n\r\t\0\u2028\u2029\\]/g, x => escapes[x]);
+ };
+})();
diff --git a/libraries/sizeUtils/sizeUtils.js b/libraries/sizeUtils/sizeUtils.js
new file mode 100644
index 00000000000..41cdd71df89
--- /dev/null
+++ b/libraries/sizeUtils/sizeUtils.js
@@ -0,0 +1,29 @@
+/**
+ * Read an adUnit object and return the sizes used in an [[728, 90]] format (even if they had [728, 90] defined)
+ * Preference is given to the `adUnit.mediaTypes.banner.sizes` object over the `adUnit.sizes`
+ * @param {object} adUnit one adUnit object from the normal list of adUnits
+ * @returns {Array.} array of arrays containing numeric sizes
+ */
+export function getAdUnitSizes(adUnit) {
+ if (!adUnit) {
+ return;
+ }
+
+ let sizes = [];
+ if (adUnit.mediaTypes && adUnit.mediaTypes.banner && Array.isArray(adUnit.mediaTypes.banner.sizes)) {
+ let bannerSizes = adUnit.mediaTypes.banner.sizes;
+ if (Array.isArray(bannerSizes[0])) {
+ sizes = bannerSizes;
+ } else {
+ sizes.push(bannerSizes);
+ }
+ // TODO - remove this else block when we're ready to deprecate adUnit.sizes for bidders
+ } else if (Array.isArray(adUnit.sizes)) {
+ if (Array.isArray(adUnit.sizes[0])) {
+ sizes = adUnit.sizes;
+ } else {
+ sizes.push(adUnit.sizes);
+ }
+ }
+ return sizes;
+}
diff --git a/libraries/transformParamsUtils/convertTypes.js b/libraries/transformParamsUtils/convertTypes.js
new file mode 100644
index 00000000000..813d8e6e693
--- /dev/null
+++ b/libraries/transformParamsUtils/convertTypes.js
@@ -0,0 +1,36 @@
+import {isFn} from '../../src/utils.js';
+
+/**
+ * Try to convert a value to a type.
+ * If it can't be done, the value will be returned.
+ *
+ * @param {string} typeToConvert The target type. e.g. "string", "number", etc.
+ * @param {*} value The value to be converted into typeToConvert.
+ */
+function tryConvertType(typeToConvert, value) {
+ if (typeToConvert === 'string') {
+ return value && value.toString();
+ } else if (typeToConvert === 'number') {
+ return Number(value);
+ } else {
+ return value;
+ }
+}
+
+export function convertTypes(types, params) {
+ Object.keys(types).forEach(key => {
+ if (params[key]) {
+ if (isFn(types[key])) {
+ params[key] = types[key](params[key]);
+ } else {
+ params[key] = tryConvertType(types[key], params[key]);
+ }
+
+ // don't send invalid values
+ if (isNaN(params[key])) {
+ delete params.key;
+ }
+ }
+ });
+ return params;
+}
diff --git a/libraries/urlUtils/urlUtils.js b/libraries/urlUtils/urlUtils.js
new file mode 100644
index 00000000000..f0c5823aab1
--- /dev/null
+++ b/libraries/urlUtils/urlUtils.js
@@ -0,0 +1,7 @@
+export function tryAppendQueryString(existingUrl, key, value) {
+ if (value) {
+ return existingUrl + key + '=' + encodeURIComponent(value) + '&';
+ }
+
+ return existingUrl;
+}
diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js
index b965183de19..0e9beb22013 100644
--- a/modules/33acrossBidAdapter.js
+++ b/modules/33acrossBidAdapter.js
@@ -6,7 +6,6 @@ import {
getWindowTop,
isArray,
isGptPubadsDefined,
- isSlotMatchingAdUnitCode,
logInfo,
logWarn,
mergeDeep,
@@ -14,6 +13,7 @@ import {
uniques
} from '../src/utils.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
+import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
// **************************** UTILS *************************** //
const BIDDER_CODE = '33across';
diff --git a/modules/a1MediaBidAdapter.js b/modules/a1MediaBidAdapter.js
new file mode 100644
index 00000000000..6a137e621c5
--- /dev/null
+++ b/modules/a1MediaBidAdapter.js
@@ -0,0 +1,89 @@
+import { ortbConverter } from '../libraries/ortbConverter/converter.js';
+import { registerBidder } from '../src/adapters/bidderFactory.js';
+import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js';
+
+const BIDDER_CODE = 'a1media';
+const END_POINT = 'https://d11.contentsfeed.com/dsp/breq/a1';
+const DEFAULT_CURRENCY = 'JPY';
+
+const converter = ortbConverter({
+ context: {
+ netRevenue: true,
+ ttl: 30,
+ },
+ imp(buildImp, bidRequest, context) {
+ const imp = buildImp(bidRequest, context);
+ if (!imp.bidfloor) {
+ imp.bidfloor = bidRequest.params.bidfloor || 0;
+ imp.bidfloorcur = bidRequest.params.currency || DEFAULT_CURRENCY;
+ }
+ if (bidRequest.params.battr) {
+ Object.keys(bidRequest.mediaTypes).forEach(mType => {
+ imp[mType].battr = bidRequest.params.battr;
+ })
+ }
+ return imp;
+ },
+ request(buildRequest, imps, bidderRequest, context) {
+ const request = buildRequest(imps, bidderRequest, context);
+ const bid = context.bidRequests[0];
+ if (!request.cur) {
+ request.cur = [bid.params.currency || DEFAULT_CURRENCY];
+ }
+ if (bid.params.bcat) {
+ request.bcat = bid.params.bcat;
+ }
+ return request;
+ },
+ bidResponse(buildBidResponse, bid, context) {
+ const { bidRequest } = context;
+
+ let resMediaType;
+ const reqMediaTypes = Object.keys(bidRequest.mediaTypes);
+ if (reqMediaTypes.length === 1) {
+ resMediaType = reqMediaTypes[0];
+ } else {
+ if (bid.adm.search(/^(<\?xml| isVideoBid(bid));
+ let bannerBids = bids.filter((bid) => isBannerBid(bid));
+ let requests = bannerBids.length
+ ? [createRequest(bannerBids, bidderRequest, BANNER)]
+ : [];
+ videoBids.forEach((bid) => {
+ requests.push(createRequest([bid], bidderRequest, VIDEO));
+ });
+ return requests;
+}
+
+function createRequest(bidRequests, bidderRequest, mediaType) {
+ return {
+ method: 'POST',
+ url: REQUEST_URL,
+ data: converter.toORTB({
+ bidRequests,
+ bidderRequest,
+ context: { mediaType },
+ }),
+ };
+}
+
+function isVideoBid(bid) {
+ return utils.deepAccess(bid, 'mediaTypes.video');
+}
+
+function isBannerBid(bid) {
+ return utils.deepAccess(bid, 'mediaTypes.banner');
+}
+
+function interpretResponse(resp, req) {
+ return converter.fromORTB({ request: req.data, response: resp.body });
+}
diff --git a/modules/adfusionBidAdapter.md b/modules/adfusionBidAdapter.md
new file mode 100644
index 00000000000..803a03ba1a1
--- /dev/null
+++ b/modules/adfusionBidAdapter.md
@@ -0,0 +1,61 @@
+# Overview
+
+```
+Module Name: AdFusion Bid Adapter
+Module Type: Bidder Adapter
+Maintainer: prebid@adfusion.pl
+```
+
+# Description
+
+Module that connects to AdFusion demand sources
+
+# Banner Test Parameters
+
+```js
+var adUnits = [
+ {
+ code: "test-banner",
+ mediaTypes: {
+ banner: {
+ sizes: [
+ [300, 250],
+ [300, 600],
+ [320, 480],
+ ],
+ },
+ },
+ bids: [
+ {
+ bidder: "adfusion",
+ params: {
+ accountId: 1234, // required
+ },
+ },
+ ],
+ },
+];
+```
+
+# Video Test Parameters
+
+```js
+var videoAdUnit = {
+ code: "video1",
+ mediaTypes: {
+ video: {
+ context: "instream",
+ playerSize: [640, 480],
+ mimes: ["video/mp4"],
+ },
+ },
+ bids: [
+ {
+ bidder: "adfusion",
+ params: {
+ accountId: 1234, // required
+ },
+ },
+ ],
+};
+```
diff --git a/modules/adgenerationBidAdapter.js b/modules/adgenerationBidAdapter.js
index bf75756174d..b40378c8e35 100644
--- a/modules/adgenerationBidAdapter.js
+++ b/modules/adgenerationBidAdapter.js
@@ -1,8 +1,10 @@
-import {tryAppendQueryString, getBidIdParameter, escapeUnsafeChars, deepAccess} from '../src/utils.js';
+import {deepAccess, getBidIdParameter} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
+import {escapeUnsafeChars} from '../libraries/htmlEscape/htmlEscape.js';
const ADG_BIDDER_CODE = 'adgeneration';
diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js
index 71d5c809e71..9d9da8cb0ab 100644
--- a/modules/adkernelBidAdapter.js
+++ b/modules/adkernelBidAdapter.js
@@ -5,7 +5,6 @@ import {
createTrackPixelHtml,
deepAccess,
deepSetValue,
- getAdUnitSizes,
getDefinedParams,
getDNT,
isArray,
@@ -22,6 +21,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
import {find} from '../src/polyfill.js';
import {config} from '../src/config.js';
import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
/*
* In case you're AdKernel whitelable platform's client who needs branded adapter to
diff --git a/modules/adlooxAnalyticsAdapter.js b/modules/adlooxAnalyticsAdapter.js
index 5db75c656bb..9284d543298 100644
--- a/modules/adlooxAnalyticsAdapter.js
+++ b/modules/adlooxAnalyticsAdapter.js
@@ -14,7 +14,6 @@ import {find} from '../src/polyfill.js';
import {getRefererInfo} from '../src/refererDetection.js';
import {
deepAccess,
- getGptSlotInfoForAdUnitCode,
getUniqueIdentifierStr,
insertElement,
isFn,
@@ -28,6 +27,7 @@ import {
mergeDeep,
parseUrl
} from '../src/utils.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const MODULE = 'adlooxAnalyticsAdapter';
diff --git a/modules/adlooxRtdProvider.js b/modules/adlooxRtdProvider.js
index c2037429185..727dc84e399 100644
--- a/modules/adlooxRtdProvider.js
+++ b/modules/adlooxRtdProvider.js
@@ -25,7 +25,6 @@ import {
deepAccess,
deepClone,
deepSetValue,
- getGptSlotInfoForAdUnitCode,
isArray,
isBoolean,
isInteger,
@@ -37,6 +36,7 @@ import {
parseUrl,
safeJSONParse
} from '../src/utils.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const MODULE_NAME = 'adloox';
const MODULE = `${MODULE_NAME}RtdProvider`;
diff --git a/modules/admaticBidAdapter.js b/modules/admaticBidAdapter.js
index 436f918a0f6..52c06318ec0 100644
--- a/modules/admaticBidAdapter.js
+++ b/modules/admaticBidAdapter.js
@@ -1,4 +1,4 @@
-import { getValue, logError, isEmpty, deepAccess, getBidIdParameter, isArray } from '../src/utils.js';
+import {getValue, logError, isEmpty, deepAccess, isArray, getBidIdParameter} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
diff --git a/modules/adpod.js b/modules/adpod.js
index 0318785d55e..d2fd817ee62 100644
--- a/modules/adpod.js
+++ b/modules/adpod.js
@@ -13,7 +13,6 @@
*/
import {
- compareOn,
deepAccess,
generateUUID,
groupBy,
@@ -591,6 +590,23 @@ function getAdPodAdUnits(codes) {
.filter((adUnit) => (codes.length > 0) ? codes.indexOf(adUnit.code) != -1 : true);
}
+/**
+ * This function will create compare function to sort on object property
+ * @param {string} property
+ * @returns {function} compare function to be used in sorting
+ */
+function compareOn(property) {
+ return function compare(a, b) {
+ if (a[property] < b[property]) {
+ return 1;
+ }
+ if (a[property] > b[property]) {
+ return -1;
+ }
+ return 0;
+ }
+}
+
/**
* This function removes bids of same category. It will be used when competitive exclusion is enabled.
* @param {Array[Object]} bidsReceived
diff --git a/modules/adrelevantisBidAdapter.js b/modules/adrelevantisBidAdapter.js
index f1f92e5dd5e..3c9c661b09c 100644
--- a/modules/adrelevantisBidAdapter.js
+++ b/modules/adrelevantisBidAdapter.js
@@ -1,8 +1,5 @@
import {Renderer} from '../src/Renderer.js';
import {
- chunk,
- convertCamelToUnderscore,
- convertTypes,
createTrackPixelHtml,
deepAccess,
deepClone,
@@ -21,7 +18,10 @@ import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import {find, includes} from '../src/polyfill.js';
import {INSTREAM, OUTSTREAM} from '../src/video.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
-import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusKeywords/anKeywords.js';
+import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const BIDDER_CODE = 'adrelevantis';
const URL = 'https://ssp.adrelevantis.com/prebid';
diff --git a/modules/adriverBidAdapter.js b/modules/adriverBidAdapter.js
index 1af0cffa700..5bce315f572 100644
--- a/modules/adriverBidAdapter.js
+++ b/modules/adriverBidAdapter.js
@@ -1,5 +1,5 @@
// ADRIVER BID ADAPTER for Prebid 1.13
-import { logInfo, getWindowLocation, getBidIdParameter, _each } from '../src/utils.js';
+import {logInfo, getWindowLocation, _each, getBidIdParameter} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { getStorageManager } from '../src/storageManager.js';
diff --git a/modules/adtargetBidAdapter.js b/modules/adtargetBidAdapter.js
index 89ba4878acf..a1dec5a420f 100644
--- a/modules/adtargetBidAdapter.js
+++ b/modules/adtargetBidAdapter.js
@@ -1,8 +1,9 @@
-import {_map, chunk, deepAccess, flatten, isArray, logError, parseSizesInput} from '../src/utils.js';
+import {_map, deepAccess, flatten, isArray, logError, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {find} from '../src/polyfill.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const ENDPOINT = 'https://ghb.console.adtarget.com.tr/v2/auction/';
const BIDDER_CODE = 'adtarget';
diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js
index a315c9a696e..04bca21c60f 100644
--- a/modules/adtelligentBidAdapter.js
+++ b/modules/adtelligentBidAdapter.js
@@ -1,9 +1,11 @@
-import {_map, chunk, convertTypes, deepAccess, flatten, isArray, parseSizesInput} from '../src/utils.js';
+import {_map, deepAccess, flatten, isArray, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {Renderer} from '../src/Renderer.js';
import {find} from '../src/polyfill.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const subdomainSuffixes = ['', 1, 2];
const AUCTION_PATH = '/v2/auction/';
diff --git a/modules/aduptechBidAdapter.js b/modules/aduptechBidAdapter.js
index 1ea5f1a0096..49187da2fe2 100644
--- a/modules/aduptechBidAdapter.js
+++ b/modules/aduptechBidAdapter.js
@@ -1,7 +1,8 @@
-import {deepClone, getAdUnitSizes, isArray, isBoolean, isEmpty, isFn, isPlainObject} from '../src/utils.js';
+import {deepClone, isArray, isBoolean, isEmpty, isFn, isPlainObject} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
export const BIDDER_CODE = 'aduptech';
export const GVLID = 647;
diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js
index 6eb897d334e..8952c3ae2b9 100644
--- a/modules/adyoulikeBidAdapter.js
+++ b/modules/adyoulikeBidAdapter.js
@@ -1,5 +1,6 @@
import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
+import { config } from '../src/config.js';
import {find} from '../src/polyfill.js';
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
@@ -166,6 +167,50 @@ export const spec = {
}
});
return bidResponses;
+ },
+
+ /**
+ * List user sync endpoints.
+ * Legal information have to be added to the request.
+ * Only iframe syncs are supported.
+ *
+ * @param {*} syncOptions Publisher prebid configuration.
+ * @param {*} serverResponses A successful response from the server.
+ * @return {syncs[]} An array of syncs that should be executed.
+ */
+ getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) {
+ if (!syncOptions.iframeEnabled) {
+ return [];
+ }
+
+ let params = '';
+
+ // GDPR
+ if (gdprConsent) {
+ params += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
+ params += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
+ }
+
+ // coppa compliance
+ if (config.getConfig('coppa') === true) {
+ params += '&coppa=1';
+ }
+
+ // CCPA
+ if (uspConsent) {
+ params += '&us_privacy=' + encodeURIComponent(uspConsent);
+ }
+
+ // GPP
+ if (gppConsent?.gppString && gppConsent?.applicableSections?.length) {
+ params += '&gpp=' + encodeURIComponent(gppConsent.gppString);
+ params += '&gpp_sid=' + encodeURIComponent(gppConsent?.applicableSections?.join(','));
+ }
+
+ return [{
+ type: 'iframe',
+ url: `https://visitor.omnitagjs.com/visitor/isync?uid=19340f4f097d16f41f34fc0274981ca4${params}`
+ }];
}
}
diff --git a/modules/ajaBidAdapter.js b/modules/ajaBidAdapter.js
index ffab41611ef..9049197e565 100644
--- a/modules/ajaBidAdapter.js
+++ b/modules/ajaBidAdapter.js
@@ -1,7 +1,8 @@
-import { getBidIdParameter, tryAppendQueryString, createTrackPixelHtml, logError, logWarn, deepAccess } from '../src/utils.js';
+import {createTrackPixelHtml, logError, logWarn, deepAccess, getBidIdParameter} from '../src/utils.js';
import { Renderer } from '../src/Renderer.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { VIDEO, BANNER, NATIVE } from '../src/mediaTypes.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BidderCode = 'aja';
const URL = 'https://ad.as.amanad.adtdp.com/v2/prebid';
diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js
index 6274ad2bf1c..81d993e9ac8 100644
--- a/modules/alkimiBidAdapter.js
+++ b/modules/alkimiBidAdapter.js
@@ -59,6 +59,9 @@ export const spec = {
h: screen.height
},
ortb2: {
+ site: {
+ keywords: bidderRequest.ortb2?.site?.keywords
+ },
at: bidderRequest.ortb2?.at,
bcat: bidderRequest.ortb2?.bcat,
wseat: bidderRequest.ortb2?.wseat
diff --git a/modules/apacdexBidAdapter.js b/modules/apacdexBidAdapter.js
index e1557d9c6d3..834df134c2e 100644
--- a/modules/apacdexBidAdapter.js
+++ b/modules/apacdexBidAdapter.js
@@ -96,8 +96,8 @@ export const spec = {
payload.device = {};
payload.device.ua = navigator.userAgent;
- payload.device.height = window.screen.width;
- payload.device.width = window.screen.height;
+ payload.device.height = window.screen.height;
+ payload.device.width = window.screen.width;
payload.device.dnt = _getDoNotTrack();
payload.device.language = navigator.language;
diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js
index ae4b1a0d489..e6b3441b988 100644
--- a/modules/appnexusBidAdapter.js
+++ b/modules/appnexusBidAdapter.js
@@ -1,17 +1,10 @@
import {
- chunk,
- convertCamelToUnderscore,
- convertTypes,
createTrackPixelHtml,
deepAccess,
deepClone,
- fill,
getBidRequest,
- getMaxValueFromArray,
- getMinValueFromArray,
getParameterByName,
getUniqueIdentifierStr,
- getWindowFromDocument,
isArray,
isArrayOfNums,
isEmpty,
@@ -40,7 +33,10 @@ import {
getANKewyordParamFromMaps,
getANKeywordParam,
transformBidderParamKeywords
-} from '../libraries/appnexusKeywords/anKeywords.js';
+} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const BIDDER_CODE = 'appnexus';
const URL = 'https://ib.adnxs.com/ut/v3/prebid';
@@ -1031,7 +1027,7 @@ function createAdPodRequest(tags, adPodBid) {
const { durationRangeSec, requireExactDuration } = adPodBid.mediaTypes.video;
const numberOfPlacements = getAdPodPlacementNumber(adPodBid.mediaTypes.video);
- const maxDuration = getMaxValueFromArray(durationRangeSec);
+ const maxDuration = Math.max(...durationRangeSec);
const tagToDuplicate = tags.filter(tag => tag.uuid === adPodBid.bidId);
let request = fill(...tagToDuplicate, numberOfPlacements);
@@ -1057,7 +1053,7 @@ function createAdPodRequest(tags, adPodBid) {
function getAdPodPlacementNumber(videoParams) {
const { adPodDurationSec, durationRangeSec, requireExactDuration } = videoParams;
- const minAllowedDuration = getMinValueFromArray(durationRangeSec);
+ const minAllowedDuration = Math.min(...durationRangeSec);
const numberOfPlacements = Math.floor(adPodDurationSec / minAllowedDuration);
return requireExactDuration
@@ -1142,7 +1138,7 @@ function outstreamRender(bid, doc) {
hideSASIframe(bid.adUnitCode);
// push to render queue because ANOutstreamVideo may not be loaded yet
bid.renderer.push(() => {
- const win = getWindowFromDocument(doc) || window;
+ const win = doc?.defaultView || window;
win.ANOutstreamVideo.renderAd({
tagId: bid.adResponse.tag_id,
sizes: [bid.getSize().split('x')],
diff --git a/modules/asoBidAdapter.js b/modules/asoBidAdapter.js
index e569f04a2a8..704cffefb39 100644
--- a/modules/asoBidAdapter.js
+++ b/modules/asoBidAdapter.js
@@ -7,14 +7,14 @@ import {
isArray,
isFn,
logWarn,
- parseSizesInput,
- tryAppendQueryString
+ parseSizesInput
} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { Renderer } from '../src/Renderer.js';
import { parseDomain } from '../src/refererDetection.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BIDDER_CODE = 'aso';
const DEFAULT_SERVER_URL = 'https://srv.aso1.net';
diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js
index 9beb20d4f77..e716fe94c8b 100644
--- a/modules/audiencerunBidAdapter.js
+++ b/modules/audiencerunBidAdapter.js
@@ -1,8 +1,7 @@
import {
_each,
deepAccess,
- formatQS,
- getBidIdParameter,
+ formatQS, getBidIdParameter,
getValue,
isArray,
isFn,
diff --git a/modules/beopBidAdapter.js b/modules/beopBidAdapter.js
index c5282c28cfc..b6b6107ddd0 100644
--- a/modules/beopBidAdapter.js
+++ b/modules/beopBidAdapter.js
@@ -1,7 +1,6 @@
import {
buildUrl,
- deepAccess,
- getBidIdParameter,
+ deepAccess, getBidIdParameter,
getValue,
isArray,
logInfo,
diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js
index d615e433cc0..6883b7cce2c 100644
--- a/modules/betweenBidAdapter.js
+++ b/modules/betweenBidAdapter.js
@@ -1,6 +1,7 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
-import {getAdUnitSizes, parseSizesInput} from '../src/utils.js';
+import {parseSizesInput} from '../src/utils.js';
import {includes} from '../src/polyfill.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'between';
let ENDPOINT = 'https://ads.betweendigital.com/adjson?t=prebid';
diff --git a/modules/bidglassBidAdapter.js b/modules/bidglassBidAdapter.js
index 3184372881b..a29976cfcb7 100644
--- a/modules/bidglassBidAdapter.js
+++ b/modules/bidglassBidAdapter.js
@@ -1,4 +1,4 @@
-import { _each, isArray, getBidIdParameter, deepClone, getUniqueIdentifierStr } from '../src/utils.js';
+import {_each, isArray, deepClone, getUniqueIdentifierStr, getBidIdParameter} from '../src/utils.js';
// import {config} from 'src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js
index c4cc5394a03..1fa1dac4e95 100644
--- a/modules/brightcomBidAdapter.js
+++ b/modules/brightcomBidAdapter.js
@@ -1,4 +1,17 @@
-import { getBidIdParameter, _each, isArray, getWindowTop, getUniqueIdentifierStr, deepSetValue, logError, logWarn, createTrackPixelHtml, getWindowSelf, isFn, isPlainObject } from '../src/utils.js';
+import {
+ _each,
+ isArray,
+ getWindowTop,
+ getUniqueIdentifierStr,
+ deepSetValue,
+ logError,
+ logWarn,
+ createTrackPixelHtml,
+ getWindowSelf,
+ isFn,
+ isPlainObject,
+ getBidIdParameter
+} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
diff --git a/modules/brightcomSSPBidAdapter.js b/modules/brightcomSSPBidAdapter.js
index b85a01c8fc7..4750881da40 100644
--- a/modules/brightcomSSPBidAdapter.js
+++ b/modules/brightcomSSPBidAdapter.js
@@ -1,5 +1,4 @@
import {
- getBidIdParameter,
isArray,
getWindowTop,
getUniqueIdentifierStr,
@@ -9,7 +8,7 @@ import {
createTrackPixelHtml,
getWindowSelf,
isFn,
- isPlainObject,
+ isPlainObject, getBidIdParameter,
} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
diff --git a/modules/cadentApertureMXBidAdapter.js b/modules/cadentApertureMXBidAdapter.js
index 079ca592160..e73564dacdb 100644
--- a/modules/cadentApertureMXBidAdapter.js
+++ b/modules/cadentApertureMXBidAdapter.js
@@ -1,7 +1,6 @@
import {
_each,
- deepAccess,
- getBidIdParameter,
+ deepAccess, getBidIdParameter,
isArray,
isFn,
isPlainObject,
diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js
index d5665b318be..b40ef30f6bc 100644
--- a/modules/connectadBidAdapter.js
+++ b/modules/connectadBidAdapter.js
@@ -1,7 +1,9 @@
-import { deepSetValue, convertTypes, tryAppendQueryString, logWarn } from '../src/utils.js';
+import { deepSetValue, logWarn } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js'
import {config} from '../src/config.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'connectad';
const BIDDER_CODE_ALIAS = 'connectadrealtime';
const ENDPOINT_URL = 'https://i.connectad.io/api/v2';
diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js
index fd436e51461..bef65a43616 100644
--- a/modules/conversantBidAdapter.js
+++ b/modules/conversantBidAdapter.js
@@ -3,22 +3,21 @@ import {
isStr,
deepAccess,
isArray,
- getBidIdParameter,
deepSetValue,
isEmpty,
_each,
- convertTypes,
parseUrl,
mergeDeep,
buildUrl,
_map,
logError,
isFn,
- isPlainObject,
+ isPlainObject, getBidIdParameter,
} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {getStorageManager} from '../src/storageManager.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
// Maintainer: mediapsr@epsilon.com
diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js
index 9e237ef2558..e076fb4b0bb 100755
--- a/modules/cpmstarBidAdapter.js
+++ b/modules/cpmstarBidAdapter.js
@@ -1,8 +1,8 @@
-
import * as utils from '../src/utils.js';
-import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { VIDEO, BANNER } from '../src/mediaTypes.js';
-import { config } from '../src/config.js';
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {BANNER, VIDEO} from '../src/mediaTypes.js';
+import {config} from '../src/config.js';
+import {getBidIdParameter} from '../src/utils.js';
const BIDDER_CODE = 'cpmstar';
@@ -49,13 +49,13 @@ export const spec = {
var bidRequest = validBidRequests[i];
var referer = bidderRequest.refererInfo.page ? bidderRequest.refererInfo.page : bidderRequest.refererInfo.domain;
referer = encodeURIComponent(referer);
- var e = utils.getBidIdParameter('endpoint', bidRequest.params);
+ var e = getBidIdParameter('endpoint', bidRequest.params);
var ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION;
var mediaType = spec.getMediaType(bidRequest);
var playerSize = spec.getPlayerSize(bidRequest);
var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : '');
var url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') +
- '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) +
+ '&json=c_b&mv=1&poolid=' + getBidIdParameter('placementId', bidRequest.params) +
'&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) +
'&requestid=' + bidRequest.bidId +
'&referer=' + encodeURIComponent(referer);
diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js
index 8f7821173c1..a2a054d7659 100644
--- a/modules/craftBidAdapter.js
+++ b/modules/craftBidAdapter.js
@@ -1,4 +1,4 @@
-import {convertCamelToUnderscore, convertTypes, getBidRequest, logError} from '../src/utils.js';
+import {getBidRequest, logError} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import {auctionManager} from '../src/auctionManager.js';
@@ -7,7 +7,9 @@ import {getStorageManager} from '../src/storageManager.js';
import {ajax} from '../src/ajax.js';
import {hasPurpose1Consent} from '../src/utils/gpdr.js';
import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
-import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusKeywords/anKeywords.js';
+import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'craft';
const URL_BASE = 'https://gacraft.jp/prebid-v3';
diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js
index 11d3ebb1589..395706994fe 100644
--- a/modules/datablocksBidAdapter.js
+++ b/modules/datablocksBidAdapter.js
@@ -1,10 +1,11 @@
-import {deepAccess, getAdUnitSizes, getWindowTop, isEmpty, isGptPubadsDefined} from '../src/utils.js';
+import {deepAccess, getWindowTop, isEmpty, isGptPubadsDefined} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
import {getStorageManager} from '../src/storageManager.js';
import {ajax} from '../src/ajax.js';
import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
export const storage = getStorageManager({bidderCode: 'datablocks'});
diff --git a/modules/datawrkzBidAdapter.js b/modules/datawrkzBidAdapter.js
index 2cf28c36330..127e7893ec5 100644
--- a/modules/datawrkzBidAdapter.js
+++ b/modules/datawrkzBidAdapter.js
@@ -1,4 +1,12 @@
-import { deepAccess, getBidIdParameter, isArray, getUniqueIdentifierStr, contains, isFn, isPlainObject } from '../src/utils.js';
+import {
+ deepAccess,
+ isArray,
+ getUniqueIdentifierStr,
+ contains,
+ isFn,
+ isPlainObject,
+ getBidIdParameter
+} from '../src/utils.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
diff --git a/modules/dchain.js b/modules/dchain.js
index daf97a7551f..7f84282b81e 100644
--- a/modules/dchain.js
+++ b/modules/dchain.js
@@ -1,7 +1,7 @@
import {includes} from '../src/polyfill.js';
import {config} from '../src/config.js';
import {getHook} from '../src/hook.js';
-import {_each, deepAccess, deepClone, hasOwn, isArray, isPlainObject, isStr, logError, logWarn} from '../src/utils.js';
+import {_each, deepAccess, deepClone, isArray, isPlainObject, isStr, logError, logWarn} from '../src/utils.js';
import {timedBidResponseHook} from '../src/utils/perfMetrics.js';
const shouldBeAString = ' should be a string';
@@ -49,7 +49,7 @@ export function checkDchainSyntax(bid, mode) {
appendFailMsg(`dchain.ver` + shouldBeAString);
}
- if (hasOwn(dchainObj, 'ext')) {
+ if (dchainObj.hasOwnProperty('ext')) {
if (!isPlainObject(dchainObj.ext)) {
appendFailMsg(`dchain.ext` + shouldBeAnObject);
}
diff --git a/modules/displayioBidAdapter.js b/modules/displayioBidAdapter.js
index 3d34f2c8b26..3cdfd3a77cd 100644
--- a/modules/displayioBidAdapter.js
+++ b/modules/displayioBidAdapter.js
@@ -1,7 +1,7 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {Renderer} from '../src/Renderer.js';
-import {getWindowFromDocument, logWarn} from '../src/utils.js';
+import {logWarn} from '../src/utils.js';
import {getStorageManager} from '../src/storageManager.js';
import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js';
@@ -156,7 +156,7 @@ function newRenderer(bid) {
function webisRender(bid, doc) {
bid.renderer.push(() => {
- const win = getWindowFromDocument(doc) || window;
+ const win = doc?.defaultView || window;
win.webis.init(bid.adData, bid.adUnitCode, bid.params);
})
}
diff --git a/modules/docereeBidAdapter.js b/modules/docereeBidAdapter.js
index 524f464cee3..fa4446ede47 100644
--- a/modules/docereeBidAdapter.js
+++ b/modules/docereeBidAdapter.js
@@ -1,7 +1,7 @@
-import { tryAppendQueryString } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER } from '../src/mediaTypes.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BIDDER_CODE = 'doceree';
const END_POINT = 'https://bidder.doceree.com'
diff --git a/modules/ebdrBidAdapter.js b/modules/ebdrBidAdapter.js
index a03a1ec12ca..e830f8a94f7 100644
--- a/modules/ebdrBidAdapter.js
+++ b/modules/ebdrBidAdapter.js
@@ -1,4 +1,4 @@
-import { logInfo, getBidIdParameter } from '../src/utils.js';
+import {getBidIdParameter, logInfo} from '../src/utils.js';
import { VIDEO, BANNER } from '../src/mediaTypes.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
const BIDDER_CODE = 'ebdr';
diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js
index 1ebbc78730c..d57804c04e6 100644
--- a/modules/eplanningBidAdapter.js
+++ b/modules/eplanningBidAdapter.js
@@ -1,8 +1,9 @@
-import {getWindowSelf, isEmpty, parseSizesInput, isGptPubadsDefined, isSlotMatchingAdUnitCode} from '../src/utils.js';
+import {getWindowSelf, isEmpty, parseSizesInput, isGptPubadsDefined} from '../src/utils.js';
import {getGlobal} from '../src/prebidGlobal.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getStorageManager} from '../src/storageManager.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
+import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const BIDDER_CODE = 'eplanning';
export const storage = getStorageManager({bidderCode: BIDDER_CODE});
diff --git a/modules/eskimiBidAdapter.js b/modules/eskimiBidAdapter.js
index 88d8f95b859..81b8c5d8058 100644
--- a/modules/eskimiBidAdapter.js
+++ b/modules/eskimiBidAdapter.js
@@ -1,7 +1,8 @@
-import { ortbConverter } from '../libraries/ortbConverter/converter.js';
-import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { BANNER, VIDEO } from '../src/mediaTypes.js';
+import {ortbConverter} from '../libraries/ortbConverter/converter.js';
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {BANNER, VIDEO} from '../src/mediaTypes.js';
import * as utils from '../src/utils.js';
+import {getBidIdParameter} from '../src/utils.js';
const BIDDER_CODE = 'eskimi';
// const ENDPOINT = 'https://hb.eskimi.com/bids'
@@ -65,7 +66,7 @@ const CONVERTER = ortbConverter({
imp.secure = Number(window.location.protocol === 'https:');
if (!imp.bidfloor && bidRequest.params.bidFloor) {
imp.bidfloor = bidRequest.params.bidFloor;
- imp.bidfloorcur = utils.getBidIdParameter('bidFloorCur', bidRequest.params).toUpperCase() || 'USD'
+ imp.bidfloorcur = getBidIdParameter('bidFloorCur', bidRequest.params).toUpperCase() || 'USD'
}
if (bidRequest.mediaTypes[VIDEO]) {
diff --git a/modules/fledgeForGpt.js b/modules/fledgeForGpt.js
index eddb7424f92..fd29c41210c 100644
--- a/modules/fledgeForGpt.js
+++ b/modules/fledgeForGpt.js
@@ -4,12 +4,13 @@
*/
import { config } from '../src/config.js';
import { getHook } from '../src/hook.js';
-import {deepSetValue, getGptSlotForAdUnitCode, logInfo, logWarn, mergeDeep} from '../src/utils.js';
+import {deepSetValue, logInfo, logWarn, mergeDeep} from '../src/utils.js';
import {IMP, PBS, registerOrtbProcessor, RESPONSE} from '../src/pbjsORTB.js';
import * as events from '../src/events.js'
import CONSTANTS from '../src/constants.json';
import {currencyCompare} from '../libraries/currencyUtils/currency.js';
import {maximum, minimum} from '../src/utils/reducers.js';
+import {getGptSlotForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const MODULE = 'fledgeForGpt'
const PENDING = {};
diff --git a/modules/gdprEnforcement.js b/modules/gdprEnforcement.js
index e7f1e7b8b45..4e600f71b90 100644
--- a/modules/gdprEnforcement.js
+++ b/modules/gdprEnforcement.js
@@ -5,7 +5,6 @@
import {deepAccess, logError, logWarn} from '../src/utils.js';
import {config} from '../src/config.js';
import adapterManager, {gdprDataHandler} from '../src/adapterManager.js';
-import {find} from '../src/polyfill.js';
import * as events from '../src/events.js';
import CONSTANTS from '../src/constants.json';
import {GDPR_GVLIDS, VENDORLESS_GVLID} from '../src/consentHandler.js';
@@ -27,44 +26,62 @@ import {
ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD,
ACTIVITY_FETCH_BIDS,
ACTIVITY_REPORT_ANALYTICS,
- ACTIVITY_SYNC_USER, ACTIVITY_TRANSMIT_UFPD
+ ACTIVITY_SYNC_USER, ACTIVITY_TRANSMIT_EIDS, ACTIVITY_TRANSMIT_PRECISE_GEO, ACTIVITY_TRANSMIT_UFPD
} from '../src/activities/activities.js';
export const STRICT_STORAGE_ENFORCEMENT = 'strictStorageEnforcement';
-const TCF2 = {
- purpose1: {id: 1, name: 'storage'},
- purpose2: {id: 2, name: 'basicAds'},
- purpose4: {id: 4, name: 'personalizedAds'},
- purpose7: {id: 7, name: 'measurement'},
+export const ACTIVE_RULES = {
+ purpose: {},
+ feature: {}
};
-/*
- These rules would be used if `consentManagement.gdpr.rules` is undefined by the publisher.
-*/
-const DEFAULT_RULES = [{
- purpose: 'storage',
- enforcePurpose: true,
- enforceVendor: true,
- vendorExceptions: []
-}, {
- purpose: 'basicAds',
- enforcePurpose: true,
- enforceVendor: true,
- vendorExceptions: []
-}];
-
-export let purpose1Rule;
-export let purpose2Rule;
-export let purpose4Rule;
-export let purpose7Rule;
-
-export let enforcementRules;
+const CONSENT_PATHS = {
+ purpose: 'purpose.consents',
+ feature: 'specialFeatureOptins'
+};
+
+const CONFIGURABLE_RULES = {
+ storage: {
+ type: 'purpose',
+ default: {
+ purpose: 'storage',
+ enforcePurpose: true,
+ enforceVendor: true,
+ vendorExceptions: []
+ },
+ id: 1,
+ },
+ basicAds: {
+ type: 'purpose',
+ id: 2,
+ default: {
+ purpose: 'basicAds',
+ enforcePurpose: true,
+ enforceVendor: true,
+ vendorExceptions: []
+ }
+ },
+ personalizedAds: {
+ type: 'purpose',
+ id: 4,
+ },
+ measurement: {
+ type: 'purpose',
+ id: 7,
+ },
+ transmitPreciseGeo: {
+ type: 'feature',
+ id: 1,
+ },
+};
const storageBlocked = new Set();
const biddersBlocked = new Set();
const analyticsBlocked = new Set();
const ufpdBlocked = new Set();
+const eidsBlocked = new Set();
+const geoBlocked = new Set();
let hooksAdded = false;
let strictStorageEnforcement = false;
@@ -79,6 +96,9 @@ const GVLID_LOOKUP_PRIORITY = [
const RULE_NAME = 'TCF2';
const RULE_HANDLES = [];
+// in JS we do not have access to the GVL; assume that everyone declares legitimate interest for basic ads
+const LI_PURPOSES = [2];
+
/**
* Retrieve a module's GVL ID.
*/
@@ -143,6 +163,16 @@ export function shouldEnforce(consentData, purpose, name) {
return consentData && consentData.gdprApplies;
}
+function getConsent(consentData, type, id, gvlId) {
+ let purpose = !!deepAccess(consentData, `vendorData.${CONSENT_PATHS[type]}.${id}`);
+ let vendor = !!deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`);
+ if (type === 'purpose' && LI_PURPOSES.includes(id)) {
+ purpose ||= !!deepAccess(consentData, `vendorData.purpose.legitimateInterests.${id}`);
+ vendor ||= !!deepAccess(consentData, `vendorData.vendor.legitimateInterests.${gvlId}`);
+ }
+ return {purpose, vendor};
+}
+
/**
* This function takes in a rule and consentData and validates against the consentData provided. Depending on what it returns,
* the caller may decide to suppress a TCF-sensitive activity.
@@ -153,42 +183,24 @@ export function shouldEnforce(consentData, purpose, name) {
* @returns {boolean}
*/
export function validateRules(rule, consentData, currentModule, gvlId) {
- const purposeId = TCF2[Object.keys(TCF2).filter(purposeName => TCF2[purposeName].name === rule.purpose)[0]].id;
+ const ruleOptions = CONFIGURABLE_RULES[rule.purpose];
// return 'true' if vendor present in 'vendorExceptions'
if ((rule.vendorExceptions || []).includes(currentModule)) {
return true;
}
const vendorConsentRequred = rule.enforceVendor && !((gvlId === VENDORLESS_GVLID || (rule.softVendorExceptions || []).includes(currentModule)));
-
- let purposeAllowed = !rule.enforcePurpose || !!deepAccess(consentData, `vendorData.purpose.consents.${purposeId}`);
- let vendorAllowed = !vendorConsentRequred || !!deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`);
-
- if (purposeId === 2) {
- purposeAllowed ||= !!deepAccess(consentData, `vendorData.purpose.legitimateInterests.${purposeId}`);
- vendorAllowed ||= !!deepAccess(consentData, `vendorData.vendor.legitimateInterests.${gvlId}`);
- }
-
- return purposeAllowed && vendorAllowed;
+ const {purpose, vendor} = getConsent(consentData, ruleOptions.type, ruleOptions.id, gvlId);
+ return (!rule.enforcePurpose || purpose) && (!vendorConsentRequred || vendor);
}
-/**
- * all activity rules follow the same structure:
- * if GDPR is in scope, check configuration for a particular purpose, and if that enables enforcement,
- * check against consent data for that purpose and vendor
- *
- * @param purposeNo TCF purpose number to check for this activity
- * @param getEnforcementRule getter for gdprEnforcement rule definition to use
- * @param blocked optional set to use for collecting denied vendors
- * @param gvlidFallback optional factory function for a gvlid falllback function
- */
-function gdprRule(purposeNo, getEnforcementRule, blocked = null, gvlidFallback = () => null) {
+function gdprRule(purposeNo, checkConsent, blocked = null, gvlidFallback = () => null) {
return function (params) {
const consentData = gdprDataHandler.getConsentData();
const modName = params[ACTIVITY_PARAM_COMPONENT_NAME];
if (shouldEnforce(consentData, purposeNo, modName)) {
const gvlid = getGvlid(params[ACTIVITY_PARAM_COMPONENT_TYPE], modName, gvlidFallback(params));
- let allow = !!validateRules(getEnforcementRule(), consentData, modName, gvlid);
+ let allow = !!checkConsent(consentData, modName, gvlid);
if (!allow) {
blocked && blocked.add(modName);
return {allow};
@@ -197,32 +209,62 @@ function gdprRule(purposeNo, getEnforcementRule, blocked = null, gvlidFallback =
};
}
-export const accessDeviceRule = ((rule) => {
- return function (params) {
- // for vendorless (core) storage, do not enforce rules unless strictStorageEnforcement is set
- if (params[ACTIVITY_PARAM_COMPONENT_TYPE] === MODULE_TYPE_PREBID && !strictStorageEnforcement) return;
- return rule(params);
- };
-})(gdprRule(1, () => purpose1Rule, storageBlocked));
-
-export const syncUserRule = gdprRule(1, () => purpose1Rule, storageBlocked);
-export const enrichEidsRule = gdprRule(1, () => purpose1Rule, storageBlocked);
+function singlePurposeGdprRule(purposeNo, blocked = null, gvlidFallback = () => null) {
+ return gdprRule(purposeNo, (cd, modName, gvlid) => !!validateRules(ACTIVE_RULES.purpose[purposeNo], cd, modName, gvlid), blocked, gvlidFallback);
+}
-export const fetchBidsRule = ((rule) => {
+function exceptPrebidModules(ruleFn) {
return function (params) {
- if (params[ACTIVITY_PARAM_COMPONENT_TYPE] !== MODULE_TYPE_BIDDER) {
+ if (params[ACTIVITY_PARAM_COMPONENT_TYPE] === MODULE_TYPE_PREBID) {
// TODO: this special case is for the PBS adapter (componentType is 'prebid')
// we should check for generic purpose 2 consent & vendor consent based on the PBS vendor's GVL ID;
// that is, however, a breaking change and skipped for now
return;
}
+ return ruleFn(params);
+ };
+}
+
+export const accessDeviceRule = ((rule) => {
+ return function (params) {
+ // for vendorless (core) storage, do not enforce rules unless strictStorageEnforcement is set
+ if (params[ACTIVITY_PARAM_COMPONENT_TYPE] === MODULE_TYPE_PREBID && !strictStorageEnforcement) return;
return rule(params);
};
-})(gdprRule(2, () => purpose2Rule, biddersBlocked));
+})(singlePurposeGdprRule(1, storageBlocked));
+
+export const syncUserRule = singlePurposeGdprRule(1, storageBlocked);
+export const enrichEidsRule = singlePurposeGdprRule(1, storageBlocked);
+export const fetchBidsRule = exceptPrebidModules(singlePurposeGdprRule(2, biddersBlocked));
+export const reportAnalyticsRule = singlePurposeGdprRule(7, analyticsBlocked, (params) => getGvlidFromAnalyticsAdapter(params[ACTIVITY_PARAM_COMPONENT_NAME], params[ACTIVITY_PARAM_ANL_CONFIG]));
+export const ufpdRule = singlePurposeGdprRule(4, ufpdBlocked);
+
+export const transmitEidsRule = exceptPrebidModules((() => {
+ // Transmit EID special case:
+ // by default, legal basis or vendor exceptions for any purpose between 2 and 10
+ // (but disregarding enforcePurpose and enforceVendor config) is enough to allow EIDs through
+ function check2to10Consent(consentData, modName, gvlId) {
+ for (let pno = 2; pno <= 10; pno++) {
+ if (ACTIVE_RULES.purpose[pno]?.vendorExceptions?.includes(modName)) {
+ return true;
+ }
+ const {purpose, vendor} = getConsent(consentData, 'purpose', pno, gvlId);
+ if (purpose && (vendor || ACTIVE_RULES.purpose[pno]?.softVendorExceptions?.includes(modName))) {
+ return true;
+ }
+ }
+ return false;
+ }
-export const reportAnalyticsRule = gdprRule(7, () => purpose7Rule, analyticsBlocked, (params) => getGvlidFromAnalyticsAdapter(params[ACTIVITY_PARAM_COMPONENT_NAME], params[ACTIVITY_PARAM_ANL_CONFIG]));
+ const defaultBehavior = gdprRule('2-10', check2to10Consent, eidsBlocked);
+ const p4Behavior = singlePurposeGdprRule(4, eidsBlocked);
+ return function () {
+ const fn = ACTIVE_RULES.purpose[4]?.eidsRequireP4Consent ? p4Behavior : defaultBehavior;
+ return fn.apply(this, arguments);
+ };
+})());
-export const ufpdRule = gdprRule(4, () => purpose4Rule, ufpdBlocked);
+export const transmitPreciseGeoRule = gdprRule('Special Feature 1', (cd, modName, gvlId) => validateRules(ACTIVE_RULES.feature[1], cd, modName, gvlId), geoBlocked);
/**
* Compiles the TCF2.0 enforcement results into an object, which is emitted as an event payload to "tcf2Enforcement" event.
@@ -237,65 +279,55 @@ function emitTCF2FinalResults() {
biddersBlocked: formatSet(biddersBlocked),
analyticsBlocked: formatSet(analyticsBlocked),
ufpdBlocked: formatSet(ufpdBlocked),
+ eidsBlocked: formatSet(eidsBlocked),
+ geoBlocked: formatSet(geoBlocked)
};
events.emit(CONSTANTS.EVENTS.TCF2_ENFORCEMENT, tcf2FinalResults);
- [storageBlocked, biddersBlocked, analyticsBlocked, ufpdBlocked].forEach(el => el.clear());
+ [storageBlocked, biddersBlocked, analyticsBlocked, ufpdBlocked, eidsBlocked, geoBlocked].forEach(el => el.clear());
}
events.on(CONSTANTS.EVENTS.AUCTION_END, emitTCF2FinalResults);
-function hasPurpose(purposeNo) {
- const pname = TCF2[`purpose${purposeNo}`].name;
- return (rule) => rule.purpose === pname;
-}
-
/**
* A configuration function that initializes some module variables, as well as adds hooks
* @param {Object} config - GDPR enforcement config object
*/
export function setEnforcementConfig(config) {
- const rules = deepAccess(config, 'gdpr.rules');
+ let rules = deepAccess(config, 'gdpr.rules');
if (!rules) {
logWarn('TCF2: enforcing P1 and P2 by default');
- enforcementRules = DEFAULT_RULES;
- } else {
- enforcementRules = rules;
}
+ rules = Object.fromEntries((rules || []).map(r => [r.purpose, r]));
strictStorageEnforcement = !!deepAccess(config, STRICT_STORAGE_ENFORCEMENT);
- purpose1Rule = find(enforcementRules, hasPurpose(1));
- purpose2Rule = find(enforcementRules, hasPurpose(2));
- purpose4Rule = find(enforcementRules, hasPurpose(4))
- purpose7Rule = find(enforcementRules, hasPurpose(7));
-
- if (!purpose1Rule) {
- purpose1Rule = DEFAULT_RULES[0];
- }
-
- if (!purpose2Rule) {
- purpose2Rule = DEFAULT_RULES[1];
- }
+ Object.entries(CONFIGURABLE_RULES).forEach(([name, opts]) => {
+ ACTIVE_RULES[opts.type][opts.id] = rules[name] ?? opts.default;
+ });
if (!hooksAdded) {
- if (purpose1Rule) {
+ if (ACTIVE_RULES.purpose[1] != null) {
hooksAdded = true;
RULE_HANDLES.push(registerActivityControl(ACTIVITY_ACCESS_DEVICE, RULE_NAME, accessDeviceRule));
RULE_HANDLES.push(registerActivityControl(ACTIVITY_SYNC_USER, RULE_NAME, syncUserRule));
RULE_HANDLES.push(registerActivityControl(ACTIVITY_ENRICH_EIDS, RULE_NAME, enrichEidsRule));
}
- if (purpose2Rule) {
+ if (ACTIVE_RULES.purpose[2] != null) {
RULE_HANDLES.push(registerActivityControl(ACTIVITY_FETCH_BIDS, RULE_NAME, fetchBidsRule));
}
- if (purpose4Rule) {
+ if (ACTIVE_RULES.purpose[4] != null) {
RULE_HANDLES.push(
registerActivityControl(ACTIVITY_TRANSMIT_UFPD, RULE_NAME, ufpdRule),
registerActivityControl(ACTIVITY_ENRICH_UFPD, RULE_NAME, ufpdRule)
);
}
- if (purpose7Rule) {
+ if (ACTIVE_RULES.purpose[7] != null) {
RULE_HANDLES.push(registerActivityControl(ACTIVITY_REPORT_ANALYTICS, RULE_NAME, reportAnalyticsRule));
}
+ if (ACTIVE_RULES.feature[1] != null) {
+ RULE_HANDLES.push(registerActivityControl(ACTIVITY_TRANSMIT_PRECISE_GEO, RULE_NAME, transmitPreciseGeoRule));
+ }
+ RULE_HANDLES.push(registerActivityControl(ACTIVITY_TRANSMIT_EIDS, RULE_NAME, transmitEidsRule));
}
}
diff --git a/modules/getintentBidAdapter.js b/modules/getintentBidAdapter.js
index 25322d81f9b..2b6ea1c2c2a 100644
--- a/modules/getintentBidAdapter.js
+++ b/modules/getintentBidAdapter.js
@@ -1,4 +1,4 @@
-import { getBidIdParameter, isFn, isInteger } from '../src/utils.js';
+import {getBidIdParameter, isFn, isInteger} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
const BIDDER_CODE = 'getintent';
diff --git a/modules/gmosspBidAdapter.js b/modules/gmosspBidAdapter.js
index 8c90d0cccfe..559f9f77aaf 100644
--- a/modules/gmosspBidAdapter.js
+++ b/modules/gmosspBidAdapter.js
@@ -1,17 +1,16 @@
import {
createTrackPixelHtml,
deepAccess,
- deepSetValue,
- getBidIdParameter,
+ deepSetValue, getBidIdParameter,
getDNT,
getWindowTop,
isEmpty,
- logError,
- tryAppendQueryString
+ logError
} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
import {BANNER} from '../src/mediaTypes.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BIDDER_CODE = 'gmossp';
const ENDPOINT = 'https://sp.gmossp-sp.jp/hb/prebid/query.ad';
diff --git a/modules/goldbachBidAdapter.js b/modules/goldbachBidAdapter.js
index 4768931950c..8892df130df 100644
--- a/modules/goldbachBidAdapter.js
+++ b/modules/goldbachBidAdapter.js
@@ -1,15 +1,9 @@
import {Renderer} from '../src/Renderer.js';
import {
- chunk,
- convertCamelToUnderscore,
- convertTypes,
createTrackPixelHtml,
deepAccess,
deepClone,
- fill,
getBidRequest,
- getMaxValueFromArray,
- getMinValueFromArray,
getParameterByName,
isArray,
isArrayOfNums,
@@ -29,9 +23,12 @@ import {auctionManager} from '../src/auctionManager.js';
import {find, includes} from '../src/polyfill.js';
import {INSTREAM, OUTSTREAM} from '../src/video.js';
import {hasPurpose1Consent} from '../src/utils/gpdr.js';
-import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
-import { APPNEXUS_CATEGORY_MAPPING } from '../libraries/categoryTranslationMapping/index.js';
-import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusKeywords/anKeywords.js';
+import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
+import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js';
+import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const BIDDER_CODE = 'goldbach';
const URL = 'https://ib.adnxs.com/ut/v3/prebid';
@@ -971,7 +968,7 @@ function createAdPodRequest(tags, adPodBid) {
const { durationRangeSec, requireExactDuration } = adPodBid.mediaTypes.video;
const numberOfPlacements = getAdPodPlacementNumber(adPodBid.mediaTypes.video);
- const maxDuration = getMaxValueFromArray(durationRangeSec);
+ const maxDuration = Math.max(...durationRangeSec);
const tagToDuplicate = tags.filter(tag => tag.uuid === adPodBid.bidId);
let request = fill(...tagToDuplicate, numberOfPlacements);
@@ -997,7 +994,7 @@ function createAdPodRequest(tags, adPodBid) {
function getAdPodPlacementNumber(videoParams) {
const { adPodDurationSec, durationRangeSec, requireExactDuration } = videoParams;
- const minAllowedDuration = getMinValueFromArray(durationRangeSec);
+ const minAllowedDuration = Math.min(...durationRangeSec);
const numberOfPlacements = Math.floor(adPodDurationSec / minAllowedDuration);
return requireExactDuration
diff --git a/modules/growadvertisingBidAdapter.js b/modules/growadvertisingBidAdapter.js
index b9b256dbaff..f6f7867f0fe 100644
--- a/modules/growadvertisingBidAdapter.js
+++ b/modules/growadvertisingBidAdapter.js
@@ -1,6 +1,6 @@
'use strict';
-import { getBidIdParameter, deepAccess, _each, triggerPixel } from '../src/utils.js';
+import {deepAccess, _each, triggerPixel, getBidIdParameter} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
diff --git a/modules/growthCodeIdSystem.js b/modules/growthCodeIdSystem.js
index aec49c64fa3..e50a4e73019 100644
--- a/modules/growthCodeIdSystem.js
+++ b/modules/growthCodeIdSystem.js
@@ -5,11 +5,12 @@
* @requires module:modules/userId
*/
-import {logError, logInfo, pick, tryAppendQueryString} from '../src/utils.js';
+import {logError, logInfo, pick} from '../src/utils.js';
import {ajax} from '../src/ajax.js';
import { submodule } from '../src/hook.js'
import {getStorageManager} from '../src/storageManager.js';
import {MODULE_TYPE_UID} from '../src/activities/modules.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const MODULE_NAME = 'growthCodeId';
const GC_DATA_KEY = '_gc_data';
diff --git a/modules/growthCodeRtdProvider.js b/modules/growthCodeRtdProvider.js
index 370ace9a203..ef5c7906ad7 100644
--- a/modules/growthCodeRtdProvider.js
+++ b/modules/growthCodeRtdProvider.js
@@ -5,10 +5,11 @@
import { submodule } from '../src/hook.js'
import { getStorageManager } from '../src/storageManager.js';
import {
- logMessage, logError, tryAppendQueryString, mergeDeep
+ logMessage, logError, mergeDeep
} from '../src/utils.js';
import * as ajax from '../src/ajax.js';
import { MODULE_TYPE_RTD } from '../src/activities/modules.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const MODULE_NAME = 'growthCodeRtd';
const LOG_PREFIX = 'GrowthCodeRtd: ';
diff --git a/modules/holidBidAdapter.js b/modules/holidBidAdapter.js
index 2073063168d..fbcbb9492c7 100644
--- a/modules/holidBidAdapter.js
+++ b/modules/holidBidAdapter.js
@@ -1,7 +1,6 @@
import {
deepAccess,
- deepSetValue,
- getBidIdParameter,
+ deepSetValue, getBidIdParameter,
isStr,
logMessage,
triggerPixel,
diff --git a/modules/iasRtdProvider.js b/modules/iasRtdProvider.js
index 994be7c0804..b9de7ef4e46 100644
--- a/modules/iasRtdProvider.js
+++ b/modules/iasRtdProvider.js
@@ -1,7 +1,9 @@
-import { submodule } from '../src/hook.js';
+import {submodule} from '../src/hook.js';
import * as utils from '../src/utils.js';
-import { ajax } from '../src/ajax.js';
-import { getGlobal } from '../src/prebidGlobal.js';
+import {ajax} from '../src/ajax.js';
+import {getGlobal} from '../src/prebidGlobal.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
/** @type {string} */
const MODULE_NAME = 'realTimeData';
@@ -76,7 +78,7 @@ function getAdUnitPath(adSlot, bidRequest, adUnitPath) {
if (!utils.isEmpty(adSlot)) {
p = adSlot.gptSlot;
} else {
- if (!utils.isEmpty(adUnitPath) && utils.hasOwn(adUnitPath, bidRequest.code)) {
+ if (!utils.isEmpty(adUnitPath) && adUnitPath.hasOwnProperty(bidRequest.code)) {
if (utils.isStr(adUnitPath[bidRequest.code]) && !utils.isEmpty(adUnitPath[bidRequest.code])) {
p = adUnitPath[bidRequest.code];
}
@@ -86,13 +88,13 @@ function getAdUnitPath(adSlot, bidRequest, adUnitPath) {
}
function stringifySlot(bidRequest, adUnitPath) {
- const sizes = utils.getAdUnitSizes(bidRequest);
+ const sizes = getAdUnitSizes(bidRequest);
const id = bidRequest.code;
const ss = stringifySlotSizes(sizes);
- const adSlot = utils.getGptSlotInfoForAdUnitCode(bidRequest.code);
+ const adSlot = getGptSlotInfoForAdUnitCode(bidRequest.code);
const p = getAdUnitPath(adSlot, bidRequest, adUnitPath);
const slot = { id, ss, p };
- const keyValues = utils.getKeys(slot).map(function (key) {
+ const keyValues = Object.keys(slot).map(function (key) {
return [key, slot[key]].join(':');
});
return '{' + keyValues.join(',') + '}';
diff --git a/modules/imdsBidAdapter.js b/modules/imdsBidAdapter.js
index d6f3df94409..122662feb8a 100644
--- a/modules/imdsBidAdapter.js
+++ b/modules/imdsBidAdapter.js
@@ -1,10 +1,11 @@
'use strict';
-import {deepAccess, deepSetValue, getAdUnitSizes, isFn, isPlainObject, logWarn, mergeDeep} from '../src/utils.js';
+import {deepAccess, deepSetValue, isFn, isPlainObject, logWarn, mergeDeep} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {includes} from '../src/polyfill.js';
import {config} from '../src/config.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BID_SCHEME = 'https://';
const BID_DOMAIN = 'technoratimedia.com';
diff --git a/modules/ivsBidAdapter.js b/modules/ivsBidAdapter.js
index 47685fbbe46..6f4c024f09f 100644
--- a/modules/ivsBidAdapter.js
+++ b/modules/ivsBidAdapter.js
@@ -1,5 +1,5 @@
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
-import { deepAccess, deepSetValue, getBidIdParameter, logError } from '../src/utils.js';
+import {deepAccess, deepSetValue, getBidIdParameter, logError} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { VIDEO } from '../src/mediaTypes.js';
import { INSTREAM } from '../src/video.js';
diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js
index 50595152b23..6c5f90b7a2a 100644
--- a/modules/ixBidAdapter.js
+++ b/modules/ixBidAdapter.js
@@ -1,10 +1,8 @@
import {
contains,
- convertTypes,
deepAccess,
deepClone,
deepSetValue,
- getGptSlotInfoForAdUnitCode,
inIframe,
isArray,
isEmpty,
@@ -24,6 +22,8 @@ import { find } from '../src/polyfill.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { INSTREAM, OUTSTREAM } from '../src/video.js';
import { Renderer } from '../src/Renderer.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'ix';
const ALIAS_BIDDER_CODE = 'roundel';
diff --git a/modules/jixieBidAdapter.js b/modules/jixieBidAdapter.js
index 824bc3828b4..103c925a2f9 100644
--- a/modules/jixieBidAdapter.js
+++ b/modules/jixieBidAdapter.js
@@ -1,4 +1,4 @@
-import {deepAccess, getDNT, isArray, logWarn} from '../src/utils.js';
+import {deepAccess, getDNT, isArray, logWarn, isFn, isPlainObject} from '../src/utils.js';
import {config} from '../src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getStorageManager} from '../src/storageManager.js';
@@ -14,6 +14,27 @@ const JX_OUTSTREAM_RENDERER_URL = 'https://scripts.jixie.media/jxhbrenderer.1.1.
const REQUESTS_URL = 'https://hb.jixie.io/v2/hbpost';
const sidTTLMins_ = 30;
+/**
+ * Get bid floor from Price Floors Module
+ *
+ * @param {Object} bid
+ * @returns {float||null}
+ */
+function getBidFloor(bid) {
+ if (!isFn(bid.getFloor)) {
+ return null;
+ }
+ let floor = bid.getFloor({
+ currency: 'USD',
+ mediaType: '*',
+ size: '*'
+ });
+ if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') {
+ return floor.floor;
+ }
+ return null;
+}
+
/**
* Own miscellaneous support functions:
*/
@@ -56,7 +77,7 @@ function fetchIds_() {
if (tmp) ret.client_id_ls = tmp;
tmp = storage.getDataFromLocalStorage('_jxxs');
if (tmp) ret.session_id_ls = tmp;
- ['_jxtoko', '_jxifo', '_jxtdid', '__uid2_advertising_token'].forEach(function(n) {
+ ['_jxtoko', '_jxifo', '_jxtdid', '_jxcomp'].forEach(function(n) {
tmp = storage.getCookie(n);
if (tmp) ret.jxeids[n] = tmp;
});
@@ -171,9 +192,12 @@ export const spec = {
params: one.params,
gpid: gpid
};
+ let bidFloor = getBidFloor(one);
+ if (bidFloor) {
+ tmp.bidFloor = bidFloor;
+ }
bids.push(tmp);
});
-
let jixieCfgBlob = config.getConfig('jixie');
if (!jixieCfgBlob) {
jixieCfgBlob = {};
diff --git a/modules/kueezBidAdapter.js b/modules/kueezBidAdapter.js
index 0a868661310..5a5536e0c1a 100644
--- a/modules/kueezBidAdapter.js
+++ b/modules/kueezBidAdapter.js
@@ -1,4 +1,16 @@
-import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
+import {
+ logWarn,
+ logInfo,
+ isArray,
+ isFn,
+ deepAccess,
+ isEmpty,
+ contains,
+ timestamp,
+ triggerPixel,
+ isInteger,
+ getBidIdParameter
+} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
diff --git a/modules/lockerdomeBidAdapter.js b/modules/lockerdomeBidAdapter.js
index 5c38753c1e2..5038eadce30 100644
--- a/modules/lockerdomeBidAdapter.js
+++ b/modules/lockerdomeBidAdapter.js
@@ -1,6 +1,6 @@
-import { getBidIdParameter } from '../src/utils.js';
import {BANNER} from '../src/mediaTypes.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {getBidIdParameter} from '../src/utils.js';
export const spec = {
code: 'lockerdome',
diff --git a/modules/mediafuseBidAdapter.js b/modules/mediafuseBidAdapter.js
index 98179c49e0d..1fdd3530fae 100644
--- a/modules/mediafuseBidAdapter.js
+++ b/modules/mediafuseBidAdapter.js
@@ -1,14 +1,8 @@
import {
- chunk,
- convertCamelToUnderscore,
- convertTypes,
createTrackPixelHtml,
deepAccess,
deepClone,
- fill,
getBidRequest,
- getMaxValueFromArray,
- getMinValueFromArray,
getParameterByName,
isArray,
isArrayOfNums,
@@ -38,7 +32,10 @@ import {
getANKewyordParamFromMaps,
getANKeywordParam,
transformBidderParamKeywords
-} from '../libraries/appnexusKeywords/anKeywords.js';
+} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const BIDDER_CODE = 'mediafuse';
const URL = 'https://ib.adnxs.com/ut/v3/prebid';
@@ -959,7 +956,7 @@ function createAdPodRequest(tags, adPodBid) {
const { durationRangeSec, requireExactDuration } = adPodBid.mediaTypes.video;
const numberOfPlacements = getAdPodPlacementNumber(adPodBid.mediaTypes.video);
- const maxDuration = getMaxValueFromArray(durationRangeSec);
+ const maxDuration = Math.max(...durationRangeSec);
const tagToDuplicate = tags.filter(tag => tag.uuid === adPodBid.bidId);
let request = fill(...tagToDuplicate, numberOfPlacements);
@@ -985,7 +982,7 @@ function createAdPodRequest(tags, adPodBid) {
function getAdPodPlacementNumber(videoParams) {
const { adPodDurationSec, durationRangeSec, requireExactDuration } = videoParams;
- const minAllowedDuration = getMinValueFromArray(durationRangeSec);
+ const minAllowedDuration = Math.min(...durationRangeSec);
const numberOfPlacements = Math.floor(adPodDurationSec / minAllowedDuration);
return requireExactDuration
diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js
index 659da0c16fb..041db71cd34 100644
--- a/modules/medianetBidAdapter.js
+++ b/modules/medianetBidAdapter.js
@@ -1,7 +1,6 @@
import {
buildUrl,
deepAccess,
- getGptSlotInfoForAdUnitCode,
getWindowTop,
isArray,
isEmpty,
@@ -18,6 +17,7 @@ import {getRefererInfo} from '../src/refererDetection.js';
import {Renderer} from '../src/Renderer.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import {getGlobal} from '../src/prebidGlobal.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const BIDDER_CODE = 'medianet';
const TRUSTEDSTACK_CODE = 'trustedstack';
diff --git a/modules/mediasniperBidAdapter.js b/modules/mediasniperBidAdapter.js
index 378a804487a..aee5f6230b2 100644
--- a/modules/mediasniperBidAdapter.js
+++ b/modules/mediasniperBidAdapter.js
@@ -1,8 +1,7 @@
import {
deepAccess,
deepClone,
- deepSetValue,
- getBidIdParameter,
+ deepSetValue, getBidIdParameter,
inIframe,
isArray,
isEmpty,
diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js
index 8e889261e52..1e158236deb 100644
--- a/modules/mgidBidAdapter.js
+++ b/modules/mgidBidAdapter.js
@@ -9,11 +9,10 @@ import {
isEmpty,
triggerPixel,
logWarn,
- getBidIdParameter,
isFn,
isNumber,
isBoolean,
- isInteger, deepSetValue,
+ isInteger, deepSetValue, getBidIdParameter,
} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
diff --git a/modules/minutemediaBidAdapter.js b/modules/minutemediaBidAdapter.js
index bb0bb76bdbc..e67534d74fe 100644
--- a/modules/minutemediaBidAdapter.js
+++ b/modules/minutemediaBidAdapter.js
@@ -1,4 +1,16 @@
-import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
+import {
+ logWarn,
+ logInfo,
+ isArray,
+ isFn,
+ deepAccess,
+ isEmpty,
+ contains,
+ timestamp,
+ triggerPixel,
+ isInteger,
+ getBidIdParameter
+} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js
index cb660ad9fd6..0cbe954175c 100644
--- a/modules/nextMillenniumBidAdapter.js
+++ b/modules/nextMillenniumBidAdapter.js
@@ -1,8 +1,7 @@
import {
_each,
createTrackPixelHtml,
- deepAccess,
- getBidIdParameter,
+ deepAccess, getBidIdParameter,
getDefinedParams,
getWindowTop,
isArray,
diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js
index 0dd4b334f6e..eab174d22dd 100644
--- a/modules/nextrollBidAdapter.js
+++ b/modules/nextrollBidAdapter.js
@@ -1,6 +1,5 @@
import {
- deepAccess,
- getBidIdParameter,
+ deepAccess, getBidIdParameter,
isArray,
isFn,
isNumber,
diff --git a/modules/nexx360BidAdapter.js b/modules/nexx360BidAdapter.js
index 3d8e9c348c8..c65544936fa 100644
--- a/modules/nexx360BidAdapter.js
+++ b/modules/nexx360BidAdapter.js
@@ -190,7 +190,7 @@ function interpretResponse(serverResponse) {
demandSource: bid.ext.ssp,
},
};
- if (allowAlternateBidderCodes) response.bidderCode = `n360-${bid.ext.ssp}`;
+ if (allowAlternateBidderCodes) response.bidderCode = `n360_${bid.ext.ssp}`;
if (bid.ext.mediaType === BANNER) {
if (bid.adm) {
diff --git a/modules/oguryBidAdapter.js b/modules/oguryBidAdapter.js
index 4fd9b711b42..c1c8376de87 100644
--- a/modules/oguryBidAdapter.js
+++ b/modules/oguryBidAdapter.js
@@ -1,9 +1,10 @@
'use strict';
import {BANNER} from '../src/mediaTypes.js';
-import {getAdUnitSizes, getWindowSelf, getWindowTop, isFn, logWarn} from '../src/utils.js';
+import {getWindowSelf, getWindowTop, isFn, logWarn} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {ajax} from '../src/ajax.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'ogury';
const GVLID = 31;
diff --git a/modules/onomagicBidAdapter.js b/modules/onomagicBidAdapter.js
index edab625e541..78f00153a8b 100644
--- a/modules/onomagicBidAdapter.js
+++ b/modules/onomagicBidAdapter.js
@@ -1,7 +1,6 @@
import {
_each,
- createTrackPixelHtml,
- getBidIdParameter,
+ createTrackPixelHtml, getBidIdParameter,
getUniqueIdentifierStr,
getWindowSelf,
getWindowTop,
diff --git a/modules/open8BidAdapter.js b/modules/open8BidAdapter.js
index 5fa1dd0a143..49523926c0e 100644
--- a/modules/open8BidAdapter.js
+++ b/modules/open8BidAdapter.js
@@ -1,8 +1,9 @@
import { Renderer } from '../src/Renderer.js';
import {ajax} from '../src/ajax.js';
-import { createTrackPixelHtml, getBidIdParameter, logError, logWarn, tryAppendQueryString } from '../src/utils.js';
+import {createTrackPixelHtml, getBidIdParameter, logError, logWarn} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { VIDEO, BANNER } from '../src/mediaTypes.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BIDDER_CODE = 'open8';
const URL = 'https://as.vt.open8.com/v1/control/prebid';
diff --git a/modules/openwebBidAdapter.js b/modules/openwebBidAdapter.js
index 296bfc682f1..547447039da 100644
--- a/modules/openwebBidAdapter.js
+++ b/modules/openwebBidAdapter.js
@@ -1,8 +1,9 @@
-import {convertTypes, deepAccess, flatten, isArray, isNumber, parseSizesInput} from '../src/utils.js';
+import {deepAccess, flatten, isArray, isNumber, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {find} from '../src/polyfill.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const ENDPOINT = 'https://ghb.spotim.market/v2/auction';
const BIDDER_CODE = 'openweb';
diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js
index d206e70aac4..181a0c70c7e 100644
--- a/modules/openxBidAdapter.js
+++ b/modules/openxBidAdapter.js
@@ -4,6 +4,7 @@ import * as utils from '../src/utils.js';
import {mergeDeep} from '../src/utils.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {ortbConverter} from '../libraries/ortbConverter/converter.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const bidderConfig = 'hb_pb_ortb';
const bidderVersion = '2.0';
@@ -150,7 +151,7 @@ const converter = ortbConverter({
});
function transformBidParams(params, isOpenRtb) {
- return utils.convertTypes({
+ return convertTypes({
'unit': 'string',
'customFloor': 'number'
}, params);
diff --git a/modules/optidigitalBidAdapter.js b/modules/optidigitalBidAdapter.js
index 489f2c8264c..9f27ae49d1e 100755
--- a/modules/optidigitalBidAdapter.js
+++ b/modules/optidigitalBidAdapter.js
@@ -1,6 +1,7 @@
-import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { BANNER } from '../src/mediaTypes.js';
-import { deepAccess, parseSizesInput, getAdUnitSizes } from '../src/utils.js';
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {BANNER} from '../src/mediaTypes.js';
+import {deepAccess, parseSizesInput} from '../src/utils.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'optidigital';
const GVL_ID = 915;
diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js
index f135ebb2bd1..53fff39047f 100644
--- a/modules/orbidderBidAdapter.js
+++ b/modules/orbidderBidAdapter.js
@@ -1,11 +1,11 @@
import { isFn, isPlainObject } from '../src/utils.js';
-import {registerBidder} from '../src/adapters/bidderFactory.js';
+import { registerBidder } from '../src/adapters/bidderFactory.js';
import { getStorageManager } from '../src/storageManager.js';
import { BANNER, NATIVE } from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
-import {getGlobal} from '../src/prebidGlobal.js';
+import { getGlobal } from '../src/prebidGlobal.js';
-const storageManager = getStorageManager({bidderCode: 'orbidder'});
+const storageManager = getStorageManager({ bidderCode: 'orbidder' });
/**
* Determines whether or not the given bid response is valid.
@@ -69,7 +69,7 @@ export const spec = {
return !!(bid.sizes && bid.bidId && bid.params &&
(bid.params.accountId && (typeof bid.params.accountId === 'string')) &&
(bid.params.placementId && (typeof bid.params.placementId === 'string')) &&
- ((typeof bid.params.profile === 'undefined') || (typeof bid.params.profile === 'object')));
+ ((typeof bid.params.keyValues === 'undefined') || (typeof bid.params.keyValues === 'object')));
},
/**
diff --git a/modules/orbitsoftBidAdapter.js b/modules/orbitsoftBidAdapter.js
index 4c3f2e38c58..f55c7ff9917 100644
--- a/modules/orbitsoftBidAdapter.js
+++ b/modules/orbitsoftBidAdapter.js
@@ -1,5 +1,6 @@
import * as utils from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {getBidIdParameter} from '../src/utils.js';
const BIDDER_CODE = 'orbitsoft';
let styleParamsMap = {
@@ -45,10 +46,10 @@ export const spec = {
for (let i = 0; i < validBidRequests.length; i++) {
bidRequest = validBidRequests[i];
let bidRequestParams = bidRequest.params;
- let placementId = utils.getBidIdParameter('placementId', bidRequestParams);
- let requestUrl = utils.getBidIdParameter('requestUrl', bidRequestParams);
- let referrer = utils.getBidIdParameter('ref', bidRequestParams);
- let location = utils.getBidIdParameter('loc', bidRequestParams);
+ let placementId = getBidIdParameter('placementId', bidRequestParams);
+ let requestUrl = getBidIdParameter('requestUrl', bidRequestParams);
+ let referrer = getBidIdParameter('ref', bidRequestParams);
+ let location = getBidIdParameter('loc', bidRequestParams);
// Append location & referrer
if (location === '') {
location = utils.getWindowLocation();
@@ -58,7 +59,7 @@ export const spec = {
}
// Styles params
- let stylesParams = utils.getBidIdParameter('style', bidRequestParams);
+ let stylesParams = getBidIdParameter('style', bidRequestParams);
let stylesParamsArray = {};
for (let currentValue in stylesParams) {
if (stylesParams.hasOwnProperty(currentValue)) {
@@ -74,7 +75,7 @@ export const spec = {
}
}
// Custom params
- let customParams = utils.getBidIdParameter('customParams', bidRequestParams);
+ let customParams = getBidIdParameter('customParams', bidRequestParams);
let customParamsArray = {};
for (let customField in customParams) {
if (customParams.hasOwnProperty(customField)) {
diff --git a/modules/otmBidAdapter.js b/modules/otmBidAdapter.js
index 6125cee6593..7d4049e3054 100644
--- a/modules/otmBidAdapter.js
+++ b/modules/otmBidAdapter.js
@@ -2,14 +2,13 @@ import { registerBidder } from '../src/adapters/bidderFactory.js';
import {
logInfo,
logError,
- getBidIdParameter,
_each,
getValue,
isFn,
isPlainObject,
isArray,
isStr,
- isNumber,
+ isNumber, getBidIdParameter,
} from '../src/utils.js';
import { BANNER } from '../src/mediaTypes.js';
diff --git a/modules/pixfutureBidAdapter.js b/modules/pixfutureBidAdapter.js
index 608ba20aa5f..1c3f9b8da1a 100644
--- a/modules/pixfutureBidAdapter.js
+++ b/modules/pixfutureBidAdapter.js
@@ -3,10 +3,11 @@ import {getStorageManager} from '../src/storageManager.js';
import {BANNER} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {find, includes} from '../src/polyfill.js';
-import {convertCamelToUnderscore, deepAccess, isArray, isFn, isNumber, isPlainObject} from '../src/utils.js';
+import {deepAccess, isArray, isFn, isNumber, isPlainObject} from '../src/utils.js';
import {auctionManager} from '../src/auctionManager.js';
import {getGlobal} from '../src/prebidGlobal.js';
-import {getANKeywordParam} from '../libraries/appnexusKeywords/anKeywords.js';
+import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js';
const SOURCE = 'pbjs';
const storageManager = getStorageManager({bidderCode: 'pixfuture'});
diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js
index e49dfec2f1c..0fff93cdcd1 100644
--- a/modules/prebidServerBidAdapter/index.js
+++ b/modules/prebidServerBidAdapter/index.js
@@ -1,6 +1,6 @@
import Adapter from '../../src/adapter.js';
import {
- bind,
+ deepAccess,
deepClone,
flatten,
generateUUID,
@@ -15,7 +15,6 @@ import {
logWarn,
triggerPixel,
uniques,
- deepAccess,
} from '../../src/utils.js';
import CONSTANTS from '../../src/constants.json';
import adapterManager, {s2sActivityParams} from '../../src/adapterManager.js';
@@ -297,7 +296,7 @@ function doAllSyncs(bidders, s2sConfig) {
// if PBS reports this bidder doesn't have an ID, then call the sync and recurse to the next sync entry
if (thisSync.no_cookie) {
- doPreBidderSync(thisSync.usersync.type, thisSync.usersync.url, thisSync.bidder, bind.call(doAllSyncs, null, bidders, s2sConfig), s2sConfig);
+ doPreBidderSync(thisSync.usersync.type, thisSync.usersync.url, thisSync.bidder, doAllSyncs.bind(null, bidders, s2sConfig), s2sConfig);
} else {
// bidder already has an ID, so just recurse to the next sync entry
doAllSyncs(bidders, s2sConfig);
@@ -356,8 +355,7 @@ function doClientSideSyncs(bidders, gdprConsent, uspConsent, gppConsent) {
if (clientAdapter && clientAdapter.registerSyncs) {
config.runWithBidder(
bidder,
- bind.call(
- clientAdapter.registerSyncs,
+ clientAdapter.registerSyncs.bind(
clientAdapter,
[],
gdprConsent,
diff --git a/modules/priceFloors.js b/modules/priceFloors.js
index a72a79c2b40..07f8fbed45d 100644
--- a/modules/priceFloors.js
+++ b/modules/priceFloors.js
@@ -4,7 +4,6 @@ import {
deepClone,
deepSetValue,
generateUUID,
- getGptSlotInfoForAdUnitCode,
getParameterByName,
isNumber,
logError,
@@ -13,7 +12,8 @@ import {
mergeDeep,
parseGPTSingleSizeArray,
parseUrl,
- pick
+ pick,
+ deepEqual
} from '../src/utils.js';
import {getGlobal} from '../src/prebidGlobal.js';
import {config} from '../src/config.js';
@@ -28,6 +28,7 @@ import {auctionManager} from '../src/auctionManager.js';
import {IMP, PBS, registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js';
import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js';
import {adjustCpm} from '../src/utils/cpm.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
import {convertCurrency} from '../libraries/currencyUtils/currency.js';
/**
@@ -40,10 +41,13 @@ const MODULE_NAME = 'Price Floors';
*/
const ajax = ajaxBuilder(10000);
+// eslint-disable-next-line symbol-description
+const SYN_FIELD = Symbol();
+
/**
* @summary Allowed fields for rules to have
*/
-export let allowedFields = ['gptSlot', 'adUnitCode', 'size', 'domain', 'mediaType'];
+export let allowedFields = [SYN_FIELD, 'gptSlot', 'adUnitCode', 'size', 'domain', 'mediaType'];
/**
* @summary This is a flag to indicate if a AJAX call is processing for a floors request
@@ -104,6 +108,7 @@ function getAdUnitCode(request, response, {index = auctionManager.index} = {}) {
* @summary floor field types with their matching functions to resolve the actual matched value
*/
export let fieldMatchingFunctions = {
+ [SYN_FIELD]: () => '*',
'size': (bidRequest, bidResponse) => parseGPTSingleSizeArray(bidResponse.size) || '*',
'mediaType': (bidRequest, bidResponse) => bidResponse.mediaType || 'banner',
'gptSlot': (bidRequest, bidResponse) => getGptSlotFromAdUnit((bidRequest || bidResponse).transactionId) || getGptSlotInfoForAdUnitCode(getAdUnitCode(bidRequest, bidResponse)).gptSlot,
@@ -117,6 +122,7 @@ export let fieldMatchingFunctions = {
* Returns array of Tuple [exact match, catch all] for each field in rules file
*/
function enumeratePossibleFieldValues(floorFields, bidObject, responseObject) {
+ if (!floorFields.length) return [];
// generate combination of all exact matches and catch all for each field type
return floorFields.reduce((accum, field) => {
let exactMatch = fieldMatchingFunctions[field](bidObject, responseObject) || '*';
@@ -132,7 +138,9 @@ function enumeratePossibleFieldValues(floorFields, bidObject, responseObject) {
*/
export function getFirstMatchingFloor(floorData, bidObject, responseObject = {}) {
let fieldValues = enumeratePossibleFieldValues(deepAccess(floorData, 'schema.fields') || [], bidObject, responseObject);
- if (!fieldValues.length) return { matchingFloor: floorData.default };
+ if (!fieldValues.length) {
+ return {matchingFloor: undefined}
+ }
// look to see if a request for this context was made already
let matchingInput = fieldValues.map(field => field[0]).join('-');
@@ -146,9 +154,9 @@ export function getFirstMatchingFloor(floorData, bidObject, responseObject = {})
let matchingData = {
floorMin: floorData.floorMin || 0,
- floorRuleValue: isNaN(floorData.values[matchingRule]) ? floorData.default : floorData.values[matchingRule],
+ floorRuleValue: floorData.values[matchingRule],
matchingData: allPossibleMatches[0], // the first possible match is an "exact" so contains all data relevant for anlaytics adapters
- matchingRule
+ matchingRule: matchingRule === floorData.meta?.defaultRule ? undefined : matchingRule
};
// use adUnit floorMin as priority!
const floorMin = deepAccess(bidObject, 'ortb2Imp.ext.prebid.floors.floorMin');
@@ -300,14 +308,20 @@ function normalizeRulesForAuction(floorData, adUnitCode) {
* Only called if no set config or fetch level data has returned
*/
export function getFloorDataFromAdUnits(adUnits) {
+ const schemaAu = adUnits.find(au => au.floors?.schema != null);
return adUnits.reduce((accum, adUnit) => {
- if (isFloorsDataValid(adUnit.floors)) {
+ if (adUnit.floors?.schema != null && !deepEqual(adUnit.floors.schema, schemaAu?.floors?.schema)) {
+ logError(`${MODULE_NAME}: adUnit '${adUnit.code}' declares a different schema from one previously declared by adUnit '${schemaAu.code}'. Floor config for '${adUnit.code}' will be ignored.`)
+ return accum;
+ }
+ const floors = Object.assign({}, schemaAu?.floors, {values: undefined}, adUnit.floors)
+ if (isFloorsDataValid(floors)) {
// if values already exist we want to not overwrite them
if (!accum.values) {
- accum = getFloorsDataForAuction(adUnit.floors, adUnit.code);
+ accum = getFloorsDataForAuction(floors, adUnit.code);
accum.location = 'adUnit';
} else {
- let newRules = getFloorsDataForAuction(adUnit.floors, adUnit.code).values;
+ let newRules = getFloorsDataForAuction(floors, adUnit.code).values;
// copy over the new rules into our values object
Object.assign(accum.values, newRules);
}
@@ -443,7 +457,26 @@ function validateRules(floorsData, numFields, delimiter) {
return Object.keys(floorsData.values).length > 0;
}
+export function normalizeDefault(model) {
+ if (isNumber(model.default)) {
+ let defaultRule = '*';
+ const numFields = (model.schema?.fields || []).length;
+ if (!numFields) {
+ deepSetValue(model, 'schema.fields', [SYN_FIELD]);
+ } else {
+ defaultRule = Array(numFields).fill('*').join(model.schema?.delimiter || '|');
+ }
+ model.values = model.values || {};
+ if (model.values[defaultRule] == null) {
+ model.values[defaultRule] = model.default;
+ model.meta = {defaultRule};
+ }
+ }
+ return model;
+}
+
function modelIsValid(model) {
+ model = normalizeDefault(model);
// schema.fields has only allowed attributes
if (!validateSchemaFields(deepAccess(model, 'schema.fields'))) {
return false;
diff --git a/modules/prismaBidAdapter.js b/modules/prismaBidAdapter.js
index 7c9108f60b1..c13e6e1c330 100644
--- a/modules/prismaBidAdapter.js
+++ b/modules/prismaBidAdapter.js
@@ -2,7 +2,7 @@ import {ajax} from '../src/ajax.js';
import {config} from '../src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
-import {getANKeywordParam} from '../libraries/appnexusKeywords/anKeywords.js';
+import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js';
const BIDDER_CODE = 'prisma';
const BIDDER_URL = 'https://prisma.nexx360.io/prebid';
diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js
index 3391773a3d2..0651b373f12 100755
--- a/modules/pubmaticAnalyticsAdapter.js
+++ b/modules/pubmaticAnalyticsAdapter.js
@@ -1,10 +1,11 @@
-import { _each, pick, logWarn, isStr, isArray, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
+import {_each, isArray, isStr, logError, logWarn, pick} from '../src/utils.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import CONSTANTS from '../src/constants.json';
-import { ajax } from '../src/ajax.js';
-import { config } from '../src/config.js';
-import { getGlobal } from '../src/prebidGlobal.js';
+import {ajax} from '../src/ajax.js';
+import {config} from '../src/config.js';
+import {getGlobal} from '../src/prebidGlobal.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
/// /////////// CONSTANTS //////////////
const ADAPTER_CODE = 'pubmatic';
@@ -273,7 +274,8 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
'en': bid.bidResponse ? bid.bidResponse.bidPriceUSD : 0,
'di': bid.bidResponse ? (bid.bidResponse.dealId || OPEN_AUCTION_DEAL_ID) : OPEN_AUCTION_DEAL_ID,
'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING,
- 'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0,
+ 'l1': bid.bidResponse ? bid.partnerTimeToRespond : 0,
+ 'ol1': bid.bidResponse ? bid.clientLatencyTimeMs : 0,
'l2': 0,
'adv': bid.bidResponse ? getAdDomain(bid.bidResponse) || undefined : undefined,
'ss': isS2SBidder(bid.bidder),
@@ -507,6 +509,10 @@ function bidResponseHandler(args) {
bid.adId = args.adId;
bid.source = formatSource(bid.source || args.source);
setBidStatus(bid, args);
+ const latency = args?.timeToRespond || Date.now() - cache.auctions[args.auctionId].timestamp;
+ const auctionTime = cache.auctions[args.auctionId].timeout;
+ // Check if latency is greater than auctiontime+150, then log auctiontime+150 to avoid large numbers
+ bid.partnerTimeToRespond = latency > (auctionTime + 150) ? (auctionTime + 150) : latency;
bid.clientLatencyTimeMs = Date.now() - cache.auctions[args.auctionId].timestamp;
bid.bidResponse = parseBidResponse(args);
}
diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js
index a3833551fff..16d909c2fea 100644
--- a/modules/pubmaticBidAdapter.js
+++ b/modules/pubmaticBidAdapter.js
@@ -1,10 +1,11 @@
-import { getBidRequest, logWarn, isBoolean, isStr, isArray, inIframe, mergeDeep, deepAccess, isNumber, deepSetValue, logInfo, logError, deepClone, convertTypes, uniques, isPlainObject, isInteger } from '../src/utils.js';
+import { getBidRequest, logWarn, isBoolean, isStr, isArray, inIframe, mergeDeep, deepAccess, isNumber, deepSetValue, logInfo, logError, deepClone, uniques, isPlainObject, isInteger } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO, NATIVE, ADPOD } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
import { bidderSettings } from '../src/bidderSettings.js';
import CONSTANTS from '../src/constants.json';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'pubmatic';
const LOG_WARN_PREFIX = 'PubMatic: ';
@@ -1359,6 +1360,21 @@ export const spec = {
});
});
}
+ let fledgeAuctionConfigs = deepAccess(response.body, 'ext.fledge_auction_configs');
+ if (fledgeAuctionConfigs) {
+ fledgeAuctionConfigs = Object.entries(fledgeAuctionConfigs).map(([bidId, cfg]) => {
+ return {
+ bidId,
+ config: Object.assign({
+ auctionSignals: {},
+ }, cfg)
+ }
+ });
+ return {
+ bids: bidResponses,
+ fledgeAuctionConfigs,
+ }
+ }
} catch (error) {
logError(error);
}
diff --git a/modules/pubxaiAnalyticsAdapter.js b/modules/pubxaiAnalyticsAdapter.js
index 19a3c236942..e97e5505768 100644
--- a/modules/pubxaiAnalyticsAdapter.js
+++ b/modules/pubxaiAnalyticsAdapter.js
@@ -1,9 +1,10 @@
-import { deepAccess, getGptSlotInfoForAdUnitCode, parseSizesInput, getWindowLocation, buildUrl } from '../src/utils.js';
+import { deepAccess, parseSizesInput, getWindowLocation, buildUrl } from '../src/utils.js';
import { ajax } from '../src/ajax.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import CONSTANTS from '../src/constants.json';
import {getGlobal} from '../src/prebidGlobal.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const emptyUrl = '';
const analyticsType = 'endpoint';
diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js
index 7297c931326..516254b358b 100644
--- a/modules/pulsepointBidAdapter.js
+++ b/modules/pulsepointBidAdapter.js
@@ -1,6 +1,7 @@
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
-import {convertTypes, isArray} from '../src/utils.js';
+import {isArray} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const DEFAULT_CURRENCY = 'USD';
const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'battr', 'deals'];
diff --git a/modules/rasBidAdapter.js b/modules/rasBidAdapter.js
index a7aceb107b9..801457aa552 100644
--- a/modules/rasBidAdapter.js
+++ b/modules/rasBidAdapter.js
@@ -1,7 +1,8 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
-import { isEmpty, getAdUnitSizes, parseSizesInput, deepAccess } from '../src/utils.js';
+import { isEmpty, parseSizesInput, deepAccess } from '../src/utils.js';
import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'ras';
const VERSION = '1.0';
diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js
index b2961b09eb5..1e702d812f0 100644
--- a/modules/relaidoBidAdapter.js
+++ b/modules/relaidoBidAdapter.js
@@ -1,4 +1,14 @@
-import { deepAccess, logWarn, getBidIdParameter, parseQueryStringParameters, triggerPixel, generateUUID, isArray, isNumber, parseSizesInput } from '../src/utils.js';
+import {
+ deepAccess,
+ logWarn,
+ parseQueryStringParameters,
+ triggerPixel,
+ generateUUID,
+ isArray,
+ isNumber,
+ parseSizesInput,
+ getBidIdParameter
+} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { Renderer } from '../src/Renderer.js';
diff --git a/modules/revcontentBidAdapter.js b/modules/revcontentBidAdapter.js
index 5bf7dd691e7..f1d5521f780 100644
--- a/modules/revcontentBidAdapter.js
+++ b/modules/revcontentBidAdapter.js
@@ -3,9 +3,10 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
-import {_map, deepAccess, getAdUnitSizes, isFn, parseGPTSingleSizeArrayToRtbSize, triggerPixel} from '../src/utils.js';
+import {_map, deepAccess, isFn, parseGPTSingleSizeArrayToRtbSize, triggerPixel} from '../src/utils.js';
import {parseDomain} from '../src/refererDetection.js';
import {convertOrtbRequestToProprietaryNative} from '../src/native.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'revcontent';
const NATIVE_PARAMS = {
diff --git a/modules/riseBidAdapter.js b/modules/riseBidAdapter.js
index d5c6469db12..78740f7f87d 100644
--- a/modules/riseBidAdapter.js
+++ b/modules/riseBidAdapter.js
@@ -1,4 +1,16 @@
-import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
+import {
+ logWarn,
+ logInfo,
+ isArray,
+ isFn,
+ deepAccess,
+ isEmpty,
+ contains,
+ timestamp,
+ triggerPixel,
+ isInteger,
+ getBidIdParameter
+} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js
index 8e083a43505..4cfd40fb682 100644
--- a/modules/rubiconBidAdapter.js
+++ b/modules/rubiconBidAdapter.js
@@ -7,7 +7,6 @@ import { find } from '../src/polyfill.js';
import { getGlobal } from '../src/prebidGlobal.js';
import { Renderer } from '../src/Renderer.js';
import {
- convertTypes,
deepAccess,
deepSetValue,
formatQS,
@@ -21,6 +20,7 @@ import {
parseSizesInput, _each
} from '../src/utils.js';
import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const DEFAULT_INTEGRATION = 'pbjs_lite';
const DEFAULT_PBS_INTEGRATION = 'pbjs';
diff --git a/modules/schain.js b/modules/schain.js
index 2991bb5b3d5..726679b133f 100644
--- a/modules/schain.js
+++ b/modules/schain.js
@@ -1,16 +1,17 @@
-import { config } from '../src/config.js';
+import {config} from '../src/config.js';
import adapterManager from '../src/adapterManager.js';
import {
- isNumber,
- isStr,
+ _each,
+ deepAccess,
+ deepClone,
+ deepSetValue,
isArray,
+ isInteger,
+ isNumber,
isPlainObject,
- hasOwn,
+ isStr,
logError,
- isInteger,
- _each,
- logWarn,
- deepAccess, deepSetValue, deepClone
+ logWarn
} from '../src/utils.js';
import {registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js';
@@ -63,7 +64,7 @@ export function isSchainObjectValid(schainObject, returnOnError) {
}
// ext: Object [optional]
- if (hasOwn(schainObject, 'ext')) {
+ if (schainObject.hasOwnProperty('ext')) {
if (!isPlainObject(schainObject.ext)) {
appendFailMsg(`schain.config.ext` + shouldBeAnObject);
}
@@ -92,28 +93,28 @@ export function isSchainObjectValid(schainObject, returnOnError) {
}
// rid: String [Optional]
- if (hasOwn(node, 'rid')) {
+ if (node.hasOwnProperty('rid')) {
if (!isStr(node.rid)) {
appendFailMsg(`schain.config.nodes[${index}].rid` + shouldBeAString);
}
}
// name: String [Optional]
- if (hasOwn(node, 'name')) {
+ if (node.hasOwnProperty('name')) {
if (!isStr(node.name)) {
appendFailMsg(`schain.config.nodes[${index}].name` + shouldBeAString);
}
}
// domain: String [Optional]
- if (hasOwn(node, 'domain')) {
+ if (node.hasOwnProperty('domain')) {
if (!isStr(node.domain)) {
appendFailMsg(`schain.config.nodes[${index}].domain` + shouldBeAString);
}
}
// ext: Object [Optional]
- if (hasOwn(node, 'ext')) {
+ if (node.hasOwnProperty('ext')) {
if (!isPlainObject(node.ext)) {
appendFailMsg(`schain.config.nodes[${index}].ext` + shouldBeAnObject);
}
diff --git a/modules/sharethroughAnalyticsAdapter.js b/modules/sharethroughAnalyticsAdapter.js
index 6502c7e3a53..dc621e8da92 100644
--- a/modules/sharethroughAnalyticsAdapter.js
+++ b/modules/sharethroughAnalyticsAdapter.js
@@ -1,6 +1,6 @@
-import { tryAppendQueryString } from '../src/utils.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const emptyUrl = '';
const analyticsType = 'endpoint';
diff --git a/modules/shinezBidAdapter.js b/modules/shinezBidAdapter.js
index 96b6d281fdc..47fca317de2 100644
--- a/modules/shinezBidAdapter.js
+++ b/modules/shinezBidAdapter.js
@@ -1,4 +1,16 @@
-import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
+import {
+ logWarn,
+ logInfo,
+ isArray,
+ isFn,
+ deepAccess,
+ isEmpty,
+ contains,
+ timestamp,
+ triggerPixel,
+ isInteger,
+ getBidIdParameter
+} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js
index a241cb71a5d..a1e7df49d18 100644
--- a/modules/showheroes-bsBidAdapter.js
+++ b/modules/showheroes-bsBidAdapter.js
@@ -1,10 +1,9 @@
import {
deepAccess,
- getBidIdParameter,
getWindowTop,
triggerPixel,
logInfo,
- logError
+ logError, getBidIdParameter
} from '../src/utils.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
diff --git a/modules/slimcutBidAdapter.js b/modules/slimcutBidAdapter.js
index 447e314958f..c3f06556652 100644
--- a/modules/slimcutBidAdapter.js
+++ b/modules/slimcutBidAdapter.js
@@ -1,4 +1,4 @@
-import { getValue, parseSizesInput, getBidIdParameter } from '../src/utils.js';
+import {getBidIdParameter, getValue, parseSizesInput} from '../src/utils.js';
import {
registerBidder
} from '../src/adapters/bidderFactory.js';
diff --git a/modules/smaatoBidAdapter.js b/modules/smaatoBidAdapter.js
index 1b50e033074..b735953d099 100644
--- a/modules/smaatoBidAdapter.js
+++ b/modules/smaatoBidAdapter.js
@@ -1,22 +1,12 @@
-import {
- chunk,
- deepAccess,
- deepSetValue,
- fill,
- getAdUnitSizes,
- getDNT,
- getMaxValueFromArray,
- getMinValueFromArray,
- isEmpty,
- isNumber,
- logError,
- logInfo
-} from '../src/utils.js';
+import {deepAccess, deepSetValue, getDNT, isEmpty, isNumber, logError, logInfo} from '../src/utils.js';
import {find} from '../src/polyfill.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
import {ADPOD, BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import CONSTANTS from '../src/constants.json';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
+import {fill} from '../libraries/appnexusUtils/anUtils.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const { NATIVE_IMAGE_TYPES } = CONSTANTS;
const BIDDER_CODE = 'smaato';
@@ -466,7 +456,7 @@ function createAdPodImp(bidRequest, videoMediaType) {
});
} else {
// all maxdurations should be the same
- const maxDuration = getMaxValueFromArray(durationRangeSec);
+ const maxDuration = Math.max(...durationRangeSec);
imps.map((imp, index) => {
const sequence = index + 1;
imp.video.maxduration = maxDuration
@@ -481,7 +471,7 @@ function createAdPodImp(bidRequest, videoMediaType) {
function getAdPodNumberOfPlacements(videoMediaType) {
const {adPodDurationSec, durationRangeSec, requireExactDuration} = videoMediaType
- const minAllowedDuration = getMinValueFromArray(durationRangeSec)
+ const minAllowedDuration = Math.min(...durationRangeSec)
const numberOfPlacements = Math.floor(adPodDurationSec / minAllowedDuration)
return requireExactDuration
diff --git a/modules/smartxBidAdapter.js b/modules/smartxBidAdapter.js
index d91b62729bc..45cc45192ef 100644
--- a/modules/smartxBidAdapter.js
+++ b/modules/smartxBidAdapter.js
@@ -1,4 +1,17 @@
-import { logError, deepAccess, isArray, getBidIdParameter, getDNT, generateUUID, isEmpty, _each, logMessage, logWarn, isFn, isPlainObject } from '../src/utils.js';
+import {
+ logError,
+ deepAccess,
+ isArray,
+ getDNT,
+ generateUUID,
+ isEmpty,
+ _each,
+ logMessage,
+ logWarn,
+ isFn,
+ isPlainObject,
+ getBidIdParameter
+} from '../src/utils.js';
import {
Renderer
} from '../src/Renderer.js';
diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js
index b40ff9a65c9..a2d1f385623 100644
--- a/modules/sonobiBidAdapter.js
+++ b/modules/sonobiBidAdapter.js
@@ -1,11 +1,12 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { parseSizesInput, logError, generateUUID, isEmpty, deepAccess, logWarn, logMessage, getGptSlotInfoForAdUnitCode, isFn, isPlainObject } from '../src/utils.js';
+import { parseSizesInput, logError, generateUUID, isEmpty, deepAccess, logWarn, logMessage, isFn, isPlainObject } from '../src/utils.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
import { userSync } from '../src/userSync.js';
import { bidderSettings } from '../src/bidderSettings.js';
import { getAllOrtbKeywords } from '../libraries/keywords/keywords.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const BIDDER_CODE = 'sonobi';
const STR_ENDPOINT = 'https://apex.go.sonobi.com/trinity.json';
const PAGEVIEW_ID = generateUUID();
diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js
index 0d077ad2ae3..79481b81936 100644
--- a/modules/sovrnBidAdapter.js
+++ b/modules/sovrnBidAdapter.js
@@ -1,13 +1,12 @@
import {
_each,
- getBidIdParameter,
isArray,
getUniqueIdentifierStr,
deepSetValue,
logError,
deepAccess,
isInteger,
- logWarn
+ logWarn, getBidIdParameter
} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js'
import {
diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js
index 874207adcf8..017544cc596 100644
--- a/modules/spotxBidAdapter.js
+++ b/modules/spotxBidAdapter.js
@@ -1,4 +1,20 @@
-import { logError, deepAccess, isArray, getBidIdParameter, getDNT, deepSetValue, isEmpty, _each, logMessage, logWarn, isBoolean, isNumber, isPlainObject, isFn, setScriptAttributes } from '../src/utils.js';
+import {
+ logError,
+ deepAccess,
+ isArray,
+ getDNT,
+ deepSetValue,
+ isEmpty,
+ _each,
+ logMessage,
+ logWarn,
+ isBoolean,
+ isNumber,
+ isPlainObject,
+ isFn,
+ setScriptAttributes,
+ getBidIdParameter
+} from '../src/utils.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js
index 6107d1a6e66..5e92af640b8 100644
--- a/modules/teadsBidAdapter.js
+++ b/modules/teadsBidAdapter.js
@@ -1,4 +1,4 @@
-import { getValue, logError, deepAccess, getBidIdParameter, parseSizesInput, isArray } from '../src/utils.js';
+import {getValue, logError, deepAccess, parseSizesInput, isArray, getBidIdParameter} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getStorageManager} from '../src/storageManager.js';
diff --git a/modules/trafficgateBidAdapter.js b/modules/trafficgateBidAdapter.js
index 25289a19801..fcd84306099 100644
--- a/modules/trafficgateBidAdapter.js
+++ b/modules/trafficgateBidAdapter.js
@@ -1,7 +1,8 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {ortbConverter} from '../libraries/ortbConverter/converter.js';
-import {deepAccess, mergeDeep, convertTypes} from '../src/utils.js';
+import {deepAccess, mergeDeep} from '../src/utils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'trafficgate';
const URL = 'https://[HOST].bc-plugin.com/prebidjs'
diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js
index b6375243a5a..e976396c71c 100644
--- a/modules/trionBidAdapter.js
+++ b/modules/trionBidAdapter.js
@@ -1,6 +1,7 @@
-import { getBidIdParameter, parseSizesInput, tryAppendQueryString } from '../src/utils.js';
+import {getBidIdParameter, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import { getStorageManager } from '../src/storageManager.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const BID_REQUEST_BASE_URL = 'https://in-appadvertising.com/api/bidRequest';
const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.html';
diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js
index 22936ba750a..bfbf1409c1b 100644
--- a/modules/tripleliftBidAdapter.js
+++ b/modules/tripleliftBidAdapter.js
@@ -1,8 +1,9 @@
-import { tryAppendQueryString, logMessage, logError, isEmpty, isStr, isPlainObject, isArray, logWarn } from '../src/utils.js';
+import { logMessage, logError, isEmpty, isStr, isPlainObject, isArray, logWarn } from '../src/utils.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { getStorageManager } from '../src/storageManager.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
const GVLID = 28;
const BIDDER_CODE = 'triplelift';
diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js
index 7561cdb60de..4c2bdfe175f 100644
--- a/modules/underdogmediaBidAdapter.js
+++ b/modules/underdogmediaBidAdapter.js
@@ -4,7 +4,6 @@ import {
getWindowSelf,
getWindowTop,
isGptPubadsDefined,
- isSlotMatchingAdUnitCode,
logInfo,
logMessage,
logWarn,
@@ -12,6 +11,7 @@ import {
} from '../src/utils.js';
import {config} from '../src/config.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
const BIDDER_CODE = 'underdogmedia';
const UDM_ADAPTER_VERSION = '7.30V';
diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js
index fa1e2898a4a..05960378d23 100644
--- a/modules/vdoaiBidAdapter.js
+++ b/modules/vdoaiBidAdapter.js
@@ -1,6 +1,6 @@
-import {getAdUnitSizes} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const BIDDER_CODE = 'vdoai';
const ENDPOINT_URL = 'https://prebid.vdo.ai/auction';
diff --git a/modules/ventesBidAdapter.js b/modules/ventesBidAdapter.js
index 73ae0a7e5f1..78c580c4116 100644
--- a/modules/ventesBidAdapter.js
+++ b/modules/ventesBidAdapter.js
@@ -1,8 +1,9 @@
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
-import {convertCamelToUnderscore, isArray, isNumber, isPlainObject, isStr, replaceAuctionPrice} from '../src/utils.js';
+import {isArray, isNumber, isPlainObject, isStr, replaceAuctionPrice} from '../src/utils.js';
import {find} from '../src/polyfill.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
+import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js';
const BID_METHOD = 'POST';
const BIDDER_URL = 'https://ad.ventesavenues.in/va/ad';
diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js
index ba21a9c82d2..b5323181c6c 100644
--- a/modules/vidazooBidAdapter.js
+++ b/modules/vidazooBidAdapter.js
@@ -1,9 +1,10 @@
-import {_each, chunk, deepAccess, isFn, parseSizesInput, parseUrl, uniques, isArray} from '../src/utils.js';
+import {_each, deepAccess, isFn, parseSizesInput, parseUrl, uniques, isArray} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {getStorageManager} from '../src/storageManager.js';
import {bidderSettings} from '../src/bidderSettings.js';
import {config} from '../src/config.js';
+import {chunk} from '../libraries/chunk/chunk.js';
const GVLID = 744;
const DEFAULT_SUB_DOMAIN = 'prebid';
diff --git a/modules/videoreachBidAdapter.js b/modules/videoreachBidAdapter.js
index 9fd5853c75e..8835398d7cc 100644
--- a/modules/videoreachBidAdapter.js
+++ b/modules/videoreachBidAdapter.js
@@ -1,4 +1,4 @@
-import { getValue, getBidIdParameter } from '../src/utils.js';
+import {getBidIdParameter, getValue} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
const BIDDER_CODE = 'videoreach';
const ENDPOINT_URL = 'https://a.videoreach.com/hb/';
diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js
index c1bb626a39c..a45a1db9ece 100644
--- a/modules/visxBidAdapter.js
+++ b/modules/visxBidAdapter.js
@@ -1,9 +1,11 @@
-import { triggerPixel, parseSizesInput, deepAccess, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
-import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { config } from '../src/config.js';
-import { BANNER, VIDEO } from '../src/mediaTypes.js';
-import { INSTREAM as VIDEO_INSTREAM } from '../src/video.js';
+import {deepAccess, logError, parseSizesInput, triggerPixel} from '../src/utils.js';
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {config} from '../src/config.js';
+import {BANNER, VIDEO} from '../src/mediaTypes.js';
+import {INSTREAM as VIDEO_INSTREAM} from '../src/video.js';
import {getStorageManager} from '../src/storageManager.js';
+import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
+
const BIDDER_CODE = 'visx';
const GVLID = 154;
const BASE_URL = 'https://t.visx.net';
diff --git a/modules/weboramaRtdProvider.js b/modules/weboramaRtdProvider.js
index 6ba502d2c8b..14abba95323 100644
--- a/modules/weboramaRtdProvider.js
+++ b/modules/weboramaRtdProvider.js
@@ -109,8 +109,7 @@ import {
isBoolean,
isPlainObject,
logWarn,
- mergeDeep,
- tryAppendQueryString
+ mergeDeep
} from '../src/utils.js';
import {
submodule
@@ -123,6 +122,7 @@ import {
} from '../src/storageManager.js';
import adapterManager from '../src/adapterManager.js';
import {MODULE_TYPE_RTD} from '../src/activities/modules.js';
+import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js';
/** @type {string} */
const MODULE_NAME = 'realTimeData';
diff --git a/modules/winrBidAdapter.js b/modules/winrBidAdapter.js
index 5cc063d16b4..41efc432e11 100644
--- a/modules/winrBidAdapter.js
+++ b/modules/winrBidAdapter.js
@@ -1,6 +1,4 @@
import {
- convertCamelToUnderscore,
- convertTypes,
deepAccess,
getBidRequest,
getParameterByName,
@@ -16,7 +14,9 @@ import {BANNER} from '../src/mediaTypes.js';
import {find, includes} from '../src/polyfill.js';
import {getStorageManager} from '../src/storageManager.js';
import {hasPurpose1Consent} from '../src/utils/gpdr.js';
-import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusKeywords/anKeywords.js';
+import {getANKeywordParam, transformBidderParamKeywords} from '../libraries/appnexusUtils/anKeywords.js';
+import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js';
+import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js';
const BIDDER_CODE = 'winr';
const URL = 'https://ib.adnxs.com/ut/v3/prebid';
diff --git a/modules/xeBidAdapter.js b/modules/xeBidAdapter.js
index 94a66e9980e..6f527d905d6 100644
--- a/modules/xeBidAdapter.js
+++ b/modules/xeBidAdapter.js
@@ -1,7 +1,8 @@
import { config } from '../src/config.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { getAdUnitSizes, parseSizesInput, isFn, deepAccess, getBidIdParameter, logError, isArray } from '../src/utils.js';
+import {parseSizesInput, isFn, deepAccess, logError, isArray, getBidIdParameter} from '../src/utils.js';
+import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js';
const CUR = 'USD';
const BIDDER_CODE = 'xe';
diff --git a/modules/zeta_global_sspAnalyticsAdapter.js b/modules/zeta_global_sspAnalyticsAdapter.js
index 9609a047656..3d5466dd906 100644
--- a/modules/zeta_global_sspAnalyticsAdapter.js
+++ b/modules/zeta_global_sspAnalyticsAdapter.js
@@ -1,4 +1,4 @@
-import {logInfo, logError, deepClone} from '../src/utils.js';
+import {logInfo, logError} from '../src/utils.js';
import { ajax } from '../src/ajax.js';
import adapterManager from '../src/adapterManager.js';
import CONSTANTS from '../src/constants.json';
@@ -47,46 +47,25 @@ function getZetaParams(event) {
/// /////////// ADAPTER EVENT HANDLER FUNCTIONS //////////////
-function adRenderSucceededHandler(originalArgs) {
- const args = deepClone(originalArgs);
+function adRenderSucceededHandler(args) {
let eventType = CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED
logInfo(LOG_PREFIX + 'handle ' + eventType + ' event');
- if (args.bid) {
- // cleanup object
- delete args.bid.metrics;
- delete args.bid.ad;
-
- // set zetaParams from cache
- if (args.bid.auctionId) {
- const zetaParams = cache.auctions[args.bid.auctionId];
- if (zetaParams) {
- args.bid.params = [ zetaParams ];
- }
+ // set zetaParams from cache
+ if (args.bid && args.bid.auctionId) {
+ const zetaParams = cache.auctions[args.bid.auctionId];
+ if (zetaParams) {
+ args.bid.params = [ zetaParams ];
}
}
sendEvent(eventType, args);
}
-function auctionEndHandler(originalArgs) {
- const args = deepClone(originalArgs);
+function auctionEndHandler(args) {
let eventType = CONSTANTS.EVENTS.AUCTION_END;
logInfo(LOG_PREFIX + 'handle ' + eventType + ' event');
- // cleanup object
- delete args.metrics;
- if (args.bidderRequests) {
- args.bidderRequests.forEach(requests => {
- delete requests.metrics;
- if (requests.bids) {
- requests.bids.forEach(bid => {
- delete bid.metrics;
- })
- }
- })
- }
-
// save zetaParams to cache
const zetaParams = getZetaParams(args);
if (zetaParams && args.auctionId) {
diff --git a/package-lock.json b/package-lock.json
index dffd7c0b837..43935bca1ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "8.15.0-pre",
+ "version": "8.16.0-pre",
"lockfileVersion": 2,
"requires": true,
"packages": {
diff --git a/package.json b/package.json
index e2cc34a23ce..4b53b8e2c29 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "8.15.0-pre",
+ "version": "8.16.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
diff --git a/src/activities/redactor.js b/src/activities/redactor.js
index 5942ee17152..d052c029c13 100644
--- a/src/activities/redactor.js
+++ b/src/activities/redactor.js
@@ -8,7 +8,17 @@ import {
ACTIVITY_TRANSMIT_UFPD
} from './activities.js';
-export const ORTB_UFPD_PATHS = ['user.data', 'user.ext.data', 'user.yob', 'user.gender', 'user.keywords', 'user.kwarray'];
+export const ORTB_UFPD_PATHS = [
+ 'data',
+ 'ext.data',
+ 'yob',
+ 'gender',
+ 'keywords',
+ 'kwarray',
+ 'id',
+ 'buyeruid',
+ 'customdata'
+].map(f => `user.${f}`);
export const ORTB_EIDS_PATHS = ['user.eids', 'user.ext.eids'];
export const ORTB_GEO_PATHS = ['user.geo.lat', 'user.geo.lon', 'device.geo.lat', 'device.geo.lon'];
diff --git a/src/adapterManager.js b/src/adapterManager.js
index 554fde21734..575d28b35fa 100644
--- a/src/adapterManager.js
+++ b/src/adapterManager.js
@@ -1,8 +1,6 @@
/** @module adaptermanger */
import {
- _each,
- bind,
deepAccess,
deepClone,
flatten,
@@ -31,12 +29,7 @@ import {hook} from './hook.js';
import {find, includes} from './polyfill.js';
import {adunitCounter} from './adUnits.js';
import {getRefererInfo} from './refererDetection.js';
-import {
- GDPR_GVLIDS,
- gdprDataHandler,
- uspDataHandler,
- gppDataHandler,
-} from './consentHandler.js';
+import {GDPR_GVLIDS, gdprDataHandler, gppDataHandler, uspDataHandler, } from './consentHandler.js';
import * as events from './events.js';
import CONSTANTS from './constants.json';
import {useMetrics} from './utils/perfMetrics.js';
@@ -422,7 +415,7 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
bidRequest.start = timestamp();
return function () {
onTimelyResponse(bidRequest.bidderRequestId);
- doneCbs.apply(bidRequest, arguments);
+ doneCb.apply(bidRequest, arguments);
}
});
@@ -468,8 +461,7 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
try {
config.runWithBidder(
bidderRequest.bidderCode,
- bind.call(
- adapter.callBids,
+ adapter.callBids.bind(
adapter,
bidderRequest,
addBidResponse,
@@ -597,7 +589,7 @@ adapterManager.enableAnalytics = function (config) {
config = [config];
}
- _each(config, adapterConfig => {
+ config.forEach(adapterConfig => {
const entry = _analyticsRegistry[adapterConfig.provider];
if (entry && entry.adapter) {
if (dep.isAllowed(ACTIVITY_REPORT_ANALYTICS, activityParams(MODULE_TYPE_ANALYTICS, adapterConfig.provider, {[ACTIVITY_PARAM_ANL_CONFIG]: adapterConfig}))) {
diff --git a/src/auction.js b/src/auction.js
index c3712c0a4df..4bdd590f7ea 100644
--- a/src/auction.js
+++ b/src/auction.js
@@ -58,9 +58,6 @@
*/
import {
- _each,
- adUnitsFilter,
- bind,
deepAccess,
generateUUID,
getValue,
@@ -210,9 +207,8 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a
bidsBackCallback(_adUnits, function () {
try {
if (_callback != null) {
- const adUnitCodes = _adUnitCodes;
const bids = _bidsReceived
- .filter(bind.call(adUnitsFilter, this, adUnitCodes))
+ .filter(bid => _adUnitCodes.includes(bid.adUnitCode))
.reduce(groupByPlacement, {});
_callback.apply(pbjsInstance, [bids, timedOut, _auctionId]);
_callback = null;
@@ -945,7 +941,7 @@ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) {
var targeting = bidderSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING];
custBidObj.size = custBidObj.getSize();
- _each(targeting, function (kvPair) {
+ (targeting || []).forEach(function (kvPair) {
var key = kvPair.key;
var value = kvPair.val;
diff --git a/src/config.js b/src/config.js
index 48909d677e9..d4dc07989af 100644
--- a/src/config.js
+++ b/src/config.js
@@ -12,11 +12,20 @@
* @property {(string|Object)} [video-outstream]
*/
-import { isValidPriceConfig } from './cpmBucketManager.js';
-import {find, includes, arrayFrom as from} from './polyfill.js';
+import {isValidPriceConfig} from './cpmBucketManager.js';
+import {arrayFrom as from, find, includes} from './polyfill.js';
import {
- mergeDeep, deepClone, getParameterByName, isPlainObject, logMessage, logWarn, logError,
- isArray, isStr, isBoolean, deepAccess, bind
+ deepAccess,
+ deepClone,
+ getParameterByName,
+ isArray,
+ isBoolean,
+ isPlainObject,
+ isStr,
+ logError,
+ logMessage,
+ logWarn,
+ mergeDeep
} from './utils.js';
import CONSTANTS from './constants.json';
@@ -505,7 +514,7 @@ export function newConfig() {
return function(cb) {
return function(...args) {
if (typeof cb === 'function') {
- return runWithBidder(bidder, bind.call(cb, this, ...args))
+ return runWithBidder(bidder, cb.bind(this, ...args))
} else {
logWarn('config.callbackWithBidder callback is not a function');
}
diff --git a/src/events.js b/src/events.js
index bea5d4ee4d9..7a1e25e0e49 100644
--- a/src/events.js
+++ b/src/events.js
@@ -49,9 +49,7 @@ const _public = (function () {
let idPath = idPaths[eventString];
let key = eventPayload[idPath];
let event = _handlers[eventString] || { que: [] };
- let eventKeys = utils._map(event, function (v, k) {
- return k;
- });
+ var eventKeys = Object.keys(event);
let callbacks = [];
@@ -69,7 +67,7 @@ const _public = (function () {
* each function in the `que` array as an argument to push to the
* `callbacks` array
* */
- if (key && utils.contains(eventKeys, key)) {
+ if (key && eventKeys.includes(key)) {
push.apply(callbacks, event[key].que);
}
@@ -77,7 +75,7 @@ const _public = (function () {
push.apply(callbacks, event.que);
/** call each of the callbacks */
- utils._each(callbacks, function (fn) {
+ (callbacks || []).forEach(function (fn) {
if (!fn) return;
try {
fn.apply(null, args);
@@ -88,7 +86,7 @@ const _public = (function () {
}
function _checkAvailableEvent(event) {
- return utils.contains(allEvents, event);
+ return allEvents.includes(event)
}
_public.on = function (eventString, handler, id) {
@@ -126,14 +124,14 @@ const _public = (function () {
}
if (id) {
- utils._each(event[id].que, function (_handler) {
+ (event[id].que || []).forEach(function (_handler) {
let que = event[id].que;
if (_handler === handler) {
que.splice(que.indexOf(_handler), 1);
}
});
} else {
- utils._each(event.que, function (_handler) {
+ (event.que || []).forEach(function (_handler) {
let que = event.que;
if (_handler === handler) {
que.splice(que.indexOf(_handler), 1);
diff --git a/src/native.js b/src/native.js
index 1414c7a2ee7..c4709dd77e2 100644
--- a/src/native.js
+++ b/src/native.js
@@ -1,7 +1,6 @@
import {
deepAccess,
deepClone,
- getKeyByValue,
insertHtmlIntoIframe,
isArray,
isBoolean,
@@ -422,12 +421,14 @@ function assetsMessage(data, adObject, keys, {index = auctionManager.index} = {}
return message;
}
+const NATIVE_KEYS_INVERTED = Object.fromEntries(Object.entries(CONSTANTS.NATIVE_KEYS).map(([k, v]) => [v, k]));
+
/**
* Constructs a message object containing asset values for each of the
* requested data keys.
*/
export function getAssetMessage(data, adObject) {
- const keys = data.assets.map((k) => getKeyByValue(CONSTANTS.NATIVE_KEYS, k));
+ const keys = data.assets.map((k) => NATIVE_KEYS_INVERTED[k]);
return assetsMessage(data, adObject, keys);
}
diff --git a/src/prebid.js b/src/prebid.js
index decc2a7cef6..6ad5120ce82 100644
--- a/src/prebid.js
+++ b/src/prebid.js
@@ -2,10 +2,7 @@
import {getGlobal} from './prebidGlobal.js';
import {
- adUnitsFilter,
- bind,
callBurl,
- contains,
createInvisibleIframe,
deepAccess,
deepClone,
@@ -91,7 +88,7 @@ function checkDefinedPlacement(id) {
.reduce(flatten)
.filter(uniques);
- if (!contains(adUnitCodes, id)) {
+ if (!adUnitCodes.includes(id)) {
logError('The "' + id + '" placement is not defined.');
return;
}
@@ -345,7 +342,7 @@ pbjsInstance.getConsentMetadata = function () {
function getBids(type) {
const responses = auctionManager[type]()
- .filter(bind.call(adUnitsFilter, this, auctionManager.getAdUnitCodes()));
+ .filter(bid => auctionManager.getAdUnitCodes().includes(bid.adUnitCode))
// find the last auction id to get responses for most recent auction only
const currentAuctionId = auctionManager.getLastAuctionId();
diff --git a/src/utils.js b/src/utils.js
index c436b6385e7..256dfb15174 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,6 +1,6 @@
import {config} from './config.js';
import clone from 'just-clone';
-import {find, includes} from './polyfill.js';
+import {includes} from './polyfill.js';
import CONSTANTS from './constants.json';
import {GreedyPromise} from './utils/promise.js';
import {getGlobal} from './prebidGlobal.js';
@@ -8,7 +8,6 @@ import {getGlobal} from './prebidGlobal.js';
export { default as deepAccess } from 'dlv/index.js';
export { dset as deepSetValue } from 'dset';
-var tArr = 'Array';
var tStr = 'String';
var tFn = 'Function';
var tNumb = 'Number';
@@ -64,17 +63,6 @@ export function getPrebidInternal() {
return prebidInternal;
}
-var uniqueRef = {};
-export let bind = function(a, b) { return b; }.bind(null, 1, uniqueRef)() === uniqueRef
- ? Function.prototype.bind
- : function(bind) {
- var self = this;
- var args = Array.prototype.slice.call(arguments, 1);
- return function() {
- return self.apply(bind, args.concat(Array.prototype.slice.call(arguments)));
- };
- };
-
/* utility method to get incremental integer starting from 1 */
var getIncrementalInteger = (function () {
var count = 0;
@@ -114,19 +102,7 @@ function _getRandomData() {
}
export function getBidIdParameter(key, paramsObj) {
- if (paramsObj && paramsObj[key]) {
- return paramsObj[key];
- }
-
- return '';
-}
-
-export function tryAppendQueryString(existingUrl, key, value) {
- if (value) {
- return existingUrl + key + '=' + encodeURIComponent(value) + '&';
- }
-
- return existingUrl;
+ return paramsObj?.[key] || '';
}
// parse a query string object passed in bid params
@@ -145,84 +121,30 @@ export function parseQueryStringParameters(queryObj) {
export function transformAdServerTargetingObj(targeting) {
// we expect to receive targeting for a single slot at a time
if (targeting && Object.getOwnPropertyNames(targeting).length > 0) {
- return getKeys(targeting)
- .map(key => `${key}=${encodeURIComponent(getValue(targeting, key))}`).join('&');
+ return Object.keys(targeting)
+ .map(key => `${key}=${encodeURIComponent(targeting[key])}`).join('&');
} else {
return '';
}
}
-/**
- * Read an adUnit object and return the sizes used in an [[728, 90]] format (even if they had [728, 90] defined)
- * Preference is given to the `adUnit.mediaTypes.banner.sizes` object over the `adUnit.sizes`
- * @param {object} adUnit one adUnit object from the normal list of adUnits
- * @returns {Array.} array of arrays containing numeric sizes
- */
-export function getAdUnitSizes(adUnit) {
- if (!adUnit) {
- return;
- }
-
- let sizes = [];
- if (adUnit.mediaTypes && adUnit.mediaTypes.banner && Array.isArray(adUnit.mediaTypes.banner.sizes)) {
- let bannerSizes = adUnit.mediaTypes.banner.sizes;
- if (Array.isArray(bannerSizes[0])) {
- sizes = bannerSizes;
- } else {
- sizes.push(bannerSizes);
- }
- // TODO - remove this else block when we're ready to deprecate adUnit.sizes for bidders
- } else if (Array.isArray(adUnit.sizes)) {
- if (Array.isArray(adUnit.sizes[0])) {
- sizes = adUnit.sizes;
- } else {
- sizes.push(adUnit.sizes);
- }
- }
- return sizes;
-}
-
/**
* Parse a GPT-Style general size Array like `[[300, 250]]` or `"300x250,970x90"` into an array of sizes `["300x250"]` or '['300x250', '970x90']'
* @param {(Array.|Array.)} sizeObj Input array or double array [300,250] or [[300,250], [728,90]]
* @return {Array.} Array of strings like `["300x250"]` or `["300x250", "728x90"]`
*/
export function parseSizesInput(sizeObj) {
- var parsedSizes = [];
-
- // if a string for now we can assume it is a single size, like "300x250"
if (typeof sizeObj === 'string') {
// multiple sizes will be comma-separated
- var sizes = sizeObj.split(',');
-
- // regular expression to match strigns like 300x250
- // start of line, at least 1 number, an "x" , then at least 1 number, and the then end of the line
- var sizeRegex = /^(\d)+x(\d)+$/i;
- if (sizes) {
- for (var curSizePos in sizes) {
- if (hasOwn(sizes, curSizePos) && sizes[curSizePos].match(sizeRegex)) {
- parsedSizes.push(sizes[curSizePos]);
- }
- }
- }
+ return sizeObj.split(',').filter(sz => sz.match(/^(\d)+x(\d)+$/i))
} else if (typeof sizeObj === 'object') {
- var sizeArrayLength = sizeObj.length;
-
- // don't process empty array
- if (sizeArrayLength > 0) {
- // if we are a 2 item array of 2 numbers, we must be a SingleSize array
- if (sizeArrayLength === 2 && typeof sizeObj[0] === 'number' && typeof sizeObj[1] === 'number') {
- parsedSizes.push(parseGPTSingleSizeArray(sizeObj));
- } else {
- // otherwise, we must be a MultiSize array
- for (var i = 0; i < sizeArrayLength; i++) {
- parsedSizes.push(parseGPTSingleSizeArray(sizeObj[i]));
- }
- }
+ if (sizeObj.length === 2 && typeof sizeObj[0] === 'number' && typeof sizeObj[1] === 'number') {
+ return [parseGPTSingleSizeArray(sizeObj)];
+ } else {
+ return sizeObj.map(parseGPTSingleSizeArray)
}
}
-
- return parsedSizes;
+ return [];
}
// Parse a GPT style single size array, (i.e [300, 250])
@@ -345,6 +267,9 @@ export function createInvisibleIframe() {
f.frameBorder = '0';
f.src = 'about:blank';
f.style.display = 'none';
+ f.style.height = '0px';
+ f.style.width = '0px';
+ f.allowtransparency = 'true';
return f;
}
@@ -375,9 +300,7 @@ export function isStr(object) {
return isA(object, tStr);
}
-export function isArray(object) {
- return isA(object, tArr);
-}
+export const isArray = Array.isArray.bind(Array);
export function isNumber(object) {
return isA(object, tNumb);
@@ -402,12 +325,7 @@ export function isEmpty(object) {
if (isArray(object) || isStr(object)) {
return !(object.length > 0);
}
-
- for (var k in object) {
- if (hasOwnProperty.call(object, k)) return false;
- }
-
- return true;
+ return Object.keys(object).length <= 0;
}
/**
@@ -426,38 +344,12 @@ export function isEmptyStr(str) {
* @param {Function(value, key, object)} fn
*/
export function _each(object, fn) {
- if (isEmpty(object)) return;
- if (isFn(object.forEach)) return object.forEach(fn, this);
-
- var k = 0;
- var l = object.length;
-
- if (l > 0) {
- for (; k < l; k++) fn(object[k], k, object);
- } else {
- for (k in object) {
- if (hasOwnProperty.call(object, k)) fn.call(this, object[k], k);
- }
- }
+ if (isFn(object?.forEach)) return object.forEach(fn, this);
+ Object.entries(object || {}).forEach(([k, v]) => fn.call(this, v, k));
}
export function contains(a, obj) {
- if (isEmpty(a)) {
- return false;
- }
-
- if (isFn(a.indexOf)) {
- return a.indexOf(obj) !== -1;
- }
-
- var i = a.length;
- while (i--) {
- if (a[i] === obj) {
- return true;
- }
- }
-
- return false;
+ return isFn(a?.includes) && a.includes(obj);
}
/**
@@ -468,24 +360,10 @@ export function contains(a, obj) {
* @return {Array}
*/
export function _map(object, callback) {
- if (isEmpty(object)) return [];
- if (isFn(object.map)) return object.map(callback);
- var output = [];
- _each(object, function (value, key) {
- output.push(callback(value, key, object));
- });
-
- return output;
+ if (isFn(object?.map)) return object.map(callback);
+ return Object.entries(object || {}).map(([k, v]) => callback(v, k, object))
}
-export function hasOwn(objectToCheck, propertyToCheckFor) {
- if (objectToCheck.hasOwnProperty) {
- return objectToCheck.hasOwnProperty(propertyToCheckFor);
- } else {
- return (typeof objectToCheck[propertyToCheckFor] !== 'undefined') && (objectToCheck.constructor.prototype[propertyToCheckFor] !== objectToCheck[propertyToCheckFor]);
- }
-};
-
/*
* Inserts an element(elm) as targets child, by default as first child
* @param {HTMLElement} elm
@@ -568,27 +446,14 @@ export function insertHtmlIntoIframe(htmlCode) {
if (!htmlCode) {
return;
}
-
- let iframe = document.createElement('iframe');
- iframe.id = getUniqueIdentifierStr();
- iframe.width = 0;
- iframe.height = 0;
- iframe.hspace = '0';
- iframe.vspace = '0';
- iframe.marginWidth = '0';
- iframe.marginHeight = '0';
- iframe.style.display = 'none';
- iframe.style.height = '0px';
- iframe.style.width = '0px';
- iframe.scrolling = 'no';
- iframe.frameBorder = '0';
- iframe.allowtransparency = 'true';
-
+ const iframe = createInvisibleIframe();
internal.insertElement(iframe, document, 'body');
- iframe.contentWindow.document.open();
- iframe.contentWindow.document.write(htmlCode);
- iframe.contentWindow.document.close();
+ ((doc) => {
+ doc.open();
+ doc.write(htmlCode);
+ doc.close();
+ })(iframe.contentWindow.document);
}
/**
@@ -654,19 +519,6 @@ export function createTrackPixelIframeHtml(url, encodeUri = true, sandbox = '')
`;
}
-export function getValueString(param, val, defaultValue) {
- if (val === undefined || val === null) {
- return defaultValue;
- }
- if (isStr(val)) {
- return val;
- }
- if (isNumber(val)) {
- return val.toString();
- }
- internal.logWarn('Unsuported type for param: ' + param + ' required type: String');
-}
-
export function uniques(value, index, arry) {
return arry.indexOf(value) === index;
}
@@ -679,38 +531,14 @@ export function getBidRequest(id, bidderRequests) {
if (!id) {
return;
}
- let bidRequest;
- bidderRequests.some(bidderRequest => {
- let result = find(bidderRequest.bids, bid => ['bidId', 'adId', 'bid_id'].some(type => bid[type] === id));
- if (result) {
- bidRequest = result;
- }
- return result;
- });
- return bidRequest;
-}
-
-export function getKeys(obj) {
- return Object.keys(obj);
+ return bidderRequests.flatMap(br => br.bids)
+ .find(bid => ['bidId', 'adId', 'bid_id'].some(prop => bid[prop] === id))
}
export function getValue(obj, key) {
return obj[key];
}
-/**
- * Get the key of an object for a given value
- */
-export function getKeyByValue(obj, value) {
- for (let prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- if (obj[prop] === value) {
- return prop;
- }
- }
- }
-}
-
export function getBidderCodes(adUnits = pbjsInstance.adUnits) {
// this could memoize adUnits
return adUnits.map(unit => unit.bids.map(bid => bid.bidder)
@@ -755,10 +583,6 @@ export function shuffle(array) {
return array;
}
-export function adUnitsFilter(filter, bid) {
- return includes(filter, bid && bid.adUnitCode);
-}
-
export function deepClone(obj) {
return clone(obj);
}
@@ -917,7 +741,7 @@ export function getDNT() {
return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNotTrack === '1' || navigator.doNotTrack === 'yes';
}
-const compareCodeAndSlot = (slot, adUnitCode) => slot.getAdUnitPath() === adUnitCode || slot.getSlotElementId() === adUnitCode;
+export const compareCodeAndSlot = (slot, adUnitCode) => slot.getAdUnitPath() === adUnitCode || slot.getSlotElementId() === adUnitCode;
/**
* Returns filter function to match adUnitCode in slot
@@ -928,41 +752,6 @@ export function isAdUnitCodeMatchingSlot(slot) {
return (adUnitCode) => compareCodeAndSlot(slot, adUnitCode);
}
-/**
- * Returns filter function to match adUnitCode in slot
- * @param {string} adUnitCode AdUnit code
- * @return {function} filter function
- */
-export function isSlotMatchingAdUnitCode(adUnitCode) {
- return (slot) => compareCodeAndSlot(slot, adUnitCode);
-}
-
-/**
- * @summary Uses the adUnit's code in order to find a matching gpt slot object on the page
- */
-export function getGptSlotForAdUnitCode(adUnitCode) {
- let matchingSlot;
- if (isGptPubadsDefined()) {
- // find the first matching gpt slot on the page
- matchingSlot = find(window.googletag.pubads().getSlots(), isSlotMatchingAdUnitCode(adUnitCode));
- }
- return matchingSlot;
-};
-
-/**
- * @summary Uses the adUnit's code in order to find a matching gptSlot on the page
- */
-export function getGptSlotInfoForAdUnitCode(adUnitCode) {
- const matchingSlot = getGptSlotForAdUnitCode(adUnitCode);
- if (matchingSlot) {
- return {
- gptSlot: matchingSlot.getAdUnitPath(),
- divId: matchingSlot.getSlotElementId()
- }
- }
- return {};
-};
-
/**
* Constructs warning message for when unsupported bidders are dropped from an adunit
* @param {Object} adUnit ad unit from which the bidder is being dropped
@@ -984,33 +773,14 @@ export function unsupportedBidderMessage(adUnit, bidder) {
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
* @param {*} value
*/
-export function isInteger(value) {
- if (Number.isInteger) {
- return Number.isInteger(value);
- } else {
- return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
- }
-}
-
-/**
- * Converts a string value in camel-case to underscore eg 'placementId' becomes 'placement_id'
- * @param {string} value string value to convert
- */
-export function convertCamelToUnderscore(value) {
- return value.replace(/(?:^|\.?)([A-Z])/g, function (x, y) { return '_' + y.toLowerCase() }).replace(/^_/, '');
-}
+export const isInteger = Number.isInteger.bind(Number);
/**
* Returns a new object with undefined properties removed from given object
* @param obj the object to clean
*/
export function cleanObj(obj) {
- return Object.keys(obj).reduce((newObj, key) => {
- if (typeof obj[key] !== 'undefined') {
- newObj[key] = obj[key];
- }
- return newObj;
- }, {})
+ return Object.fromEntries(Object.entries(obj).filter(([_, v]) => typeof v !== 'undefined'))
}
/**
@@ -1047,104 +817,10 @@ export function pick(obj, properties) {
}, {});
}
-/**
- * Try to convert a value to a type.
- * If it can't be done, the value will be returned.
- *
- * @param {string} typeToConvert The target type. e.g. "string", "number", etc.
- * @param {*} value The value to be converted into typeToConvert.
- */
-function tryConvertType(typeToConvert, value) {
- if (typeToConvert === 'string') {
- return value && value.toString();
- } else if (typeToConvert === 'number') {
- return Number(value);
- } else {
- return value;
- }
-}
-
-export function convertTypes(types, params) {
- Object.keys(types).forEach(key => {
- if (params[key]) {
- if (isFn(types[key])) {
- params[key] = types[key](params[key]);
- } else {
- params[key] = tryConvertType(types[key], params[key]);
- }
-
- // don't send invalid values
- if (isNaN(params[key])) {
- delete params.key;
- }
- }
- });
- return params;
-}
-
export function isArrayOfNums(val, size) {
return (isArray(val)) && ((size) ? val.length === size : true) && (val.every(v => isInteger(v)));
}
-/**
- * Creates an array of n length and fills each item with the given value
- */
-export function fill(value, length) {
- let newArray = [];
-
- for (let i = 0; i < length; i++) {
- let valueToPush = isPlainObject(value) ? deepClone(value) : value;
- newArray.push(valueToPush);
- }
-
- return newArray;
-}
-
-/**
- * http://npm.im/chunk
- * Returns an array with *size* chunks from given array
- *
- * Example:
- * ['a', 'b', 'c', 'd', 'e'] chunked by 2 =>
- * [['a', 'b'], ['c', 'd'], ['e']]
- */
-export function chunk(array, size) {
- let newArray = [];
-
- for (let i = 0; i < Math.ceil(array.length / size); i++) {
- let start = i * size;
- let end = start + size;
- newArray.push(array.slice(start, end));
- }
-
- return newArray;
-}
-
-export function getMinValueFromArray(array) {
- return Math.min(...array);
-}
-
-export function getMaxValueFromArray(array) {
- return Math.max(...array);
-}
-
-/**
- * This function will create compare function to sort on object property
- * @param {string} property
- * @returns {function} compare function to be used in sorting
- */
-export function compareOn(property) {
- return function compare(a, b) {
- if (a[property] < b[property]) {
- return 1;
- }
- if (a[property] > b[property]) {
- return -1;
- }
- return 0;
- }
-}
-
export function parseQS(query) {
return !query ? {} : query
.replace(/^\?/, '')
@@ -1307,15 +983,6 @@ export function cyrb53Hash(str, seed = 0) {
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
}
-/**
- * returns a window object, which holds the provided document or null
- * @param {Document} doc
- * @returns {Window}
- */
-export function getWindowFromDocument(doc) {
- return (doc) ? doc.defaultView : null;
-}
-
/**
* returns the result of `JSON.parse(data)`, or undefined if that throws an error.
* @param data
@@ -1354,40 +1021,9 @@ export function memoize(fn, key = function (arg) { return arg; }) {
* @param {object} attributes
*/
export function setScriptAttributes(script, attributes) {
- for (let key in attributes) {
- if (attributes.hasOwnProperty(key)) {
- script.setAttribute(key, attributes[key]);
- }
- }
+ Object.entries(attributes).forEach(([k, v]) => script.setAttribute(k, v))
}
-/**
- * Encode a string for inclusion in HTML.
- * See https://pragmaticwebsecurity.com/articles/spasecurity/json-stringify-xss.html and
- * https://codeql.github.com/codeql-query-help/javascript/js-bad-code-sanitization/
- * @return {string}
- */
-export const escapeUnsafeChars = (() => {
- const escapes = {
- '<': '\\u003C',
- '>': '\\u003E',
- '/': '\\u002F',
- '\\': '\\\\',
- '\b': '\\b',
- '\f': '\\f',
- '\n': '\\n',
- '\r': '\\r',
- '\t': '\\t',
- '\0': '\\0',
- '\u2028': '\\u2028',
- '\u2029': '\\u2029'
- };
-
- return function(str) {
- return str.replace(/[<>\b\f\n\r\t\0\u2028\u2029\\]/g, x => escapes[x])
- }
-})();
-
/**
* Perform a binary search for `el` on an ordered array `arr`.
*
diff --git a/test/spec/appnexusKeywords_spec.js b/test/spec/appnexusKeywords_spec.js
index 9bf567a27c5..68faeff0b82 100644
--- a/test/spec/appnexusKeywords_spec.js
+++ b/test/spec/appnexusKeywords_spec.js
@@ -1,4 +1,4 @@
-import {transformBidderParamKeywords} from '../../libraries/appnexusKeywords/anKeywords.js';
+import {transformBidderParamKeywords} from '../../libraries/appnexusUtils/anKeywords.js';
import {expect} from 'chai/index.js';
import * as utils from '../../src/utils.js';
diff --git a/test/spec/libraries/sizeUtils_spec.js b/test/spec/libraries/sizeUtils_spec.js
new file mode 100644
index 00000000000..1c954c6accf
--- /dev/null
+++ b/test/spec/libraries/sizeUtils_spec.js
@@ -0,0 +1,30 @@
+import {getAdUnitSizes} from '../../../libraries/sizeUtils/sizeUtils.js';
+import {expect} from 'chai/index.js';
+
+describe('getAdUnitSizes', function () {
+ it('returns an empty response when adUnits is undefined', function () {
+ let sizes = getAdUnitSizes();
+ expect(sizes).to.be.undefined;
+ });
+
+ it('returns an empty array when invalid data is present in adUnit object', function () {
+ let sizes = getAdUnitSizes({sizes: 300});
+ expect(sizes).to.deep.equal([]);
+ });
+
+ it('retuns an array of arrays when reading from adUnit.sizes', function () {
+ let sizes = getAdUnitSizes({sizes: [300, 250]});
+ expect(sizes).to.deep.equal([[300, 250]]);
+
+ sizes = getAdUnitSizes({sizes: [[300, 250], [300, 600]]});
+ expect(sizes).to.deep.equal([[300, 250], [300, 600]]);
+ });
+
+ it('returns an array of arrays when reading from adUnit.mediaTypes.banner.sizes', function () {
+ let sizes = getAdUnitSizes({mediaTypes: {banner: {sizes: [300, 250]}}});
+ expect(sizes).to.deep.equal([[300, 250]]);
+
+ sizes = getAdUnitSizes({mediaTypes: {banner: {sizes: [[300, 250], [300, 600]]}}});
+ expect(sizes).to.deep.equal([[300, 250], [300, 600]]);
+ });
+});
diff --git a/test/spec/libraries/urlUtils_spec.js b/test/spec/libraries/urlUtils_spec.js
new file mode 100644
index 00000000000..9dd66b05407
--- /dev/null
+++ b/test/spec/libraries/urlUtils_spec.js
@@ -0,0 +1,24 @@
+import {tryAppendQueryString} from '../../../libraries/urlUtils/urlUtils.js';
+import assert from 'assert';
+
+describe('tryAppendQueryString', function () {
+ it('should append query string to existing url', function () {
+ var url = 'www.a.com?';
+ var key = 'b';
+ var value = 'c';
+
+ var output = tryAppendQueryString(url, key, value);
+
+ var expectedResult = url + key + '=' + encodeURIComponent(value) + '&';
+ assert.equal(output, expectedResult);
+ });
+
+ it('should return existing url, if the value is empty', function () {
+ var url = 'www.a.com?';
+ var key = 'b';
+ var value = '';
+
+ var output = tryAppendQueryString(url, key, value);
+ assert.equal(output, url);
+ });
+});
diff --git a/test/spec/modules/a1MediaBidAdapter_spec.js b/test/spec/modules/a1MediaBidAdapter_spec.js
new file mode 100644
index 00000000000..060fe3b5a65
--- /dev/null
+++ b/test/spec/modules/a1MediaBidAdapter_spec.js
@@ -0,0 +1,220 @@
+import { spec } from 'modules/a1MediaBidAdapter.js';
+import { config } from 'src/config.js';
+import { BANNER, VIDEO, NATIVE } from 'src/mediaTypes.js';
+import 'modules/currency.js';
+import 'modules/priceFloors.js';
+
+const ortbBlockParams = {
+ battr: [ 13 ],
+ bcat: ['IAB1-1']
+};
+const getBidderRequest = (isMulti = false) => {
+ return {
+ bidderCode: 'a1media',
+ auctionId: 'ba87bfdf-493e-4a88-8e26-17b4cbc9adbd',
+ bidderRequestId: '104e8d2392bd6f',
+ bids: [
+ {
+ bidder: 'a1media',
+ params: {},
+ auctionId: 'ba87bfdf-493e-4a88-8e26-17b4cbc9adbd',
+ mediaTypes: {
+ banner: {
+ sizes: [
+ [ 320, 100 ],
+ ]
+ },
+ ...(isMulti && {
+ video: {
+ mimes: ['video/mp4']
+ },
+ native: {
+ title: {
+ required: true,
+ }}
+ })
+ },
+ ...(isMulti && {
+ nativeOrtbRequest: {
+ ver: '1.2',
+ assets: [
+ {
+ id: 0,
+ required: 1,
+ title: {
+ len: 140
+ }
+ }
+ ]
+ }
+ }),
+ adUnitCode: 'test-div',
+ transactionId: 'cab00498-028b-4061-8f9d-a8d66c8cb91d',
+ bidId: '2e9f38ea93bb9e',
+ bidderRequestId: '104e8d2392bd6f',
+ }
+ ],
+ }
+};
+const getConvertedBidReq = () => {
+ return {
+ cur: [
+ 'JPY'
+ ],
+ imp: [
+ {
+ banner: {
+ format: [
+ {
+ h: 100,
+ w: 320
+ },
+ ],
+ topframe: 0
+ },
+ bidfloor: 0,
+ bidfloorcur: 'JPY',
+ id: '2e9f38ea93bb9e'
+ }
+ ],
+ test: 0,
+ }
+};
+
+const getBidderResponse = () => {
+ return {
+ body: {
+ id: 'bid-response',
+ cur: 'JPY',
+ seatbid: [
+ {
+ bid: [{
+ impid: '2e9f38ea93bb9e',
+ crid: 'creative-id',
+ cur: 'JPY',
+ price: 9,
+ }]
+ }
+ ]
+ }
+ }
+}
+const bannerAdm = '';
+const videoAdm = 'testvast1';
+const nativeAdm = '{"ver":"1.2","link":{"url":"test_url"},"assets":[{"id":1,"required":1,"title":{"text":"native_title"}}]}';
+
+describe('a1MediaBidAdapter', function() {
+ describe('isValidRequest', function() {
+ const bid = {
+ bidder: 'a1media',
+ };
+
+ it('should return true always', function () {
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+ });
+
+ describe('buildRequests', function() {
+ let bidderRequest, convertedRequest;
+ beforeEach(function() {
+ bidderRequest = getBidderRequest();
+ convertedRequest = getConvertedBidReq();
+ });
+
+ it('should return expected request object', function() {
+ const bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ convertedRequest.id = bidRequest.data.id;
+
+ expect(bidRequest.method).equal('POST');
+ expect(bidRequest.url).equal('https://d11.contentsfeed.com/dsp/breq/a1');
+ expect(bidRequest.data).deep.equal(convertedRequest);
+ });
+ it('should set ortb blocking using params', function() {
+ bidderRequest.bids[0].params = ortbBlockParams;
+
+ const bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ convertedRequest.id = bidRequest.data.id;
+ convertedRequest.bcat = ortbBlockParams.bcat;
+ convertedRequest.imp[0].banner.battr = ortbBlockParams.battr;
+
+ expect(bidRequest.data).deep.equal(convertedRequest);
+ });
+
+ it('should set bidfloor when getFloor is available', function() {
+ bidderRequest.bids[0].getFloor = () => ({ currency: 'USD', floor: 999 });
+ const bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+
+ expect(bidRequest.data.imp[0].bidfloor).equal(999);
+ expect(bidRequest.data.imp[0].bidfloorcur).equal('USD');
+ });
+
+ it('should set cur when currency config is configured', function() {
+ config.setConfig({
+ currency: {
+ adServerCurrency: 'USD',
+ }
+ });
+ const bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+
+ expect(bidRequest.data.cur[0]).equal('USD');
+ });
+
+ it('should set bidfloor and currency using params when modules not available', function() {
+ bidderRequest.bids[0].params.currency = 'USD';
+ bidderRequest.bids[0].params.bidfloor = 0.99;
+
+ const bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ convertedRequest.id = bidRequest.data.id;
+ convertedRequest.imp[0].bidfloor = 0.99;
+ convertedRequest.imp[0].bidfloorcur = 'USD';
+ convertedRequest.cur[0] = 'USD';
+
+ expect(bidRequest.data).deep.equal(convertedRequest);
+ });
+ });
+
+ describe('interpretResponse', function() {
+ describe('when request mediaType is single', function() {
+ let bidRequest, bidderResponse;
+ beforeEach(function() {
+ const bidderRequest = getBidderRequest();
+ bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ bidderResponse = getBidderResponse();
+ });
+ it('should set cpm using price attribute', function() {
+ const bidResPrice = 9;
+ bidderResponse.body.seatbid[0].bid[0].price = bidResPrice;
+ const interpretedRes = spec.interpretResponse(bidderResponse, bidRequest);
+ expect(interpretedRes[0].cpm).equal(bidResPrice);
+ });
+ it('should set mediaType using request mediaTypes', function() {
+ const interpretedRes = spec.interpretResponse(bidderResponse, bidRequest);
+ expect(interpretedRes[0].mediaType).equal(BANNER);
+ });
+ });
+
+ describe('when request mediaType is multi', function() {
+ let bidRequest, bidderResponse;
+ beforeEach(function() {
+ const bidderRequest = getBidderRequest(true);
+ bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ bidderResponse = getBidderResponse();
+ });
+ it('should set mediaType to video', function() {
+ bidderResponse.body.seatbid[0].bid[0].adm = videoAdm;
+ const interpretedRes = spec.interpretResponse(bidderResponse, bidRequest);
+ expect(interpretedRes[0].mediaType).equal(VIDEO);
+ });
+ it('should set mediaType to native', function() {
+ bidderResponse.body.seatbid[0].bid[0].adm = nativeAdm;
+ const interpretedRes = spec.interpretResponse(bidderResponse, bidRequest);
+ expect(interpretedRes[0].mediaType).equal(NATIVE);
+ });
+ it('should set mediaType to banner when adm is neither native or video', function() {
+ bidderResponse.body.seatbid[0].bid[0].adm = bannerAdm;
+ const interpretedRes = spec.interpretResponse(bidderResponse, bidRequest);
+ expect(interpretedRes[0].mediaType).equal(BANNER);
+ });
+ });
+ });
+})
diff --git a/test/spec/modules/adfusionBidAdapter_spec.js b/test/spec/modules/adfusionBidAdapter_spec.js
new file mode 100644
index 00000000000..638831c33f3
--- /dev/null
+++ b/test/spec/modules/adfusionBidAdapter_spec.js
@@ -0,0 +1,97 @@
+import { expect } from 'chai';
+import { spec } from 'modules/adfusionBidAdapter';
+import 'modules/priceFloors.js';
+import { newBidder } from 'src/adapters/bidderFactory';
+
+describe('adfusionBidAdapter', function () {
+ const adapter = newBidder(spec);
+ describe('inherited functions', function () {
+ it('exists and is a function', function () {
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
+ });
+ });
+
+ describe('isBidRequestValid', function () {
+ const bid = {
+ bidder: 'adfusion',
+ params: {
+ accountId: 1234,
+ },
+ adUnitCode: '/adunit-code/test-path',
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1',
+ transactionId: 'test-transactionId-1',
+ };
+
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+
+ it('should return false when params.accountID is missing', function () {
+ let localbid = Object.assign({}, bid);
+ delete localbid.params.accountId;
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ let bidRequests, bidderRequest;
+ beforeEach(function () {
+ bidRequests = [
+ {
+ bidder: 'adfusion',
+ params: {
+ accountId: 1234,
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [
+ [300, 250],
+ [300, 600],
+ ],
+ },
+ },
+ adUnitCode: '/adunit-code/test-path',
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1',
+ transactionId: 'test-transactionId-1',
+ },
+ {
+ bidder: 'adfusion',
+ params: {
+ accountId: 1234,
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480],
+ },
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2',
+ transactionId: 'test-transactionId-2',
+ },
+ ];
+ bidderRequest = { refererInfo: {} };
+ });
+
+ it('should return an empty array when no bid requests', function () {
+ const bidRequest = spec.buildRequests([], bidderRequest);
+ expect(bidRequest).to.be.an('array');
+ expect(bidRequest.length).to.equal(0);
+ });
+
+ it('should return a valid bid request object', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request).to.be.an('array');
+ expect(request[0].data).to.be.an('object');
+ expect(request[0].method).to.equal('POST');
+ expect(request[0].url).to.not.equal('');
+ expect(request[0].url).to.not.equal(undefined);
+ expect(request[0].url).to.not.equal(null);
+ });
+ });
+});
diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js
index de77c741364..ffd6729397a 100644
--- a/test/spec/modules/adyoulikeBidAdapter_spec.js
+++ b/test/spec/modules/adyoulikeBidAdapter_spec.js
@@ -2,6 +2,7 @@ import { expect } from 'chai';
import { spec } from 'modules/adyoulikeBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
+import { config } from 'src/config.js';
describe('Adyoulike Adapter', function () {
const canonicalUrl = 'https://canonical.url/?t=%26';
@@ -887,4 +888,115 @@ describe('Adyoulike Adapter', function () {
expect(spec.gvlid).to.equal(259)
})
});
+
+ describe('getUserSyncs', function () {
+ const syncurl_iframe = 'https://visitor.omnitagjs.com/visitor/isync?uid=19340f4f097d16f41f34fc0274981ca4';
+
+ const emptySync = [];
+
+ describe('with iframe enabled', function() {
+ const userSyncConfig = { iframeEnabled: true };
+
+ it('should not add parameters if not provided', function() {
+ expect(spec.getUserSyncs(userSyncConfig, {}, undefined, undefined)).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}`
+ }]);
+ });
+
+ it('should add GDPR parameters if provided', function() {
+ expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=`
+ }]);
+
+ expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: 'foo?'}, undefined)).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo%3F`
+ }]);
+ expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: false, consentString: 'bar'}, undefined)).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&gdpr=0&gdpr_consent=bar`
+ }]);
+ });
+
+ it('should add CCPA parameters if provided', function() {
+ expect(spec.getUserSyncs(userSyncConfig, {}, undefined, 'foo?')).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&us_privacy=foo%3F`
+ }]);
+ });
+
+ describe('COPPA', function() {
+ let sandbox;
+
+ this.beforeEach(function() {
+ sandbox = sinon.sandbox.create();
+ });
+
+ this.afterEach(function() {
+ sandbox.restore();
+ });
+
+ it('should add coppa parameters if provided', function() {
+ sandbox.stub(config, 'getConfig').callsFake(key => {
+ const config = {
+ 'coppa': true
+ };
+ return config[key];
+ });
+
+ expect(spec.getUserSyncs(userSyncConfig, {}, undefined, undefined)).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&coppa=1`
+ }]);
+ });
+ });
+
+ describe('GPP', function() {
+ it('should not apply if not gppConsent.gppString', function() {
+ const gppConsent = { gppString: '', applicableSections: [123] };
+ const result = spec.getUserSyncs(userSyncConfig, {}, undefined, undefined, gppConsent);
+ expect(result).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}`
+ }]);
+ });
+
+ it('should not apply if not gppConsent.applicableSections', function() {
+ const gppConsent = { gppString: '', applicableSections: undefined };
+ const result = spec.getUserSyncs(userSyncConfig, {}, undefined, undefined, gppConsent);
+ expect(result).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}`
+ }]);
+ });
+
+ it('should not apply if empty gppConsent.applicableSections', function() {
+ const gppConsent = { gppString: '', applicableSections: [] };
+ const result = spec.getUserSyncs(userSyncConfig, {}, undefined, undefined, gppConsent);
+ expect(result).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}`
+ }]);
+ });
+
+ it('should apply if all above are available', function() {
+ const gppConsent = { gppString: 'foo?', applicableSections: [123] };
+ const result = spec.getUserSyncs(userSyncConfig, {}, undefined, undefined, gppConsent);
+ expect(result).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&gpp=foo%3F&gpp_sid=123`
+ }]);
+ });
+
+ it('should support multiple sections', function() {
+ const gppConsent = { gppString: 'foo', applicableSections: [123, 456] };
+ const result = spec.getUserSyncs(userSyncConfig, {}, undefined, undefined, gppConsent);
+ expect(result).to.deep.equal([{
+ type: 'iframe', url: `${syncurl_iframe}&gpp=foo&gpp_sid=123%2C456`
+ }]);
+ });
+ });
+ });
+
+ describe('with iframe disabled', function() {
+ const userSyncConfig = { iframeEnabled: false };
+
+ it('should return empty list of syncs', function() {
+ expect(spec.getUserSyncs(userSyncConfig, {}, undefined, undefined)).to.deep.equal(emptySync);
+ expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: 'foo'}, 'bar')).to.deep.equal(emptySync);
+ });
+ });
+ });
});
diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js
index 08f00186358..3101fac7500 100644
--- a/test/spec/modules/alkimiBidAdapter_spec.js
+++ b/test/spec/modules/alkimiBidAdapter_spec.js
@@ -112,7 +112,15 @@ describe('alkimiBidAdapter', function () {
vendorData: {},
gdprApplies: true
},
- uspConsent: 'uspConsent'
+ uspConsent: 'uspConsent',
+ ortb2: {
+ site: {
+ keywords: 'test1, test2'
+ },
+ at: 2,
+ bcat: ['BSW1', 'BSW2'],
+ wseat: ['16', '165']
+ }
}
const bidderRequest = spec.buildRequests(bidRequests, requestData)
@@ -138,6 +146,7 @@ describe('alkimiBidAdapter', function () {
expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined)
expect(bidderRequest.data.bidIds).to.deep.contains('456')
expect(bidderRequest.data.signature).to.equal(undefined)
+ expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2' }, })
expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true })
expect(bidderRequest.options.contentType).to.equal('application/json')
expect(bidderRequest.url).to.equal(ENDPOINT)
diff --git a/test/spec/modules/fledgeForGpt_spec.js b/test/spec/modules/fledgeForGpt_spec.js
index 0bcd7753e55..b4bff8e82f0 100644
--- a/test/spec/modules/fledgeForGpt_spec.js
+++ b/test/spec/modules/fledgeForGpt_spec.js
@@ -5,6 +5,7 @@ import * as fledge from 'modules/fledgeForGpt.js';
import {config} from '../../../src/config.js';
import adapterManager from '../../../src/adapterManager.js';
import * as utils from '../../../src/utils.js';
+import * as gptUtils from '../../../libraries/gptUtils/gptUtils.js';
import {hook} from '../../../src/hook.js';
import 'modules/appnexusBidAdapter.js';
import 'modules/rubiconBidAdapter.js';
@@ -40,7 +41,7 @@ describe('fledgeForGpt module', () => {
setConfig: sinon.stub(),
getAdUnitPath: () => 'mock/gpt/au'
};
- sandbox.stub(utils, 'getGptSlotForAdUnitCode').callsFake(() => mockGptSlot);
+ sandbox.stub(gptUtils, 'getGptSlotForAdUnitCode').callsFake(() => mockGptSlot);
});
it('should call next()', function () {
@@ -55,8 +56,8 @@ describe('fledgeForGpt module', () => {
fledge.addComponentAuctionHook(nextFnSpy, 'aid', 'au1', cf1);
fledge.addComponentAuctionHook(nextFnSpy, 'aid', 'au2', cf2);
events.emit(CONSTANTS.EVENTS.AUCTION_END, {auctionId: 'aid'});
- sinon.assert.calledWith(utils.getGptSlotForAdUnitCode, 'au1');
- sinon.assert.calledWith(utils.getGptSlotForAdUnitCode, 'au2');
+ sinon.assert.calledWith(gptUtils.getGptSlotForAdUnitCode, 'au1');
+ sinon.assert.calledWith(gptUtils.getGptSlotForAdUnitCode, 'au2');
sinon.assert.calledWith(mockGptSlot.setConfig, {
componentAuction: [{
configKey: 'b1',
diff --git a/test/spec/modules/gdprEnforcement_spec.js b/test/spec/modules/gdprEnforcement_spec.js
index 1d0eee923b9..2880b2fac5d 100644
--- a/test/spec/modules/gdprEnforcement_spec.js
+++ b/test/spec/modules/gdprEnforcement_spec.js
@@ -1,13 +1,12 @@
import {
accessDeviceRule,
- deviceAccessHook,
- enforcementRules,
enrichEidsRule,
fetchBidsRule,
+ transmitEidsRule,
+ transmitPreciseGeoRule,
getGvlid,
getGvlidFromAnalyticsAdapter,
- purpose1Rule,
- purpose2Rule,
+ ACTIVE_RULES,
reportAnalyticsRule,
setEnforcementConfig,
STRICT_STORAGE_ENFORCEMENT,
@@ -474,6 +473,261 @@ describe('gdpr enforcement', function () {
});
});
+ describe('transmitEidsRule', () => {
+ const GVL_ID = 123;
+ const BIDDER = 'mockBidder';
+ let cd;
+ const RULES_2_10 = {
+ basicAds: 2,
+ personalizedAds: 4,
+ measurement: 7,
+ }
+
+ beforeEach(() => {
+ cd = setupConsentData();
+ cd.vendorData = {
+ vendor: {
+ consents: {},
+ legitimateInterests: {},
+ },
+ purpose: {
+ consents: {},
+ legitimateInterests: {}
+ }
+ };
+ Object.assign(gvlids, {
+ [BIDDER]: GVL_ID
+ });
+ });
+
+ function setVendorConsent(type = 'consents') {
+ cd.vendorData.vendor[type][GVL_ID] = true;
+ }
+
+ function runRule() {
+ return transmitEidsRule(activityParams(MODULE_TYPE_BIDDER, BIDDER));
+ }
+
+ describe('default behavior', () => {
+ const CS_PURPOSES = [3, 4, 5, 6, 7, 8, 9, 10];
+ const LI_PURPOSES = [2];
+ const CONSENT_TYPES = ['consents', 'legitimateInterests'];
+
+ describe('should deny if', () => {
+ describe('config is default', () => {
+ beforeEach(() => {
+ setEnforcementConfig({});
+ });
+
+ it('no consent is given, of any type or for any vendor', () => {
+ expectAllow(false, runRule());
+ });
+
+ CONSENT_TYPES.forEach(type => {
+ it(`vendor ${type} is given, but no purpose has consent`, () => {
+ setVendorConsent(type);
+ expectAllow(false, runRule());
+ });
+
+ it(`${type} is given for purpose other than 2-10`, () => {
+ setVendorConsent(type);
+ cd.vendorData.purpose[type][1] = true;
+ expectAllow(false, runRule());
+ });
+
+ LI_PURPOSES.forEach(purpose => {
+ it(`purpose ${purpose} has ${type}, but vendor does not`, () => {
+ cd.vendorData.purpose[type][purpose] = true;
+ expectAllow(false, runRule());
+ });
+ });
+ });
+ });
+
+ describe(`no consent is given`, () => {
+ [
+ {
+ enforcePurpose: false,
+ },
+ {
+ enforceVendor: false,
+ },
+ {
+ enforcePurpose: false,
+ enforceVendor: false,
+ }
+ ].forEach(t => {
+ it(`config has ${JSON.stringify(t)} for each of ${Object.keys(RULES_2_10).join(', ')}`, () => {
+ setEnforcementConfig({
+ gdpr: {
+ rules: Object.keys(RULES_2_10).map(rule => Object.assign({
+ purpose: rule,
+ vendorExceptions: [],
+ enforcePurpose: true,
+ enforceVendor: true
+ }, t))
+ }
+ });
+ expectAllow(false, runRule());
+ });
+ });
+ });
+ });
+
+ describe('should allow if', () => {
+ describe('config is default', () => {
+ beforeEach(() => {
+ setEnforcementConfig({});
+ });
+ LI_PURPOSES.forEach(purpose => {
+ it(`purpose ${purpose} has LI, vendor has LI`, () => {
+ setVendorConsent('legitimateInterests');
+ cd.vendorData.purpose.legitimateInterests[purpose] = true;
+ expectAllow(true, runRule());
+ });
+ });
+
+ LI_PURPOSES.concat(CS_PURPOSES).forEach(purpose => {
+ it(`purpose ${purpose} has consent, vendor has consent`, () => {
+ setVendorConsent();
+ cd.vendorData.purpose.consents[purpose] = true;
+ expectAllow(true, runRule());
+ });
+ });
+ });
+
+ Object.keys(RULES_2_10).forEach(rule => {
+ it(`no consent given, but '${rule}' config has a vendor exception`, () => {
+ setEnforcementConfig({
+ gdpr: {
+ rules: [
+ {
+ purpose: rule,
+ enforceVendor: false,
+ enforcePurpose: false,
+ vendorExceptions: [BIDDER]
+ }
+ ]
+ }
+ });
+ expectAllow(true, runRule());
+ });
+
+ it(`vendor consent is missing, but '${rule}' config has a softVendorException`, () => {
+ setEnforcementConfig({
+ gdpr: {
+ rules: [
+ {
+ purpose: rule,
+ enforceVendor: false,
+ enforcePurpose: false,
+ softVendorExceptions: [BIDDER]
+ }
+ ]
+ }
+ });
+ cd.vendorData.purpose.consents[RULES_2_10[rule]] = true;
+ expectAllow(true, runRule());
+ })
+ });
+ });
+ });
+
+ describe('with eidsRequireP4consent', () => {
+ function setupPAdsRule(cfg = {}) {
+ setEnforcementConfig({
+ gdpr: {
+ rules: [
+ Object.assign({
+ purpose: 'personalizedAds',
+ eidsRequireP4Consent: true,
+ enforcePurpose: true,
+ enforceVendor: true,
+ }, cfg)
+ ]
+ }
+ })
+ }
+ describe('allows when', () => {
+ Object.entries({
+ 'purpose 4 consent is given'() {
+ setupPAdsRule();
+ setVendorConsent();
+ cd.vendorData.purpose.consents[4] = true
+ },
+ 'enforcePurpose is false, with vendor consent given'() {
+ setupPAdsRule({enforcePurpose: false});
+ setVendorConsent();
+ },
+ 'enforceVendor is false, with purpose consent given'() {
+ setupPAdsRule({enforceVendor: false});
+ cd.vendorData.purpose.consents[4] = true;
+ },
+ 'vendor is excepted'() {
+ setupPAdsRule({vendorExceptions: [BIDDER]});
+ },
+ 'vendor is softly excepted, with purpose consent given'() {
+ setupPAdsRule({softVendorExceptions: [BIDDER]});
+ cd.vendorData.purpose.consents[4] = true;
+ }
+ }).forEach(([t, setup]) => {
+ it(t, () => {
+ setup();
+ expectAllow(true, runRule());
+ });
+ });
+ });
+ describe('denies when', () => {
+ Object.entries({
+ 'purpose 4 consent is not given'() {
+ setupPAdsRule();
+ setVendorConsent();
+ },
+ 'vendor consent is not given'() {
+ setupPAdsRule();
+ cd.vendorData.purpose.consents[4] = true
+ },
+ }).forEach(([t, setup]) => {
+ it(t, () => {
+ setup();
+ expectAllow(false, runRule());
+ })
+ })
+ })
+ })
+ });
+
+ describe('transmitPreciseGeoRule', () => {
+ const BIDDER = 'mockBidder';
+ let cd;
+
+ function runRule() {
+ return transmitPreciseGeoRule(activityParams(MODULE_TYPE_BIDDER, BIDDER))
+ }
+
+ beforeEach(() => {
+ cd = setupConsentData();
+ setEnforcementConfig({
+ gdpr: {
+ rules: [{
+ purpose: 'transmitPreciseGeo',
+ enforcePurpose: true,
+ enforceVendor: false
+ }]
+ }
+ })
+ });
+
+ it('should allow when special feature 1 consent is given', () => {
+ cd.vendorData.specialFeatureOptins[1] = true;
+ expectAllow(true, runRule());
+ })
+ it('should deny when configured, but consent is missing', () => {
+ cd.vendorData.specialFeatureOptins[1] = false;
+ expectAllow(false, runRule());
+ });
+ });
+
describe('validateRules', function () {
const createGdprRule = (purposeName = 'storage', enforcePurpose = true, enforceVendor = true, vendorExceptions = [], softVendorExceptions = []) => ({
purpose: purposeName,
@@ -631,7 +885,8 @@ describe('gdpr enforcement', function () {
});
expect(logWarnSpy.calledOnce).to.equal(true);
- expect(enforcementRules).to.deep.equal(DEFAULT_RULES);
+ expect(ACTIVE_RULES.purpose[1]).to.deep.equal(DEFAULT_RULES[0]);
+ expect(ACTIVE_RULES.purpose[2]).to.deep.equal(DEFAULT_RULES[1]);
});
it('should enforce TCF2 Purpose 2 also if only Purpose 1 is defined in "rules"', function () {
@@ -647,8 +902,8 @@ describe('gdpr enforcement', function () {
}
});
- expect(purpose1Rule).to.deep.equal(purpose1RuleDefinedInConfig);
- expect(purpose2Rule).to.deep.equal(DEFAULT_RULES[1]);
+ expect(ACTIVE_RULES.purpose[1]).to.deep.equal(purpose1RuleDefinedInConfig);
+ expect(ACTIVE_RULES.purpose[2]).to.deep.equal(DEFAULT_RULES[1]);
});
it('should enforce TCF2 Purpose 1 also if only Purpose 2 is defined in "rules"', function () {
@@ -664,8 +919,8 @@ describe('gdpr enforcement', function () {
}
});
- expect(purpose1Rule).to.deep.equal(DEFAULT_RULES[0]);
- expect(purpose2Rule).to.deep.equal(purpose2RuleDefinedInConfig);
+ expect(ACTIVE_RULES.purpose[1]).to.deep.equal(DEFAULT_RULES[0]);
+ expect(ACTIVE_RULES.purpose[2]).to.deep.equal(purpose2RuleDefinedInConfig);
});
it('should use the "rules" defined in config if a definition found', function() {
@@ -679,8 +934,8 @@ describe('gdpr enforcement', function () {
enforceVendor: false
}]
setEnforcementConfig({gdpr: { rules }});
-
- expect(enforcementRules).to.deep.equal(rules);
+ expect(ACTIVE_RULES.purpose[1]).to.deep.equal(rules[0]);
+ expect(ACTIVE_RULES.purpose[2]).to.deep.equal(rules[1]);
});
});
diff --git a/test/spec/modules/jixieBidAdapter_spec.js b/test/spec/modules/jixieBidAdapter_spec.js
index 4a0fa3b4d57..fd0d7e8a033 100644
--- a/test/spec/modules/jixieBidAdapter_spec.js
+++ b/test/spec/modules/jixieBidAdapter_spec.js
@@ -2,6 +2,7 @@ import { expect } from 'chai';
import { spec, internal as jixieaux, storage } from 'modules/jixieBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
import { config } from 'src/config.js';
+import { deepClone } from 'src/utils.js';
describe('jixie Adapter', function () {
const pageurl_ = 'https://testdomain.com/testpage.html';
@@ -74,13 +75,13 @@ describe('jixie Adapter', function () {
const jxtokoTest1_ = 'eyJJRCI6ImFiYyJ9';
const jxifoTest1_ = 'fffffbbbbbcccccaaaaae890606aaaaa';
const jxtdidTest1_ = '222223d1-1111-2222-3333-b9f129299999';
- const __uid2_advertising_token_Test1 = 'AAAAABBBBBCCCCCDDDDDEEEEEUkkZPQfifpkPnnlJhtsa4o+gf4nfqgN5qHiTVX73ymTSbLT9jz1nf+Q7QdxNh9nTad9UaN5pzfHMt/rs1woQw72c1ip+8heZXPfKGZtZP7ldJesYhlo3/0FVcL/wl9ZlAo1jYOEfHo7Y9zFzNXABbbbbb==';
+ const jxcompTest1_ = 'AAAAABBBBBCCCCCDDDDDEEEEEUkkZPQfifpkPnnlJhtsa4o+gf4nfqgN5qHiTVX73ymTSbLT9jz1nf+Q7QdxNh9nTad9UaN5pzfHMt/rs1woQw72c1ip+8heZXPfKGZtZP7ldJesYhlo3/0FVcL/wl9ZlAo1jYOEfHo7Y9zFzNXABbbbbb==';
const refJxEids_ = {
'_jxtoko': jxtokoTest1_,
'_jxifo': jxifoTest1_,
'_jxtdid': jxtdidTest1_,
- '__uid2_advertising_token': __uid2_advertising_token_Test1
+ '_jxcomp': jxcompTest1_
};
// to serve as the object that prebid will call jixie buildRequest with: (param2)
@@ -237,8 +238,8 @@ describe('jixie Adapter', function () {
.withArgs('_jxtdid')
.returns(jxtdidTest1_);
getCookieStub
- .withArgs('__uid2_advertising_token')
- .returns(__uid2_advertising_token_Test1);
+ .withArgs('_jxcomp')
+ .returns(jxcompTest1_);
getCookieStub
.withArgs('_jxx')
.returns(clientIdTest1_);
@@ -345,6 +346,22 @@ describe('jixie Adapter', function () {
expect(payload.schain).to.deep.include(schain);
});
+ it('it should populate the floor info when available', function () {
+ let oneSpecialBidReq = deepClone(bidRequests_[0]);
+ let request, payload = null;
+ // 1 floor is not set
+ request = spec.buildRequests([oneSpecialBidReq], bidderRequest_);
+ payload = JSON.parse(request.data);
+ expect(payload.bids[0].bidFloor).to.not.exist;
+
+ // 2 floor is set
+ let getFloorResponse = { currency: 'USD', floor: 2.1 };
+ oneSpecialBidReq.getFloor = () => getFloorResponse;
+ request = spec.buildRequests([oneSpecialBidReq], bidderRequest_);
+ payload = JSON.parse(request.data);
+ expect(payload.bids[0].bidFloor).to.exist.and.to.equal(2.1);
+ });
+
it('should populate eids when supported userIds are available', function () {
const oneSpecialBidReq = Object.assign({}, bidRequests_[0], {
userIdAsEids: [
diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js
index acb779b436d..5af5a4d710f 100644
--- a/test/spec/modules/orbidderBidAdapter_spec.js
+++ b/test/spec/modules/orbidderBidAdapter_spec.js
@@ -1,6 +1,6 @@
-import {expect} from 'chai';
-import {spec} from 'modules/orbidderBidAdapter.js';
-import {newBidder} from 'src/adapters/bidderFactory.js';
+import { expect } from 'chai';
+import { spec } from 'modules/orbidderBidAdapter.js';
+import { newBidder } from 'src/adapters/bidderFactory.js';
import * as _ from 'lodash';
import { BANNER, NATIVE } from '../../../src/mediaTypes.js';
@@ -59,7 +59,7 @@ describe('orbidderBidAdapter', () => {
}
};
- const deepClone = function (val) {
+ const deepClone = function(val) {
return JSON.parse(JSON.stringify(val));
};
@@ -91,15 +91,15 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(defaultBidRequestNative)).to.equal(true);
});
- it('banner: accepts optional profile object', () => {
+ it('banner: accepts optional keyValues object', () => {
const bidRequest = deepClone(defaultBidRequestBanner);
- bidRequest.params.profile = {'key': 'value'};
+ bidRequest.params.keyValues = { 'key': 'value' };
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
});
- it('native: accepts optional profile object', () => {
+ it('native: accepts optional keyValues object', () => {
const bidRequest = deepClone(defaultBidRequestNative);
- bidRequest.params.profile = {'key': 'value'};
+ bidRequest.params.keyValues = { 'key': 'value' };
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
});
@@ -115,15 +115,15 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
- it('banner: doesn\'t accept malformed profile', () => {
+ it('banner: doesn\'t accept malformed keyValues', () => {
const bidRequest = deepClone(defaultBidRequestBanner);
- bidRequest.params.profile = 'another not usable string';
+ bidRequest.params.keyValues = 'another not usable string';
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
- it('native: doesn\'t accept malformed profile', () => {
+ it('native: doesn\'t accept malformed keyValues', () => {
const bidRequest = deepClone(defaultBidRequestNative);
- bidRequest.params.profile = 'another not usable string';
+ bidRequest.params.keyValues = 'another not usable string';
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
@@ -347,7 +347,7 @@ describe('orbidderBidAdapter', () => {
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(expectedResponse.length);
expect(_.isEqual(expectedResponse, serverResponse)).to.be.true;
});
@@ -387,7 +387,7 @@ describe('orbidderBidAdapter', () => {
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(expectedResponse.length);
Object.keys(expectedResponse[0]).forEach((key) => {
@@ -454,7 +454,7 @@ describe('orbidderBidAdapter', () => {
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(expectedResponse.length);
expect(_.isEqual(expectedResponse, serverResponse)).to.be.true;
@@ -474,7 +474,7 @@ describe('orbidderBidAdapter', () => {
'netRevenue': true,
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(0);
});
@@ -492,7 +492,7 @@ describe('orbidderBidAdapter', () => {
'creativeId': '29681110',
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(0);
});
@@ -518,13 +518,13 @@ describe('orbidderBidAdapter', () => {
}
}
];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(0);
});
it('handles nobid responses', () => {
const serverResponse = [];
- const result = spec.interpretResponse({body: serverResponse});
+ const result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(0);
});
});
diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js
index e2b8ca38792..950e039491d 100644
--- a/test/spec/modules/priceFloors_spec.js
+++ b/test/spec/modules/priceFloors_spec.js
@@ -12,7 +12,7 @@ import {
isFloorsDataValid,
addBidResponseHook,
fieldMatchingFunctions,
- allowedFields
+ allowedFields, parseFloorData, normalizeDefault, getFloorDataFromAdUnits
} from 'modules/priceFloors.js';
import * as events from 'src/events.js';
import * as mockGpt from '../integration/faker/googletag.js';
@@ -123,7 +123,7 @@ describe('the price floors module', function () {
return {
code,
mediaTypes: {banner: { sizes: [[300, 200], [300, 600]] }, native: {}},
- bids: [{bidder: 'someBidder'}, {bidder: 'someOtherBidder'}]
+ bids: [{bidder: 'someBidder', adUnitCode: code}, {bidder: 'someOtherBidder', adUnitCode: code}]
};
}
beforeEach(function() {
@@ -143,6 +143,76 @@ describe('the price floors module', function () {
getGlobal().bidderSettings = {};
});
+ describe('parseFloorData', () => {
+ it('should accept just a default floor', () => {
+ const fd = parseFloorData({
+ default: 1.23
+ });
+ expect(getFirstMatchingFloor(fd, {}, {}).matchingFloor).to.eql(1.23);
+ });
+ });
+
+ describe('getFloorDataFromAdUnits', () => {
+ let adUnits;
+
+ function setFloorValues(rule) {
+ adUnits.forEach((au, i) => {
+ au.floors = {
+ values: {
+ [rule]: i + 1
+ }
+ }
+ })
+ }
+
+ beforeEach(() => {
+ adUnits = ['au1', 'au2', 'au3'].map(getAdUnitMock);
+ })
+
+ it('should use one schema for all adUnits', () => {
+ setFloorValues('*;*')
+ adUnits[1].floors.schema = {
+ fields: ['mediaType', 'gptSlot'],
+ delimiter: ';'
+ }
+ sinon.assert.match(getFloorDataFromAdUnits(adUnits), {
+ schema: {
+ fields: ['adUnitCode', 'mediaType', 'gptSlot'],
+ delimiter: ';'
+ },
+ values: {
+ 'au1;*;*': 1,
+ 'au2;*;*': 2,
+ 'au3;*;*': 3
+ }
+ })
+ });
+ it('should ignore adUnits that declare different schema', () => {
+ setFloorValues('*|*');
+ adUnits[0].floors.schema = {
+ fields: ['mediaType', 'gptSlot']
+ };
+ adUnits[2].floors.schema = {
+ fields: ['gptSlot', 'mediaType']
+ };
+ expect(getFloorDataFromAdUnits(adUnits).values).to.eql({
+ 'au1|*|*': 1,
+ 'au2|*|*': 2
+ })
+ });
+ it('should ignore adUnits that declare no values', () => {
+ setFloorValues('*');
+ adUnits[0].floors.schema = {
+ fields: ['mediaType']
+ };
+ delete adUnits[2].floors.values;
+ expect(getFloorDataFromAdUnits(adUnits).values).to.eql({
+ 'au1|*': 1,
+ 'au2|*': 2,
+ })
+ })
+ })
+
describe('getFloorsDataForAuction', function () {
it('converts basic input floor data into a floorData map for the auction correctly', function () {
// basic input where nothing needs to be updated
@@ -233,8 +303,8 @@ describe('the price floors module', function () {
});
describe('getFirstMatchingFloor', function () {
- it('uses a 0 floor as overrite', function () {
- let inputFloorData = {
+ it('uses a 0 floor as override', function () {
+ let inputFloorData = normalizeDefault({
currency: 'USD',
schema: {
delimiter: '|',
@@ -245,7 +315,7 @@ describe('the price floors module', function () {
'test_div_2': 2
},
default: 0.5
- };
+ });
expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({
floorMin: 0,
@@ -434,7 +504,7 @@ describe('the price floors module', function () {
});
});
it('selects the right floor for more complex rules', function () {
- let inputFloorData = {
+ let inputFloorData = normalizeDefault({
currency: 'USD',
schema: {
delimiter: '^',
@@ -448,7 +518,7 @@ describe('the price floors module', function () {
'weird_div^*^300x250': 5.5
},
default: 0.5
- };
+ });
// banner with 300x250 size
expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: [300, 250]})).to.deep.equal({
floorMin: 0,
@@ -490,10 +560,8 @@ describe('the price floors module', function () {
matchingFloor: undefined
});
// if default is there use it
- inputFloorData = { default: 5.0 };
- expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({
- matchingFloor: 5.0
- });
+ inputFloorData = normalizeDefault({ default: 5.0 });
+ expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'}).matchingFloor).to.equal(5.0);
});
describe('with gpt enabled', function () {
let gptFloorData;
@@ -693,6 +761,95 @@ describe('the price floors module', function () {
floorProvider: undefined
});
});
+ describe('default floor', () => {
+ let adUnits;
+ beforeEach(() => {
+ adUnits = ['au1', 'au2'].map(getAdUnitMock);
+ })
+ function expectFloors(floors) {
+ runStandardAuction(adUnits);
+ adUnits.forEach((au, i) => {
+ au.bids.forEach(bid => {
+ expect(bid.getFloor().floor).to.eql(floors[i]);
+ })
+ })
+ }
+ describe('should be sufficient by itself', () => {
+ it('globally', () => {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: {
+ default: 1.23
+ }
+ });
+ expectFloors([1.23, 1.23])
+ });
+ it('on adUnits', () => {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: undefined
+ });
+ adUnits[0].floors = {default: 1};
+ adUnits[1].floors = {default: 2};
+ expectFloors([1, 2])
+ });
+ it('on an adUnit with hidden schema', () => {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: undefined
+ });
+ adUnits[0].floors = {
+ schema: {
+ fields: ['mediaType', 'gptSlot'],
+ },
+ default: 1
+ }
+ adUnits[1].floors = {
+ default: 2
+ }
+ expectFloors([1, 2]);
+ })
+ });
+ describe('should NOT be used when a star rule exists', () => {
+ it('globally', () => {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: {
+ schema: {
+ fields: ['mediaType', 'gptSlot'],
+ },
+ values: {
+ '*|*': 2
+ },
+ default: 3,
+ }
+ });
+ expectFloors([2, 2]);
+ });
+ it('on adUnits', () => {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: undefined
+ });
+ adUnits[0].floors = {
+ schema: {
+ fields: ['mediaType', 'gptSlot'],
+ },
+ values: {
+ '*|*': 1
+ },
+ default: 3
+ };
+ adUnits[1].floors = {
+ values: {
+ '*|*': 2
+ },
+ default: 4
+ }
+ expectFloors([1, 2]);
+ })
+ });
+ })
it('bidRequests should have getFloor function and flooring meta data when setConfig occurs', function () {
handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider'});
runStandardAuction();
@@ -1382,7 +1539,7 @@ describe('the price floors module', function () {
it('picks the right rule with more complex rules', function () {
_floorDataForAuction[bidRequest.auctionId] = {
...basicFloorConfig,
- data: {
+ data: normalizeDefault({
currency: 'USD',
schema: { fields: ['mediaType', 'size'], delimiter: '|' },
values: {
@@ -1394,7 +1551,7 @@ describe('the price floors module', function () {
'video|*': 5.5
},
default: 10.0
- }
+ })
};
// assumes banner *
diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
index aba9750d6a6..ad471252f30 100755
--- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
@@ -388,7 +388,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[0].ps[0].en).to.equal(1.23);
expect(data.s[0].ps[0].di).to.equal('-1');
expect(data.s[0].ps[0].dc).to.equal('');
- expect(data.s[0].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[0].ps[0].l2).to.equal(0);
expect(data.s[0].ps[0].ss).to.equal(1);
expect(data.s[0].ps[0].t).to.equal(0);
@@ -417,7 +418,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -794,7 +796,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(0);
+ expect(data.s[0].ps[0].ol1).to.equal(0);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(1);
@@ -853,7 +856,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -901,7 +905,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -958,7 +963,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -1012,7 +1018,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -1067,7 +1074,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -1126,7 +1134,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -1198,7 +1207,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[0].ps[0].en).to.equal(1.23);
expect(data.s[0].ps[0].di).to.equal('-1');
expect(data.s[0].ps[0].dc).to.equal('');
- expect(data.s[0].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[0].ps[0].l2).to.equal(0);
expect(data.s[0].ps[0].ss).to.equal(0);
expect(data.s[0].ps[0].t).to.equal(0);
@@ -1228,7 +1238,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
@@ -1317,7 +1328,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[0].ps[0].en).to.equal(1.23);
expect(data.s[0].ps[0].di).to.equal('-1');
expect(data.s[0].ps[0].dc).to.equal('');
- expect(data.s[0].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[0].ps[0].l2).to.equal(0);
expect(data.s[0].ps[0].ss).to.equal(0);
expect(data.s[0].ps[0].t).to.equal(0);
@@ -1346,7 +1358,8 @@ describe('pubmatic analytics adapter', function () {
expect(data.s[1].ps[0].dc).to.equal('PMP');
expect(data.s[1].ps[0].mi).to.equal('matched-impression');
expect(data.s[1].ps[0].adv).to.equal('example.com');
- expect(data.s[1].ps[0].l1).to.equal(3214);
+ expect(data.s[0].ps[0].l1).to.equal(944);
+ expect(data.s[0].ps[0].ol1).to.equal(3214);
expect(data.s[1].ps[0].l2).to.equal(0);
expect(data.s[1].ps[0].ss).to.equal(1);
expect(data.s[1].ps[0].t).to.equal(0);
diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js
index 0ed764c8f7e..066004bd954 100644
--- a/test/spec/modules/pubmaticBidAdapter_spec.js
+++ b/test/spec/modules/pubmaticBidAdapter_spec.js
@@ -3601,6 +3601,89 @@ describe('PubMatic adapter', function () {
}
});
+ describe('Fledge Auction config Response', function () {
+ let response;
+ let bidRequestConfigs = [
+ {
+ bidder: 'pubmatic',
+ mediaTypes: {
+ banner: {
+ sizes: [[728, 90], [160, 600]]
+ }
+ },
+ params: {
+ publisherId: '5670',
+ adSlot: '/15671365/DMDemo@300x250:0',
+ kadfloor: '1.2',
+ pmzoneid: 'aabc, ddef',
+ kadpageurl: 'www.publisher.com',
+ yob: '1986',
+ gender: 'M',
+ lat: '12.3',
+ lon: '23.7',
+ wiid: '1234567890',
+ profId: '100',
+ verId: '200',
+ currency: 'AUD',
+ dctr: 'key1:val1,val2|key2:val1'
+ },
+ placementCode: '/19968336/header-bid-tag-1',
+ sizes: [[300, 250], [300, 600]],
+ bidId: 'test_bid_id',
+ requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
+ bidderRequestId: '1c56ad30b9b8ca8',
+ ortb2Imp: {
+ ext: {
+ tid: '92489f71-1bf2-49a0-adf9-000cea934729',
+ ae: 1
+ }
+ },
+ }
+ ];
+
+ let bidRequest = spec.buildRequests(bidRequestConfigs, {});
+ let bidResponse = {
+ seatbid: [{
+ bid: [{
+ impid: 'test_bid_id',
+ price: 2,
+ w: 728,
+ h: 250,
+ crid: 'test-creative-id',
+ dealid: 'test-deal-id',
+ adm: 'test-ad-markup'
+ }]
+ }],
+ cur: 'AUS',
+ ext: {
+ fledge_auction_configs: {
+ 'test_bid_id': {
+ seller: 'ads.pubmatic.com',
+ interestGroupBuyers: ['dsp1.com'],
+ sellerTimeout: 0,
+ perBuyerSignals: {
+ 'dsp1.com': {
+ bid_macros: 0.1,
+ disallowed_adv_ids: [
+ '5678',
+ '5890'
+ ],
+ }
+ }
+ }
+ }
+ }
+ };
+
+ response = spec.interpretResponse({ body: bidResponse }, bidRequest);
+ it('should return FLEDGE auction_configs alongside bids', function () {
+ expect(response).to.have.property('bids');
+ expect(response).to.have.property('fledgeAuctionConfigs');
+ expect(response.fledgeAuctionConfigs.length).to.equal(1);
+ expect(response.fledgeAuctionConfigs[0].bidId).to.equal('test_bid_id');
+ });
+ });
+
describe('Preapare metadata', function () {
it('Should copy all fields from ext to meta', function () {
const bid = {
diff --git a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
index 1dce87e4b8e..e0f4497a8c8 100644
--- a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
@@ -1,13 +1,9 @@
-import pubxaiAnalyticsAdapter from 'modules/pubxaiAnalyticsAdapter.js';
-import { getDeviceType, getBrowser, getOS } from 'modules/pubxaiAnalyticsAdapter.js';
-import {
- expect
-} from 'chai';
+import pubxaiAnalyticsAdapter, {getBrowser, getDeviceType, getOS} from 'modules/pubxaiAnalyticsAdapter.js';
+import {expect} from 'chai';
import adapterManager from 'src/adapterManager.js';
import * as utils from 'src/utils.js';
-import {
- server
-} from 'test/mocks/xhr.js';
+import {server} from 'test/mocks/xhr.js';
+import {getGptSlotInfoForAdUnitCode} from '../../../libraries/gptUtils/gptUtils.js';
let events = require('src/events');
let constants = require('src/constants.json');
@@ -527,7 +523,7 @@ describe('pubxai analytics adapter', function() {
'bidderCode': 'appnexus',
'bidId': '248f9a4489835e',
'adUnitCode': '/19968336/header-bid-tag-1',
- 'gptSlotCode': utils.getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null,
+ 'gptSlotCode': getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null,
'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4',
'sizes': '300x250',
'renderStatus': 2,
@@ -596,7 +592,7 @@ describe('pubxai analytics adapter', function() {
let expectedAfterBidWon = {
'winningBid': {
'adUnitCode': '/19968336/header-bid-tag-1',
- 'gptSlotCode': utils.getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null,
+ 'gptSlotCode': getGptSlotInfoForAdUnitCode('/19968336/header-bid-tag-1').gptSlot || null,
'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4',
'bidderCode': 'appnexus',
'bidId': '248f9a4489835e',
diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js
index b179f870e0d..164aa06d9b7 100644
--- a/test/spec/modules/sonobiBidAdapter_spec.js
+++ b/test/spec/modules/sonobiBidAdapter_spec.js
@@ -1,9 +1,9 @@
-import { expect } from 'chai'
-import { spec, _getPlatform } from 'modules/sonobiBidAdapter.js'
-import { newBidder } from 'src/adapters/bidderFactory.js'
-import { userSync } from '../../../src/userSync.js';
-import { config } from 'src/config.js';
-import * as utils from '../../../src/utils.js';
+import {expect} from 'chai';
+import {_getPlatform, spec} from 'modules/sonobiBidAdapter.js';
+import {newBidder} from 'src/adapters/bidderFactory.js';
+import {userSync} from '../../../src/userSync.js';
+import {config} from 'src/config.js';
+import * as gptUtils from '../../../libraries/gptUtils/gptUtils.js';
describe('SonobiBidAdapter', function () {
const adapter = newBidder(spec)
@@ -248,13 +248,13 @@ describe('SonobiBidAdapter', function () {
let sandbox;
beforeEach(function () {
sinon.stub(userSync, 'canBidderRegisterSync');
- sinon.stub(utils, 'getGptSlotInfoForAdUnitCode')
+ sinon.stub(gptUtils, 'getGptSlotInfoForAdUnitCode')
.onFirstCall().returns({ gptSlot: '/123123/gpt_publisher/adunit-code-3', divId: 'adunit-code-3-div-id' });
sandbox = sinon.createSandbox();
});
afterEach(function () {
userSync.canBidderRegisterSync.restore();
- utils.getGptSlotInfoForAdUnitCode.restore();
+ gptUtils.getGptSlotInfoForAdUnitCode.restore();
sandbox.restore();
});
let bidRequest = [{
diff --git a/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js b/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js
index 962d135cd6d..0796736a162 100644
--- a/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js
+++ b/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js
@@ -395,11 +395,6 @@ describe('Zeta Global SSP Analytics Adapter', function() {
const auctionEnd = JSON.parse(requests[0].requestBody);
const auctionSucceeded = JSON.parse(requests[1].requestBody);
- expect(auctionEnd.metrics).to.be.undefined;
-
- expect(auctionSucceeded.bid.ad).to.be.undefined;
- expect(auctionSucceeded.bid.metrics).to.be.undefined;
-
expect(auctionSucceeded.bid.params[0]).to.be.deep.equal(EVENTS.AUCTION_END.adUnits[0].bids[0].params);
expect(EVENTS.AUCTION_END.adUnits[0].bids[0].bidder).to.be.equal('zeta_global_ssp');
});
diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js
index cff26df2e4d..98d841d9c7c 100644
--- a/test/spec/unit/core/adapterManager_spec.js
+++ b/test/spec/unit/core/adapterManager_spec.js
@@ -965,13 +965,23 @@ describe('adapterManager tests', function () {
}];
it('invokes callBids on the S2S adapter', function () {
+ const done = sinon.stub();
+ const onTimelyResponse = sinon.stub();
+ prebidServerAdapterMock.callBids.callsFake((_1, _2, _3, done) => {
+ done();
+ });
adapterManager.callBids(
getAdUnits(),
bidRequests,
() => {},
- () => () => {}
+ done,
+ undefined,
+ undefined,
+ onTimelyResponse
);
sinon.assert.calledTwice(prebidServerAdapterMock.callBids);
+ sinon.assert.calledTwice(done);
+ bidRequests.forEach(br => sinon.assert.calledWith(onTimelyResponse, br.bidderRequestId));
});
// Enable this test when prebidServer adapter is made 1.0 compliant
diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js
index 40126f7f20c..098582c0af6 100644
--- a/test/spec/utils_spec.js
+++ b/test/spec/utils_spec.js
@@ -4,6 +4,7 @@ import CONSTANTS from 'src/constants.json';
import * as utils from 'src/utils.js';
import {getHighestCpm, getLatestHighestCpmBid, getOldestHighestCpmBid} from '../../src/utils/reducers.js';
import {binarySearch, deepEqual, memoize, waitForElementToLoad} from 'src/utils.js';
+import {convertCamelToUnderscore} from '../../libraries/appnexusUtils/anUtils.js';
var assert = require('assert');
@@ -40,28 +41,6 @@ describe('Utils', function () {
});
});
- describe('tryAppendQueryString', function () {
- it('should append query string to existing url', function () {
- var url = 'www.a.com?';
- var key = 'b';
- var value = 'c';
-
- var output = utils.tryAppendQueryString(url, key, value);
-
- var expectedResult = url + key + '=' + encodeURIComponent(value) + '&';
- assert.equal(output, expectedResult);
- });
-
- it('should return existing url, if the value is empty', function () {
- var url = 'www.a.com?';
- var key = 'b';
- var value = '';
-
- var output = utils.tryAppendQueryString(url, key, value);
- assert.equal(output, url);
- });
- });
-
describe('parseQueryStringParameters', function () {
it('should append query string to existing using the input obj', function () {
var obj = {
@@ -700,43 +679,15 @@ describe('Utils', function () {
describe('convertCamelToUnderscore', function () {
it('returns converted string value using underscore syntax instead of camelCase', function () {
let var1 = 'placementIdTest';
- let test1 = utils.convertCamelToUnderscore(var1);
+ let test1 = convertCamelToUnderscore(var1);
expect(test1).to.equal('placement_id_test');
let var2 = 'my_test_value';
- let test2 = utils.convertCamelToUnderscore(var2);
+ let test2 = convertCamelToUnderscore(var2);
expect(test2).to.equal(var2);
});
});
- describe('getAdUnitSizes', function () {
- it('returns an empty response when adUnits is undefined', function () {
- let sizes = utils.getAdUnitSizes();
- expect(sizes).to.be.undefined;
- });
-
- it('returns an empty array when invalid data is present in adUnit object', function () {
- let sizes = utils.getAdUnitSizes({ sizes: 300 });
- expect(sizes).to.deep.equal([]);
- });
-
- it('retuns an array of arrays when reading from adUnit.sizes', function () {
- let sizes = utils.getAdUnitSizes({ sizes: [300, 250] });
- expect(sizes).to.deep.equal([[300, 250]]);
-
- sizes = utils.getAdUnitSizes({ sizes: [[300, 250], [300, 600]] });
- expect(sizes).to.deep.equal([[300, 250], [300, 600]]);
- });
-
- it('returns an array of arrays when reading from adUnit.mediaTypes.banner.sizes', function () {
- let sizes = utils.getAdUnitSizes({ mediaTypes: { banner: { sizes: [300, 250] } } });
- expect(sizes).to.deep.equal([[300, 250]]);
-
- sizes = utils.getAdUnitSizes({ mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } } });
- expect(sizes).to.deep.equal([[300, 250], [300, 600]]);
- });
- });
-
describe('URL helpers', function () {
describe('parseUrl()', function () {
let parsed;