prebid.js 5.19.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/.babelrc.js +1 -10
  2. package/README.md +4 -2
  3. package/browsers.json +13 -37
  4. package/gulpfile.js +1 -0
  5. package/karma.conf.maker.js +1 -1
  6. package/modules/adheseBidAdapter.js +7 -2
  7. package/modules/adkernelBidAdapter.js +1 -0
  8. package/modules/adlivetechBidAdapter.md +61 -0
  9. package/modules/admixerBidAdapter.js +2 -1
  10. package/modules/adnuntiusBidAdapter.js +2 -1
  11. package/modules/adomikAnalyticsAdapter.js +10 -4
  12. package/modules/adplusBidAdapter.js +203 -0
  13. package/modules/adplusBidAdapter.md +39 -0
  14. package/modules/adyoulikeBidAdapter.js +7 -2
  15. package/modules/airgridRtdProvider.js +1 -1
  16. package/modules/appnexusBidAdapter.js +28 -5
  17. package/modules/atsAnalyticsAdapter.js +67 -46
  18. package/modules/atsAnalyticsAdapter.md +1 -0
  19. package/modules/beachfrontBidAdapter.js +14 -17
  20. package/modules/betweenBidAdapter.js +2 -1
  21. package/modules/browsiRtdProvider.js +106 -18
  22. package/modules/cleanioRtdProvider.js +192 -0
  23. package/modules/cleanioRtdProvider.md +59 -0
  24. package/modules/codefuelBidAdapter.js +1 -3
  25. package/modules/codefuelBidAdapter.md +3 -3
  26. package/modules/craftBidAdapter.js +5 -3
  27. package/modules/datablocksBidAdapter.js +3 -3
  28. package/modules/dchain.js +149 -0
  29. package/modules/dchain.md +45 -0
  30. package/modules/deepintentBidAdapter.js +1 -1
  31. package/modules/deltaprojectsBidAdapter.js +252 -0
  32. package/modules/deltaprojectsBidAdapter.md +32 -0
  33. package/modules/emx_digitalBidAdapter.js +9 -1
  34. package/modules/engageyaBidAdapter.js +68 -54
  35. package/modules/freewheel-sspBidAdapter.js +6 -0
  36. package/modules/glimpseBidAdapter.js +31 -16
  37. package/modules/goldbachBidAdapter.js +1176 -0
  38. package/modules/goldbachBidAdapter.md +151 -0
  39. package/modules/gptPreAuction.js +11 -5
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gumgumBidAdapter.js +5 -1
  42. package/modules/id5IdSystem.md +6 -6
  43. package/modules/imRtdProvider.js +31 -0
  44. package/modules/intersectionRtdProvider.js +114 -0
  45. package/modules/invibesBidAdapter.js +15 -9
  46. package/modules/ipromBidAdapter.js +79 -0
  47. package/modules/ixBidAdapter.js +173 -22
  48. package/modules/jixieBidAdapter.js +8 -2
  49. package/modules/justpremiumBidAdapter.js +6 -1
  50. package/modules/limelightDigitalBidAdapter.js +2 -1
  51. package/modules/livewrappedAnalyticsAdapter.js +5 -0
  52. package/modules/luponmediaBidAdapter.js +570 -0
  53. package/modules/merkleIdSystem.js +5 -0
  54. package/modules/missenaBidAdapter.js +89 -0
  55. package/modules/multibid/index.js +3 -3
  56. package/modules/nativoBidAdapter.js +32 -2
  57. package/modules/oguryBidAdapter.js +2 -1
  58. package/modules/openxBidAdapter.js +7 -2
  59. package/modules/operaadsBidAdapter.js +21 -1
  60. package/modules/otmBidAdapter.js +146 -0
  61. package/modules/otmBidAdapter.md +27 -26
  62. package/modules/outbrainBidAdapter.js +5 -0
  63. package/modules/playwireBidAdapter.md +61 -0
  64. package/modules/prebidServerBidAdapter/index.js +3 -3
  65. package/modules/pubmaticBidAdapter.js +5 -3
  66. package/modules/relaidoBidAdapter.js +86 -65
  67. package/modules/richaudienceBidAdapter.js +1 -1
  68. package/modules/rtdModule/index.js +2 -2
  69. package/modules/saambaaBidAdapter.js +420 -0
  70. package/modules/saambaaBidAdapter.md +65 -68
  71. package/modules/seedtagBidAdapter.js +6 -0
  72. package/modules/smaatoBidAdapter.js +9 -1
  73. package/modules/smartxBidAdapter.js +17 -1
  74. package/modules/sonobiBidAdapter.js +7 -0
  75. package/modules/sortableBidAdapter.js +1 -0
  76. package/modules/sspBCBidAdapter.js +34 -3
  77. package/modules/tappxBidAdapter.js +3 -1
  78. package/modules/teadsBidAdapter.js +3 -0
  79. package/modules/trustxBidAdapter.js +18 -7
  80. package/modules/undertoneBidAdapter.js +8 -1
  81. package/modules/userId/index.js +27 -2
  82. package/modules/ventes.md +71 -0
  83. package/modules/ventesBidAdapter.js +410 -0
  84. package/modules/ventesBidAdapter.md +93 -0
  85. package/modules/vidoomyBidAdapter.js +51 -100
  86. package/modules/visxBidAdapter.js +20 -3
  87. package/modules/visxBidAdapter.md +4 -6
  88. package/modules/yahoosspBidAdapter.js +6 -6
  89. package/modules/yahoosspBidAdapter.md +1 -1
  90. package/modules/yieldlabBidAdapter.js +41 -10
  91. package/modules/yieldlabBidAdapter.md +91 -48
  92. package/modules/yieldoneBidAdapter.js +115 -11
  93. package/package.json +6 -1
  94. package/src/adapterManager.js +14 -8
  95. package/src/auction.js +14 -13
  96. package/src/targeting.js +2 -2
  97. package/src/utils.js +7 -0
  98. package/test/spec/integration/faker/googletag.js +6 -0
  99. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  100. package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
  101. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  102. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  103. package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
  104. package/test/spec/modules/appnexusBidAdapter_spec.js +65 -2
  105. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  106. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  107. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  108. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  109. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  110. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  111. package/test/spec/modules/dchain_spec.js +329 -0
  112. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  113. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  114. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  115. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  116. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  117. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  118. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  119. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  120. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  121. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  122. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  123. package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
  124. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  125. package/test/spec/modules/ixBidAdapter_spec.js +288 -5
  126. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  127. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  128. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  129. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
  130. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +23 -4
  131. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  132. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  133. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  134. package/test/spec/modules/multibid_spec.js +31 -31
  135. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  136. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  137. package/test/spec/modules/openxBidAdapter_spec.js +5 -26
  138. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  139. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  140. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  141. package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
  142. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  143. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  144. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  145. package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
  146. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  147. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  148. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  149. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  150. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  151. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  152. package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
  153. package/test/spec/modules/userId_spec.js +51 -0
  154. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  155. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  156. package/test/spec/modules/visxBidAdapter_spec.js +121 -5
  157. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  158. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  159. package/test/spec/unit/core/adapterManager_spec.js +26 -7
  160. package/test/spec/unit/core/targeting_spec.js +44 -0
  161. package/wdio.conf.js +1 -1
@@ -1,4 +1,4 @@
1
- import { triggerPixel, parseSizesInput, deepAccess, logError } from '../src/utils.js';
1
+ import { triggerPixel, parseSizesInput, deepAccess, logError, getGptSlotInfoForAdUnitCode } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { config } from '../src/config.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
@@ -203,7 +203,7 @@ export const spec = {
203
203
  },
204
204
  onTimeout: function(timeoutData) {
205
205
  // Call '/track/bid_timeout' with timeout data
206
- triggerPixel(buildUrl(TRACK_TIMEOUT_PATH) + '?data=' + JSON.stringify(timeoutData));
206
+ triggerPixel(buildUrl(TRACK_TIMEOUT_PATH) + '//' + JSON.stringify(timeoutData));
207
207
  }
208
208
  };
209
209
 
@@ -241,7 +241,7 @@ function makeVideo(videoParams = {}) {
241
241
  }
242
242
 
243
243
  function buildImpObject(bid) {
244
- const { params: { uid }, bidId, mediaTypes, sizes } = bid;
244
+ const { params: { uid }, bidId, mediaTypes, sizes, adUnitCode } = bid;
245
245
  const video = mediaTypes && _isVideoBid(bid) && _isValidVideoBid(bid) && makeVideo(mediaTypes.video);
246
246
  const banner = makeBanner((mediaTypes && mediaTypes.banner) || (!video && { sizes }));
247
247
  const impObject = {
@@ -253,6 +253,10 @@ function buildImpObject(bid) {
253
253
  }
254
254
  };
255
255
 
256
+ if (impObject.banner) {
257
+ impObject.ext.bidder.adslotExists = _isAdSlotExists(adUnitCode);
258
+ }
259
+
256
260
  if (impObject.ext.bidder.uid && (impObject.banner || impObject.video)) {
257
261
  return impObject;
258
262
  }
@@ -355,4 +359,17 @@ function _isValidVideoBid(bid, logErrors = false) {
355
359
  return result;
356
360
  }
357
361
 
362
+ function _isAdSlotExists(adUnitCode) {
363
+ if (document.getElementById(adUnitCode)) {
364
+ return true;
365
+ }
366
+
367
+ const gptAdSlot = getGptSlotInfoForAdUnitCode(adUnitCode);
368
+ if (gptAdSlot && gptAdSlot.divId && document.getElementById(gptAdSlot.divId)) {
369
+ return true;
370
+ }
371
+
372
+ return false;
373
+ }
374
+
358
375
  registerBidder(spec);
@@ -3,7 +3,7 @@
3
3
  ```
4
4
  Module Name: YOC VIS.X Bidder Adapter
5
5
  Module Type: Bidder Adapter
6
- Maintainer: service@yoc.com
6
+ Maintainer: supply.partners@yoc.com
7
7
  ```
8
8
 
9
9
  # Description
@@ -47,16 +47,14 @@ var adUnits = [
47
47
  }
48
48
  ]
49
49
  },
50
- // YOC In-stream adUnit
50
+ // In-stream video adUnit
51
51
  {
52
52
  code: 'instream-test-div',
53
53
  mediaTypes: {
54
54
  video: {
55
55
  context: 'instream',
56
- playerSize: [400, 300],
57
- mimes: ['video/mp4'],
58
- protocols: [3, 6]
59
- },
56
+ playerSize: [400, 300]
57
+ }
60
58
  },
61
59
  bids: [
62
60
  {
@@ -144,9 +144,9 @@ function getAdapterMode() {
144
144
 
145
145
  function getResponseFormat(bid) {
146
146
  const adm = bid.adm;
147
- if (adm.includes('o2playerSettings') || adm.includes('YAHOO.VideoPlatform.VideoPlayer') || adm.includes('AdPlacement')) {
147
+ if (adm.indexOf('o2playerSettings') !== -1 || adm.indexOf('YAHOO.VideoPlatform.VideoPlayer') !== -1 || adm.indexOf('AdPlacement') !== -1) {
148
148
  return BANNER;
149
- } else if (adm.includes('VAST')) {
149
+ } else if (adm.indexOf('VAST') !== -1) {
150
150
  return VIDEO;
151
151
  }
152
152
  };
@@ -188,23 +188,23 @@ function validateAppendObject(validationType, allowedKeys, inputObject, appendTo
188
188
  for (const objectKey in inputObject) {
189
189
  switch (validationType) {
190
190
  case 'string':
191
- if (allowedKeys.includes(objectKey) && isStr(inputObject[objectKey])) {
191
+ if (allowedKeys.indexOf(objectKey) !== -1 && isStr(inputObject[objectKey])) {
192
192
  outputObject[objectKey] = inputObject[objectKey];
193
193
  };
194
194
  break;
195
195
  case 'number':
196
- if (allowedKeys.includes(objectKey) && isNumber(inputObject[objectKey])) {
196
+ if (allowedKeys.indexOf(objectKey) !== -1 && isNumber(inputObject[objectKey])) {
197
197
  outputObject[objectKey] = inputObject[objectKey];
198
198
  };
199
199
  break;
200
200
 
201
201
  case 'array':
202
- if (allowedKeys.includes(objectKey) && isArray(inputObject[objectKey])) {
202
+ if (allowedKeys.indexOf(objectKey) !== -1 && isArray(inputObject[objectKey])) {
203
203
  outputObject[objectKey] = inputObject[objectKey];
204
204
  };
205
205
  break;
206
206
  case 'object':
207
- if (allowedKeys.includes(objectKey) && isPlainObject(inputObject[objectKey])) {
207
+ if (allowedKeys.indexOf(objectKey) !== -1 && isPlainObject(inputObject[objectKey])) {
208
208
  outputObject[objectKey] = inputObject[objectKey];
209
209
  };
210
210
  break;
@@ -57,7 +57,7 @@ At this time, only the following partners/publishers are eligble for pubId integ
57
57
  A. Do not have any display/banner inventory.
58
58
  B. Do not have any existing accounts on Yahoo SSP (aka: aol, oneMobile, oneDisplay).
59
59
 
60
- # Mandaotory Bidder Parameters
60
+ # Mandatory Bidder Parameters
61
61
  ## dcn & pos (DEFAULT)
62
62
  The minimal requirements for the 'yahoossp' bid adapter to generate an outbound bid-request to our Yahoo SSP are:
63
63
  1. At least 1 adUnit including mediaTypes: banner or video
@@ -1,7 +1,7 @@
1
1
  import { _each, isPlainObject, isArray, deepAccess } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js'
3
3
  import find from 'core-js-pure/features/array/find.js'
4
- import { VIDEO, BANNER } from '../src/mediaTypes.js'
4
+ import { VIDEO, BANNER, NATIVE } from '../src/mediaTypes.js'
5
5
  import { Renderer } from '../src/Renderer.js'
6
6
  import { config } from '../src/config.js';
7
7
 
@@ -15,7 +15,7 @@ const GVLID = 70
15
15
  export const spec = {
16
16
  code: BIDDER_CODE,
17
17
  gvlid: GVLID,
18
- supportedMediaTypes: [VIDEO, BANNER],
18
+ supportedMediaTypes: [VIDEO, BANNER, NATIVE],
19
19
 
20
20
  isBidRequestValid: function (bid) {
21
21
  if (bid && bid.params && bid.params.adslotId && bid.params.supplyId) {
@@ -149,6 +149,27 @@ export const spec = {
149
149
  }
150
150
  }
151
151
 
152
+ if (isNative(bidRequest, adType)) {
153
+ const url = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}`
154
+ bidResponse.adUrl = url
155
+ bidResponse.mediaType = NATIVE
156
+ const nativeImageAssetObj = find(matchedBid.native.assets, e => e.id === 2)
157
+ const nativeImageAsset = nativeImageAssetObj ? nativeImageAssetObj.img : {url: '', w: 0, h: 0};
158
+ const nativeTitleAsset = find(matchedBid.native.assets, e => e.id === 1)
159
+ const nativeBodyAsset = find(matchedBid.native.assets, e => e.id === 3)
160
+ bidResponse.native = {
161
+ title: nativeTitleAsset ? nativeTitleAsset.title.text : '',
162
+ body: nativeBodyAsset ? nativeBodyAsset.data.value : '',
163
+ image: {
164
+ url: nativeImageAsset.url,
165
+ width: nativeImageAsset.w,
166
+ height: nativeImageAsset.h,
167
+ },
168
+ clickUrl: matchedBid.native.link.url,
169
+ impressionTrackers: matchedBid.native.imptrackers,
170
+ };
171
+ }
172
+
152
173
  bidResponses.push(bidResponse)
153
174
  }
154
175
  })
@@ -162,16 +183,26 @@ export const spec = {
162
183
  * @param {String} adtype
163
184
  * @returns {Boolean}
164
185
  */
165
- function isVideo (format, adtype) {
186
+ function isVideo(format, adtype) {
166
187
  return deepAccess(format, 'mediaTypes.video') && adtype.toLowerCase() === 'video'
167
188
  }
168
189
 
190
+ /**
191
+ * Is this a native format?
192
+ * @param {Object} format
193
+ * @param {String} adtype
194
+ * @returns {Boolean}
195
+ */
196
+ function isNative(format, adtype) {
197
+ return deepAccess(format, 'mediaTypes.native') && adtype.toLowerCase() === 'native'
198
+ }
199
+
169
200
  /**
170
201
  * Is this an outstream context?
171
202
  * @param {Object} format
172
203
  * @returns {Boolean}
173
204
  */
174
- function isOutstream (format) {
205
+ function isOutstream(format) {
175
206
  let context = deepAccess(format, 'mediaTypes.video.context')
176
207
  return (context === 'outstream')
177
208
  }
@@ -181,7 +212,7 @@ function isOutstream (format) {
181
212
  * @param {Object} format
182
213
  * @returns {Array}
183
214
  */
184
- function getPlayerSize (format) {
215
+ function getPlayerSize(format) {
185
216
  let playerSize = deepAccess(format, 'mediaTypes.video.playerSize')
186
217
  return (playerSize && isArray(playerSize[0])) ? playerSize[0] : playerSize
187
218
  }
@@ -191,7 +222,7 @@ function getPlayerSize (format) {
191
222
  * @param {String} size
192
223
  * @returns {Array}
193
224
  */
194
- function parseSize (size) {
225
+ function parseSize(size) {
195
226
  return size.split('x').map(Number)
196
227
  }
197
228
 
@@ -200,7 +231,7 @@ function parseSize (size) {
200
231
  * @param {Array} eids
201
232
  * @returns {String}
202
233
  */
203
- function createUserIdString (eids) {
234
+ function createUserIdString(eids) {
204
235
  let str = []
205
236
  for (let i = 0; i < eids.length; i++) {
206
237
  str.push(eids[i].source + ':' + eids[i].uids[0].id)
@@ -213,7 +244,7 @@ function createUserIdString (eids) {
213
244
  * @param {Object} obj
214
245
  * @returns {String}
215
246
  */
216
- function createQueryString (obj) {
247
+ function createQueryString(obj) {
217
248
  let str = []
218
249
  for (var p in obj) {
219
250
  if (obj.hasOwnProperty(p)) {
@@ -233,7 +264,7 @@ function createQueryString (obj) {
233
264
  * @param {Object} obj
234
265
  * @returns {String}
235
266
  */
236
- function createTargetingString (obj) {
267
+ function createTargetingString(obj) {
237
268
  let str = []
238
269
  for (var p in obj) {
239
270
  if (obj.hasOwnProperty(p)) {
@@ -250,7 +281,7 @@ function createTargetingString (obj) {
250
281
  * @param {Object} schain
251
282
  * @returns {String}
252
283
  */
253
- function createSchainString (schain) {
284
+ function createSchainString(schain) {
254
285
  const ver = schain.ver || ''
255
286
  const complete = (schain.complete === 1 || schain.complete === 0) ? schain.complete : ''
256
287
  const keys = ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']
@@ -11,53 +11,96 @@ Maintainer: solutions@yieldlab.de
11
11
  Module that connects to Yieldlab's demand sources
12
12
 
13
13
  # Test Parameters
14
+
15
+ ```javascript
16
+ const adUnits = [
17
+ {
18
+ code: 'banner',
19
+ sizes: [ [ 728, 90 ] ],
20
+ bids: [{
21
+ bidder: 'yieldlab',
22
+ params: {
23
+ adslotId: '5220336',
24
+ supplyId: '1381604',
25
+ targeting: {
26
+ key1: 'value1',
27
+ key2: 'value2'
28
+ },
29
+ extId: 'abc',
30
+ iabContent: {
31
+ id: 'some_id',
32
+ episode: '1',
33
+ title: 'some title',
34
+ series: 'some series',
35
+ season: 's1',
36
+ artist: 'John Doe',
37
+ genre: 'some genre',
38
+ isrc: 'CC-XXX-YY-NNNNN',
39
+ url: 'http://foo_url.de',
40
+ cat: [ 'IAB1-1', 'IAB1-2', 'IAB2-10' ],
41
+ context: '7',
42
+ keywords: ['k1', 'k2'],
43
+ live: '0'
44
+ }
45
+ }
46
+ }]
47
+ },
48
+ {
49
+ code: 'video',
50
+ sizes: [ [ 640, 480 ] ],
51
+ mediaTypes: {
52
+ video: {
53
+ context: 'instream' // or 'outstream'
54
+ }
55
+ },
56
+ bids: [{
57
+ bidder: 'yieldlab',
58
+ params: {
59
+ adslotId: '5220339',
60
+ supplyId: '1381604'
61
+ }
62
+ }]
63
+ },
64
+ {
65
+ code: 'native',
66
+ mediaTypes: {
67
+ native: {
68
+ // native config
69
+ }
70
+ },
71
+ bids: [{
72
+ bidder: 'yieldlab',
73
+ params: {
74
+ adslotId: '5220339',
75
+ supplyId: '1381604'
76
+ }
77
+ }]
78
+ }
79
+ ];
14
80
  ```
15
- var adUnits = [
16
- {
17
- code: "banner",
18
- sizes: [[728, 90]],
19
- bids: [{
20
- bidder: "yieldlab",
21
- params: {
22
- adslotId: "5220336",
23
- supplyId: "1381604",
24
- targeting: {
25
- key1: "value1",
26
- key2: "value2"
27
- },
28
- extId: "abc",
29
- iabContent: {
30
- id: "some_id",
31
- episode: "1",
32
- title: "some title",
33
- series: "some series",
34
- season: "s1",
35
- artist: "John Doe",
36
- genre: "some genre",
37
- isrc: "CC-XXX-YY-NNNNN",
38
- url: "http://foo_url.de",
39
- cat: ["IAB1-1", "IAB1-2", "IAB2-10"],
40
- context: "7",
41
- keywords: ["k1", "k2"],
42
- live: "0"
43
- }
44
- }
45
- }]
46
- }, {
47
- code: "video",
48
- sizes: [[640, 480]],
49
- mediaTypes: {
50
- video: {
51
- context: "instream" // or "outstream"
52
- }
53
- },
54
- bids: [{
55
- bidder: "yieldlab",
56
- params: {
57
- adslotId: "5220339",
58
- supplyId: "1381604"
59
- }
60
- }]
61
- }
62
- ];
81
+
82
+ # Multi-Format Setup
83
+
84
+ A general overview of how to set up multi-format ads can be found in the offical Prebid.js docs. See: [show multi-format ads](https://docs.prebid.org/dev-docs/show-multi-format-ads.html)
85
+
86
+ When setting up multi-format ads with Yieldlab make sure to always add at least one eligible Adslot per given media type in the ad unit configuration.
87
+
88
+ ```javascript
89
+ const adUnit = {
90
+ code: 'multi-format-adslot',
91
+ mediaTypes: {
92
+ banner: {
93
+ sizes: [ [ 728, 90 ] ]
94
+ },
95
+ native: {
96
+ // native config
97
+ }
98
+ },
99
+ bids: [
100
+ // banner Adslot
101
+ { bidder: 'yieldlab', params: { adslotId: '1234', supplyId: '42' } },
102
+ // native Adslot
103
+ { bidder: 'yieldlab', params: { adslotId: '2345', supplyId: '42' } }
104
+ ]
105
+ };
63
106
  ```
@@ -1,4 +1,4 @@
1
- import { deepAccess, isEmpty, parseSizesInput, isStr, logWarn } from '../src/utils.js';
1
+ import {deepAccess, isEmpty, isStr, logWarn, parseSizesInput} from '../src/utils.js';
2
2
  import {config} from '../src/config.js';
3
3
  import {registerBidder} from '../src/adapters/bidderFactory.js';
4
4
  import { Renderer } from '../src/Renderer.js';
@@ -11,6 +11,8 @@ const VIDEO_PLAYER_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/d
11
11
  const CMER_PLAYER_URL = 'https://an.cmertv.com/hb/renderer/cmertv-video-yone-prebid.min.js';
12
12
  const VIEWABLE_PERCENTAGE_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/prebid-adformat-config.js';
13
13
 
14
+ const DEFAULT_VIDEO_SIZE = {w: 640, h: 360};
15
+
14
16
  export const spec = {
15
17
  code: BIDDER_CODE,
16
18
  aliases: ['y1'],
@@ -40,16 +42,18 @@ export const spec = {
40
42
  t: 'i'
41
43
  };
42
44
 
43
- const videoMediaType = deepAccess(bidRequest, 'mediaTypes.video');
44
- if ((isEmpty(bidRequest.mediaType) && isEmpty(bidRequest.mediaTypes)) ||
45
- (bidRequest.mediaType === BANNER || (bidRequest.mediaTypes && bidRequest.mediaTypes[BANNER]))) {
46
- const sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes;
47
- payload.sz = parseSizesInput(sizes).join(',');
48
- } else if (bidRequest.mediaType === VIDEO || videoMediaType) {
49
- const sizes = deepAccess(bidRequest, 'mediaTypes.video.playerSize') || bidRequest.sizes;
50
- const size = parseSizesInput(sizes)[0];
51
- payload.w = size.split('x')[0];
52
- payload.h = size.split('x')[1];
45
+ const mediaType = getMediaType(bidRequest);
46
+ switch (mediaType) {
47
+ case BANNER:
48
+ payload.sz = getBannerSizes(bidRequest);
49
+ break;
50
+ case VIDEO:
51
+ const videoSize = getVideoSize(bidRequest);
52
+ payload.w = videoSize.w;
53
+ payload.h = videoSize.h;
54
+ break;
55
+ default:
56
+ break;
53
57
  }
54
58
 
55
59
  // LiveRampID
@@ -167,6 +171,106 @@ export const spec = {
167
171
  },
168
172
  }
169
173
 
174
+ /**
175
+ * NOTE: server side does not yet support multiple formats.
176
+ * @param {Object} bidRequest -
177
+ * @param {boolean} [enabledOldFormat = true] - default: `true`.
178
+ * @return {string|null} - `"banner"` or `"video"` or `null`.
179
+ */
180
+ function getMediaType(bidRequest, enabledOldFormat = true) {
181
+ let hasBannerType = Boolean(deepAccess(bidRequest, 'mediaTypes.banner'));
182
+ let hasVideoType = Boolean(deepAccess(bidRequest, 'mediaTypes.video'));
183
+
184
+ if (enabledOldFormat) {
185
+ hasBannerType = hasBannerType || bidRequest.mediaType === BANNER ||
186
+ (isEmpty(bidRequest.mediaTypes) && isEmpty(bidRequest.mediaType));
187
+ hasVideoType = hasVideoType || bidRequest.mediaType === VIDEO;
188
+ }
189
+
190
+ if (hasBannerType && hasVideoType) {
191
+ const playerParams = deepAccess(bidRequest, 'params.playerParams')
192
+ if (playerParams) {
193
+ return VIDEO;
194
+ } else {
195
+ return BANNER;
196
+ }
197
+ } else if (hasBannerType) {
198
+ return BANNER;
199
+ } else if (hasVideoType) {
200
+ return VIDEO;
201
+ }
202
+
203
+ return null;
204
+ }
205
+
206
+ /**
207
+ * NOTE:
208
+ * If `mediaTypes.banner` exists, then `mediaTypes.banner.sizes` must also exist.
209
+ * The reason for this is that Prebid.js will perform the verification and
210
+ * if `mediaTypes.banner.sizes` is inappropriate, it will delete the entire `mediaTypes.banner`.
211
+ * @param {Object} bidRequest -
212
+ * @param {Object} bidRequest.banner -
213
+ * @param {Array<string>} bidRequest.banner.sizes -
214
+ * @param {boolean} [enabledOldFormat = true] - default: `true`.
215
+ * @return {string} - strings like `"300x250"` or `"300x250,728x90"`.
216
+ */
217
+ function getBannerSizes(bidRequest, enabledOldFormat = true) {
218
+ let sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes');
219
+
220
+ if (enabledOldFormat) {
221
+ sizes = sizes || bidRequest.sizes;
222
+ }
223
+
224
+ return parseSizesInput(sizes).join(',');
225
+ }
226
+
227
+ /**
228
+ * @param {Object} bidRequest -
229
+ * @param {boolean} [enabledOldFormat = true] - default: `true`.
230
+ * @param {boolean} [enabledFlux = true] - default: `true`.
231
+ * @return {{w: number, h: number}} -
232
+ */
233
+ function getVideoSize(bidRequest, enabledOldFormat = true, enabledFlux = true) {
234
+ /**
235
+ * @param {Array<number, number> | Array<Array<number, number>>} sizes -
236
+ * @return {{w: number, h: number} | null} -
237
+ */
238
+ const _getPlayerSize = (sizes) => {
239
+ let result = null;
240
+
241
+ const size = parseSizesInput(sizes)[0];
242
+ if (isEmpty(size)) {
243
+ return result;
244
+ }
245
+
246
+ const splited = size.split('x');
247
+ const sizeObj = {w: parseInt(splited[0], 10), h: parseInt(splited[1], 10)};
248
+ const _isValidPlayerSize = !(isEmpty(sizeObj)) && (isFinite(sizeObj.w) && isFinite(sizeObj.h));
249
+ if (!_isValidPlayerSize) {
250
+ return result;
251
+ }
252
+
253
+ result = sizeObj;
254
+ return result;
255
+ }
256
+
257
+ let playerSize = _getPlayerSize(deepAccess(bidRequest, 'mediaTypes.video.playerSize'));
258
+
259
+ if (enabledOldFormat) {
260
+ playerSize = playerSize || _getPlayerSize(bidRequest.sizes);
261
+ }
262
+
263
+ if (enabledFlux) {
264
+ // NOTE: `video.playerSize` in Flux is always [1,1].
265
+ if (playerSize && (playerSize.w === 1 && playerSize.h === 1)) {
266
+ // NOTE: `params.playerSize` is a specific object to support `FLUX`.
267
+ playerSize = _getPlayerSize(deepAccess(bidRequest, 'params.playerSize'));
268
+ }
269
+ }
270
+
271
+ return playerSize || DEFAULT_VIDEO_SIZE;
272
+ }
273
+
170
274
  function newRenderer(response) {
171
275
  const renderer = Renderer.install({
172
276
  id: response.uid,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "5.19.0",
3
+ "version": "6.2.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -11,6 +11,11 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/prebid/Prebid.js.git"
13
13
  },
14
+ "browserslist": [
15
+ "> 0.25%",
16
+ "not IE 11",
17
+ "not op_mini all"
18
+ ],
14
19
  "keywords": [
15
20
  "advertising",
16
21
  "auction",
@@ -262,14 +262,16 @@ adapterManager.makeBidRequests = hook('sync', function (adUnits, auctionStart, a
262
262
  }
263
263
 
264
264
  let adUnitsS2SCopy = getAdUnitCopyForPrebidServer(adUnits, s2sConfig);
265
- let tid = generateUUID();
265
+
266
+ // uniquePbsTid is so we know which server to send which bids to during the callBids function
267
+ let uniquePbsTid = generateUUID();
266
268
  adaptersServerSide.forEach(bidderCode => {
267
269
  const bidderRequestId = getUniqueIdentifierStr();
268
270
  const bidderRequest = {
269
271
  bidderCode,
270
272
  auctionId,
271
273
  bidderRequestId,
272
- tid,
274
+ uniquePbsTid,
273
275
  bids: hookedGetBids({bidderCode, auctionId, bidderRequestId, 'adUnits': deepClone(adUnitsS2SCopy), labels, src: CONSTANTS.S2S.SRC}),
274
276
  auctionStart: auctionStart,
275
277
  timeout: s2sConfig.timeout,
@@ -350,7 +352,7 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
350
352
  serverBidRequests.forEach(serverBidRequest => {
351
353
  var index = -1;
352
354
  for (var i = 0; i < uniqueServerBidRequests.length; ++i) {
353
- if (serverBidRequest.tid === uniqueServerBidRequests[i].tid) {
355
+ if (serverBidRequest.uniquePbsTid === uniqueServerBidRequests[i].uniquePbsTid) {
354
356
  index = i;
355
357
  break;
356
358
  }
@@ -360,7 +362,10 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
360
362
  }
361
363
  });
362
364
 
363
- let counter = 0
365
+ let counter = 0;
366
+
367
+ // $.source.tid MUST be a unique UUID and also THE SAME between all PBS Requests for a given Auction
368
+ const sourceTid = generateUUID();
364
369
  _s2sConfigs.forEach((s2sConfig) => {
365
370
  if (s2sConfig && uniqueServerBidRequests[counter] && includes(s2sConfig.bidders, uniqueServerBidRequests[counter].bidderCode)) {
366
371
  // s2s should get the same client side timeout as other client side requests.
@@ -370,13 +375,13 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
370
375
  } : undefined);
371
376
  let adaptersServerSide = s2sConfig.bidders;
372
377
  const s2sAdapter = _bidderRegistry[s2sConfig.adapter];
373
- let tid = uniqueServerBidRequests[counter].tid;
378
+ let uniquePbsTid = uniqueServerBidRequests[counter].uniquePbsTid;
374
379
  let adUnitsS2SCopy = uniqueServerBidRequests[counter].adUnitsS2SCopy;
375
380
 
376
- let uniqueServerRequests = serverBidRequests.filter(serverBidRequest => serverBidRequest.tid === tid)
381
+ let uniqueServerRequests = serverBidRequests.filter(serverBidRequest => serverBidRequest.uniquePbsTid === uniquePbsTid);
377
382
 
378
383
  if (s2sAdapter) {
379
- let s2sBidRequest = {tid, 'ad_units': adUnitsS2SCopy, s2sConfig};
384
+ let s2sBidRequest = {tid: sourceTid, 'ad_units': adUnitsS2SCopy, s2sConfig};
380
385
  if (s2sBidRequest.ad_units.length) {
381
386
  let doneCbs = uniqueServerRequests.map(bidRequest => {
382
387
  bidRequest.start = timestamp();
@@ -391,7 +396,8 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request
391
396
 
392
397
  // fire BID_REQUESTED event for each s2s bidRequest
393
398
  uniqueServerRequests.forEach(bidRequest => {
394
- events.emit(CONSTANTS.EVENTS.BID_REQUESTED, bidRequest);
399
+ // add the new sourceTid
400
+ events.emit(CONSTANTS.EVENTS.BID_REQUESTED, {...bidRequest, tid: sourceTid});
395
401
  });
396
402
 
397
403
  // make bid requests