forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsizeMappingV2.js
522 lines (491 loc) · 23.9 KB
/
sizeMappingV2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
/**
* This module adds support for the new size mapping spec, Advanced Size Mapping. It's documented here. https://github.com/prebid/Prebid.js/issues/4129
* The implementation is an alternative to global sizeConfig. It introduces 'Ad Unit' & 'Bidder' level sizeConfigs and also supports 'labels' for conditional
* rendering. Read full API documentation on Prebid.org, http://prebid.org/dev-docs/modules/sizeMappingV2.html
*/
import {
deepClone,
getWindowTop,
isArray,
isArrayOfNums,
isValidMediaTypes,
logError,
logInfo,
logWarn
} from '../src/utils.js';
import {includes} from '../src/polyfill.js';
import {getHook} from '../src/hook.js';
import {adUnitSetupChecks} from '../src/prebid.js';
// Allows for stubbing of these functions while writing unit tests.
export const internal = {
checkBidderSizeConfigFormat,
getActiveSizeBucket,
getFilteredMediaTypes,
getAdUnitDetail,
getRelevantMediaTypesForBidder,
isLabelActivated
};
const V2_ADUNITS = new WeakMap();
/*
Returns "true" if at least one of the adUnits in the adUnits array is using an Ad Unit and/or Bidder level sizeConfig,
otherwise, returns "false."
*/
export function isUsingNewSizeMapping(adUnits) {
return !!adUnits.find(adUnit => {
if (V2_ADUNITS.has(adUnit)) return V2_ADUNITS.get(adUnit);
if (adUnit.mediaTypes) {
// checks for the presence of sizeConfig property at the adUnit.mediaTypes object
for (let mediaType of Object.keys(adUnit.mediaTypes)) {
if (adUnit.mediaTypes[mediaType].sizeConfig) {
V2_ADUNITS.set(adUnit, true);
return true;
}
}
for (let bid of adUnit.bids && isArray(adUnit.bids) ? adUnit.bids : []) {
if (bid.sizeConfig) {
V2_ADUNITS.set(adUnit, true);
return true;
}
}
V2_ADUNITS.set(adUnit, false);
return false;
}
});
}
/**
This hooked function executes before the function 'checkAdUnitSetup', that is defined in /src/prebid.js. It's necessary to run this funtion before
because it applies a series of checks in order to determine the correctness of the 'sizeConfig' array, which, the original 'checkAdUnitSetup' function
does not recognize.
@params {Array<AdUnits>} adUnits
@returns {Array<AdUnits>} validateAdUnits - Unrecognized properties are deleted.
*/
export function checkAdUnitSetupHook(adUnits) {
const validateSizeConfig = function (mediaType, sizeConfig, adUnitCode) {
let isValid = true;
const associatedProperty = {
banner: 'sizes',
video: 'playerSize',
native: 'active'
}
const propertyName = associatedProperty[mediaType];
const conditionalLogMessages = {
banner: 'Removing mediaTypes.banner from ad unit.',
video: 'Removing mediaTypes.video.sizeConfig from ad unit.',
native: 'Removing mediaTypes.native.sizeConfig from ad unit.'
}
if (Array.isArray(sizeConfig)) {
sizeConfig.forEach((config, index) => {
const keys = Object.keys(config);
/*
Check #1 (Applies to 'banner', 'video' and 'native' media types.)
Verify that all config objects include 'minViewPort' and 'sizes' property.
If they do not, return 'false'.
*/
if (!(includes(keys, 'minViewPort') && includes(keys, propertyName))) {
logError(`Ad unit ${adUnitCode}: Missing required property 'minViewPort' or 'sizes' from 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`);
isValid = false;
return;
}
/*
Check #2 (Applies to 'banner', 'video' and 'native' media types.)
Verify that 'config.minViewPort' property is in [width, height] format.
If not, return false.
*/
if (!isArrayOfNums(config.minViewPort, 2)) {
logError(`Ad unit ${adUnitCode}: Invalid declaration of 'minViewPort' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`);
isValid = false;
return;
}
/*
Check #3 (Applies only to 'banner' and 'video' media types.)
Verify that 'config.sizes' (in case of banner) or 'config.playerSize' (in case of video)
property is in [width, height] format. If not, return 'false'.
*/
if (mediaType === 'banner' || mediaType === 'video') {
let showError = false;
if (Array.isArray(config[propertyName])) {
const validatedSizes = adUnitSetupChecks.validateSizes(config[propertyName]);
if (config[propertyName].length > 0 && validatedSizes.length === 0) {
isValid = false;
showError = true;
}
} else {
// Either 'sizes' or 'playerSize' is not declared as an array, which makes it invalid by default.
isValid = false;
showError = true;
}
if (showError) {
logError(`Ad unit ${adUnitCode}: Invalid declaration of '${propertyName}' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`);
return;
}
}
/*
Check #4 (Applies only to 'native' media type)
Verify that 'config.active' is a 'boolean'.
If not, return 'false'.
*/
if (FEATURES.NATIVE && mediaType === 'native') {
if (typeof config[propertyName] !== 'boolean') {
logError(`Ad unit ${adUnitCode}: Invalid declaration of 'active' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`);
isValid = false;
}
}
});
} else {
logError(`Ad unit ${adUnitCode}: Invalid declaration of 'sizeConfig' in 'mediaTypes.${mediaType}.sizeConfig'. ${conditionalLogMessages[mediaType]}`);
isValid = false;
return isValid;
}
// If all checks have passed, isValid should equal 'true'
return isValid;
}
const validatedAdUnits = [];
adUnits.forEach(adUnit => {
adUnit = adUnitSetupChecks.validateAdUnit(adUnit);
if (adUnit == null) return;
const mediaTypes = adUnit.mediaTypes;
let validatedBanner, validatedVideo, validatedNative;
if (mediaTypes.banner) {
if (mediaTypes.banner.sizes) {
// Ad unit is using 'mediaTypes.banner.sizes' instead of the new property 'sizeConfig'. Apply the old checks!
validatedBanner = adUnitSetupChecks.validateBannerMediaType(adUnit);
} else if (mediaTypes.banner.sizeConfig) {
// Ad unit is using the 'sizeConfig' property, 'mediaTypes.banner.sizeConfig'. Apply the new checks!
validatedBanner = deepClone(adUnit);
const isBannerValid = validateSizeConfig('banner', mediaTypes.banner.sizeConfig, adUnit.code);
if (!isBannerValid) {
delete validatedBanner.mediaTypes.banner;
} else {
/*
Make sure 'sizes' field is always an array of arrays. If not, make it so.
For example, [] becomes [[]], and [360, 400] becomes [[360, 400]]
*/
validatedBanner.mediaTypes.banner.sizeConfig.forEach(config => {
if (!Array.isArray(config.sizes[0])) {
config.sizes = [config.sizes];
}
});
}
} else {
// Ad unit is invalid since it's mediaType property does not have either 'sizes' or 'sizeConfig' declared.
logError(`Ad unit ${adUnit.code}: 'mediaTypes.banner' does not contain either 'sizes' or 'sizeConfig' property. Removing 'mediaTypes.banner' from ad unit.`);
validatedBanner = deepClone(adUnit);
delete validatedBanner.mediaTypes.banner;
}
}
if (FEATURES.VIDEO && mediaTypes.video) {
if (mediaTypes.video.playerSize) {
// Ad unit is using 'mediaTypes.video.playerSize' instead of the new property 'sizeConfig'. Apply the old checks!
validatedVideo = validatedBanner ? adUnitSetupChecks.validateVideoMediaType(validatedBanner) : adUnitSetupChecks.validateVideoMediaType(adUnit);
} else if (mediaTypes.video.sizeConfig) {
// Ad unit is using the 'sizeConfig' property, 'mediaTypes.video.sizeConfig'. Apply the new checks!
validatedVideo = validatedBanner || deepClone(adUnit);
const isVideoValid = validateSizeConfig('video', mediaTypes.video.sizeConfig, adUnit.code);
if (!isVideoValid) {
delete validatedVideo.mediaTypes.video.sizeConfig;
} else {
/*
Make sure 'playerSize' field is always an array of arrays. If not, make it so.
For example, [] becomes [[]], and [640, 400] becomes [[640, 400]]
*/
validatedVideo.mediaTypes.video.sizeConfig.forEach(config => {
if (!Array.isArray(config.playerSize[0])) {
config.playerSize = [config.playerSize];
}
});
}
}
}
if (FEATURES.NATIVE && mediaTypes.native) {
// Apply the old native checks
validatedNative = validatedVideo ? adUnitSetupChecks.validateNativeMediaType(validatedVideo) : validatedBanner ? adUnitSetupChecks.validateNativeMediaType(validatedBanner) : adUnitSetupChecks.validateNativeMediaType(adUnit);
// Apply the new checks if 'mediaTypes.native.sizeConfig' detected
if (mediaTypes.native.sizeConfig) {
const isNativeValid = validateSizeConfig('native', mediaTypes.native.sizeConfig, adUnit.code);
if (!isNativeValid) {
delete validatedNative.mediaTypes.native.sizeConfig;
}
}
}
const validatedAdUnit = Object.assign({}, validatedBanner, validatedVideo, validatedNative);
validatedAdUnits.push(validatedAdUnit);
});
return validatedAdUnits;
}
getHook('checkAdUnitSetup').before(function (fn, adUnits) {
const usingNewSizeMapping = isUsingNewSizeMapping(adUnits);
if (usingNewSizeMapping) {
// if adUnits are found using the sizeMappingV2 spec, we run additional checks on them for checking the validity of sizeConfig object
// in addition to running the base checks on the mediaType object and return the adUnit without calling the base function.
adUnits = checkAdUnitSetupHook(adUnits);
return fn.bail(adUnits);
} else {
// if presence of sizeMappingV2 spec is not detected on adUnits, we default back to the original checks defined in the base function.
return fn.call(this, adUnits);
}
});
// checks if the sizeConfig object declared at the Bidder level is in the right format or not.
export function checkBidderSizeConfigFormat(sizeConfig) {
let didCheckPass = true;
if (Array.isArray(sizeConfig) && sizeConfig.length > 0) {
sizeConfig.forEach(config => {
const keys = Object.keys(config);
if ((includes(keys, 'minViewPort') &&
includes(keys, 'relevantMediaTypes')) &&
isArrayOfNums(config.minViewPort, 2) &&
Array.isArray(config.relevantMediaTypes) &&
config.relevantMediaTypes.length > 0 &&
(config.relevantMediaTypes.length > 1 ? (config.relevantMediaTypes.every(mt => (includes(['banner', 'video', 'native'], mt))))
: (['none', 'banner', 'video', 'native'].indexOf(config.relevantMediaTypes[0]) > -1))) {
didCheckPass = didCheckPass && true;
} else {
didCheckPass = false;
}
});
} else {
didCheckPass = false;
}
return didCheckPass;
}
getHook('setupAdUnitMediaTypes').before(function (fn, adUnits, labels) {
if (isUsingNewSizeMapping(adUnits)) {
return fn.bail(setupAdUnitMediaTypes(adUnits, labels));
} else {
return fn.call(this, adUnits, labels);
}
});
/**
* Given an Ad Unit or a Bid as an input, returns a boolean telling if the Ad Unit/ Bid is active based on label checks
* @param {Object<BidOrAdUnit>} bidOrAdUnit - Either the Ad Unit object or the Bid object
* @param {Array<string>} activeLabels - List of active labels passed as an argument to pbjs.requestBids function
* @param {string} adUnitCode - Unique string identifier for an Ad Unit.
* @param {number} adUnitInstance - Instance count of an 'Identical' ad unit.
* @returns {boolean} Represents if the Ad Unit or the Bid is active or not
*/
export function isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode, adUnitInstance) {
let labelOperator;
const labelsFound = Object.keys(bidOrAdUnit).filter(prop => prop === 'labelAny' || prop === 'labelAll');
if (labelsFound && labelsFound.length > 1) {
logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code)
? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)
: (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Bidder has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`);
}
labelOperator = labelsFound[0];
if (labelOperator && !activeLabels) {
logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code)
? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Found '${labelOperator}' on ad unit, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`)
: (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Found '${labelOperator}' on bidder, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`)}`);
return true;
}
if (labelOperator === 'labelAll' && Array.isArray(bidOrAdUnit[labelOperator])) {
if (bidOrAdUnit.labelAll.length === 0) {
logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAll' with an empty array.`);
return true;
}
return bidOrAdUnit.labelAll.every(label => includes(activeLabels, label));
} else if (labelOperator === 'labelAny' && Array.isArray(bidOrAdUnit[labelOperator])) {
if (bidOrAdUnit.labelAny.length === 0) {
logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAny' with an empty array.`);
return true;
}
return bidOrAdUnit.labelAny.some(label => includes(activeLabels, label));
}
return true;
}
/**
* Processes the MediaTypes object and calculates the active size buckets for each Media Type. Uses `window.innerWidth` and `window.innerHeight`
* to calculate the width and height of the active Viewport.
* @param {MediaTypes} mediaTypes Contains information about supported media types for an Ad Unit and size information for each of those types
* @returns {FilteredMediaTypes} Filtered mediaTypes object with relevant media types filtered by size buckets based on activeViewPort size
*/
export function getFilteredMediaTypes(mediaTypes) {
let
activeViewportWidth,
activeViewportHeight,
transformedMediaTypes;
transformedMediaTypes = deepClone(mediaTypes);
let activeSizeBucket = {
banner: undefined,
video: undefined,
native: undefined
}
try {
activeViewportWidth = getWindowTop().innerWidth;
activeViewportHeight = getWindowTop().innerHeight;
} catch (e) {
logWarn(`SizeMappingv2:: Unfriendly iframe blocks viewport size to be evaluated correctly`);
activeViewportWidth = window.innerWidth;
activeViewportHeight = window.innerHeight;
}
const activeViewport = [activeViewportWidth, activeViewportHeight];
Object.keys(mediaTypes).map(mediaType => {
const sizeConfig = mediaTypes[mediaType].sizeConfig;
if (sizeConfig) {
activeSizeBucket[mediaType] = getActiveSizeBucket(sizeConfig, activeViewport);
const filteredSizeConfig = sizeConfig.filter(config => config.minViewPort === activeSizeBucket[mediaType] && isSizeConfigActivated(mediaType, config));
transformedMediaTypes[mediaType] = Object.assign({ filteredSizeConfig }, mediaTypes[mediaType]);
// transform mediaTypes object
const config = {
banner: 'sizes',
video: 'playerSize'
};
if (transformedMediaTypes[mediaType].filteredSizeConfig.length > 0) {
// map sizes or playerSize property in filteredSizeConfig object to transformedMediaTypes.banner.sizes if mediaType is banner
// or transformedMediaTypes.video.playerSize if the mediaType in video.
// doesn't apply to native mediaType since native doesn't have any property defining 'sizes' or 'playerSize'.
if (mediaType !== 'native') {
transformedMediaTypes[mediaType][config[mediaType]] = transformedMediaTypes[mediaType].filteredSizeConfig[0][config[mediaType]];
}
} else {
delete transformedMediaTypes[mediaType];
}
}
})
// filter out 'undefined' values from activeSizeBucket object and attach sizes/playerSize information against the active size bucket.
const sizeBucketToSizeMap = Object
.keys(activeSizeBucket)
.filter(mediaType => activeSizeBucket[mediaType] !== undefined)
.reduce((sizeBucketToSizeMap, mediaType) => {
sizeBucketToSizeMap[mediaType] = {
activeSizeBucket: activeSizeBucket[mediaType],
activeSizeDimensions: (mediaType === 'banner') ? (
// banner mediaType gets deleted incase no sizes are specified for a given size bucket, that's why this check is necessary
(transformedMediaTypes.banner) ? (transformedMediaTypes.banner.sizes) : ([])
) : ((mediaType === 'video') ? (
// video mediaType gets deleted incase no playerSize is specified for a given size bucket, that's why this check is necessary
(transformedMediaTypes.video) ? (transformedMediaTypes.video.playerSize) : ([])
) : ('NA'))
};
return sizeBucketToSizeMap;
}, {});
return { sizeBucketToSizeMap, activeViewport, transformedMediaTypes };
}
/**
* Evaluates the given sizeConfig object and checks for various properties to determine if the sizeConfig is active or not. For example,
* let's suppose the sizeConfig is for a Banner media type. Then, if the sizes property is found empty, it returns false, else returns true.
* In case of a Video media type, it checks the playerSize property. If found empty, returns false, else returns true.
* In case of a Native media type, it checks the active property. If found false, returns false, if found true, returns true.
* @param {string} mediaType It can be 'banner', 'native' or 'video'
* @param {Object<SizeConfig>} sizeConfig Represents the sizeConfig object which is active based on the current viewport size
* @returns {boolean} Represents if the size config is active or not
*/
export function isSizeConfigActivated(mediaType, sizeConfig) {
switch (mediaType) {
case 'banner':
// we need this check, sizeConfig.sizes[0].length > 0, in place because a sizeBucket can have sizes: [],
// gets converted to sizes: [[]] in the checkAdUnitSetupHook function
return sizeConfig.sizes && sizeConfig.sizes.length > 0 && sizeConfig.sizes[0].length > 0;
case 'video':
// for why we need the last check, read the above comment
return sizeConfig.playerSize && sizeConfig.playerSize.length > 0 && sizeConfig.playerSize[0].length > 0;
case 'native':
return sizeConfig.active;
default:
return false;
}
}
/**
* Returns the active size bucket for a given media type
* @param {Array<SizeConfig>} sizeConfig SizeConfig defines the characteristics of an Ad Unit categorised into multiple size buckets per media type
* @param {Array} activeViewport Viewport size of the browser in the form [w, h] (w -> width, h -> height)
* Calculated at the time of making call to pbjs.requestBids function
* @returns {Array} The active size bucket matching the activeViewPort, for example: [750, 0]
*/
export function getActiveSizeBucket(sizeConfig, activeViewport) {
let activeSizeBucket = [];
sizeConfig
.sort((a, b) => a.minViewPort[0] - b.minViewPort[0])
.forEach(config => {
if (activeViewport[0] >= config.minViewPort[0]) {
if (activeViewport[1] >= config.minViewPort[1]) {
activeSizeBucket = config.minViewPort;
} else {
activeSizeBucket = [];
}
}
})
return activeSizeBucket;
}
export function getRelevantMediaTypesForBidder(sizeConfig, activeViewport) {
const mediaTypes = new Set();
if (internal.checkBidderSizeConfigFormat(sizeConfig)) {
const activeSizeBucket = internal.getActiveSizeBucket(sizeConfig, activeViewport);
sizeConfig.filter(config => config.minViewPort === activeSizeBucket)[0]['relevantMediaTypes'].forEach((mt) => mediaTypes.add(mt));
}
return mediaTypes;
}
export function getAdUnitDetail(adUnit, labels, adUnitInstance) {
const isLabelActivated = internal.isLabelActivated(adUnit, labels, adUnit.code, adUnitInstance);
const { sizeBucketToSizeMap, activeViewport, transformedMediaTypes } = isLabelActivated && internal.getFilteredMediaTypes(adUnit.mediaTypes);
isLabelActivated && logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Active size buckets after filtration: `, sizeBucketToSizeMap);
return {
activeViewport,
transformedMediaTypes,
isLabelActivated,
};
}
export function setupAdUnitMediaTypes(adUnits, labels) {
const duplCounter = {};
return adUnits.reduce((result, adUnit) => {
const instance = (() => {
if (!duplCounter.hasOwnProperty(adUnit.code)) {
duplCounter[adUnit.code] = 1;
}
return duplCounter[adUnit.code]++;
})();
if (adUnit.mediaTypes && isValidMediaTypes(adUnit.mediaTypes)) {
const { activeViewport, transformedMediaTypes, isLabelActivated } = internal.getAdUnitDetail(adUnit, labels, instance);
if (isLabelActivated) {
if (Object.keys(transformedMediaTypes).length === 0) {
logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}) => Ad unit disabled since there are no active media types after sizeConfig filtration.`);
} else {
adUnit.mediaTypes = transformedMediaTypes;
adUnit.bids = adUnit.bids.reduce((bids, bid) => {
if (internal.isLabelActivated(bid, labels, adUnit.code, instance)) {
if (bid.sizeConfig) {
const relevantMediaTypes = internal.getRelevantMediaTypesForBidder(bid.sizeConfig, activeViewport);
if (relevantMediaTypes.size === 0) {
logError(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}), Bidder: ${bid.bidder} => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remain active.`);
bids.push(bid);
} else if (!relevantMediaTypes.has('none')) {
let modified = false;
const bidderMediaTypes = Object.fromEntries(
Object.entries(transformedMediaTypes)
.filter(([key, val]) => {
if (!relevantMediaTypes.has(key)) {
modified = true;
return false;
}
return true;
})
);
if (Object.keys(bidderMediaTypes).length > 0) {
if (modified) {
bid.mediaTypes = bidderMediaTypes;
}
bids.push(bid);
} else {
logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`);
}
} else {
logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`);
}
} else {
bids.push(bid);
}
} else {
logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}), Bidder: ${bid.bidder} => Label check for this bidder has failed. This bidder is disabled.`);
}
return bids;
}, []);
result.push(adUnit);
}
} else {
logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${instance}) => Ad unit is disabled due to failing label check.`);
}
} else {
logWarn(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`);
}
return result;
}, [])
}