prebid.js 7.54.0 → 7.54.2

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 (140) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/adyoulikeBidAdapter.js +1 -1
  11. package/dist/ajaBidAdapter.js +1 -1
  12. package/dist/amxBidAdapter.js +1 -1
  13. package/dist/amxIdSystem.js +1 -1
  14. package/dist/appierAnalyticsAdapter.js +1 -1
  15. package/dist/appnexusBidAdapter.js +1 -1
  16. package/dist/asoBidAdapter.js +1 -1
  17. package/dist/axonixBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bridgewellBidAdapter.js +1 -1
  21. package/dist/brightMountainMediaBidAdapter.js +1 -1
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/chtnwBidAdapter.js +1 -1
  24. package/dist/concertBidAdapter.js +1 -1
  25. package/dist/connectadBidAdapter.js +1 -1
  26. package/dist/consumableBidAdapter.js +1 -1
  27. package/dist/conversantAnalyticsAdapter.js +1 -1
  28. package/dist/conversantBidAdapter.js +1 -1
  29. package/dist/craftBidAdapter.js +1 -1
  30. package/dist/criteoBidAdapter.js +1 -1
  31. package/dist/cwireBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/euidIdSystem.js +1 -1
  35. package/dist/feedadBidAdapter.js +1 -1
  36. package/dist/finativeBidAdapter.js +1 -1
  37. package/dist/freewheel-sspBidAdapter.js +1 -1
  38. package/dist/glimpseBidAdapter.js +1 -1
  39. package/dist/gmosspBidAdapter.js +1 -1
  40. package/dist/goldbachBidAdapter.js +1 -1
  41. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  42. package/dist/greenbidsRtdProvider.js +1 -1
  43. package/dist/gridBidAdapter.js +1 -1
  44. package/dist/gumgumBidAdapter.js +1 -1
  45. package/dist/h12mediaBidAdapter.js +1 -1
  46. package/dist/hypelabBidAdapter.js +1 -1
  47. package/dist/id5IdSystem.js +1 -1
  48. package/dist/improvedigitalBidAdapter.js +1 -1
  49. package/dist/inmarBidAdapter.js +1 -1
  50. package/dist/insticatorBidAdapter.js +1 -1
  51. package/dist/ixBidAdapter.js +1 -1
  52. package/dist/justpremiumBidAdapter.js +1 -1
  53. package/dist/kargoBidAdapter.js +1 -1
  54. package/dist/konduitAnalyticsAdapter.js +1 -1
  55. package/dist/kueezBidAdapter.js +1 -1
  56. package/dist/kueezRtbBidAdapter.js +1 -1
  57. package/dist/kulturemediaBidAdapter.js +1 -1
  58. package/dist/lassoBidAdapter.js +1 -1
  59. package/dist/lifestreetBidAdapter.js +1 -1
  60. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  61. package/dist/logicadBidAdapter.js +1 -1
  62. package/dist/loglyliftBidAdapter.js +1 -1
  63. package/dist/magniteAnalyticsAdapter.js +1 -1
  64. package/dist/malltvAnalyticsAdapter.js +1 -1
  65. package/dist/marsmediaBidAdapter.js +1 -1
  66. package/dist/mediafuseBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/minutemediaplusBidAdapter.js +1 -1
  71. package/dist/nexx360BidAdapter.js +1 -1
  72. package/dist/not-for-prod/prebid.js +128 -128
  73. package/dist/oguryBidAdapter.js +1 -1
  74. package/dist/onetagBidAdapter.js +1 -1
  75. package/dist/ooloAnalyticsAdapter.js +1 -1
  76. package/dist/optidigitalBidAdapter.js +1 -1
  77. package/dist/outbrainBidAdapter.js +1 -1
  78. package/dist/oxxionRtdProvider.js +1 -1
  79. package/dist/parrableIdSystem.js +1 -1
  80. package/dist/pixfutureBidAdapter.js +1 -1
  81. package/dist/prebid-core.js +1 -1
  82. package/dist/publinkIdSystem.js +1 -1
  83. package/dist/pubmaticBidAdapter.js +1 -1
  84. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  85. package/dist/pxyzBidAdapter.js +1 -1
  86. package/dist/quantcastBidAdapter.js +1 -1
  87. package/dist/readpeakBidAdapter.js +1 -1
  88. package/dist/relaidoBidAdapter.js +1 -1
  89. package/dist/retailspotBidAdapter.js +1 -1
  90. package/dist/rhythmoneBidAdapter.js +1 -1
  91. package/dist/riseBidAdapter.js +1 -1
  92. package/dist/rubiconAnalyticsAdapter.js +1 -1
  93. package/dist/rubiconBidAdapter.js +1 -1
  94. package/dist/seedingAllianceBidAdapter.js +1 -1
  95. package/dist/seedtagBidAdapter.js +1 -1
  96. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  97. package/dist/sharethroughBidAdapter.js +1 -1
  98. package/dist/shinezBidAdapter.js +1 -1
  99. package/dist/smaatoBidAdapter.js +1 -1
  100. package/dist/smartadserverBidAdapter.js +1 -1
  101. package/dist/smartxBidAdapter.js +1 -1
  102. package/dist/smilewantedBidAdapter.js +1 -1
  103. package/dist/sonobiBidAdapter.js +1 -1
  104. package/dist/sovrnAnalyticsAdapter.js +1 -1
  105. package/dist/sovrnBidAdapter.js +1 -1
  106. package/dist/sspBCBidAdapter.js +1 -1
  107. package/dist/stvBidAdapter.js +1 -1
  108. package/dist/sublimeBidAdapter.js +1 -1
  109. package/dist/synacormediaBidAdapter.js +1 -1
  110. package/dist/targetVideoBidAdapter.js +1 -1
  111. package/dist/teadsBidAdapter.js +1 -1
  112. package/dist/trionBidAdapter.js +1 -1
  113. package/dist/tripleliftBidAdapter.js +1 -1
  114. package/dist/ttdBidAdapter.js +1 -1
  115. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  116. package/dist/uid2IdSystem.js +1 -1
  117. package/dist/underdogmediaBidAdapter.js +1 -1
  118. package/dist/undertoneBidAdapter.js +1 -1
  119. package/dist/vidazooBidAdapter.js +1 -1
  120. package/dist/videobyteBidAdapter.js +1 -1
  121. package/dist/visxBidAdapter.js +1 -1
  122. package/dist/vuukleBidAdapter.js +1 -1
  123. package/dist/widespaceBidAdapter.js +1 -1
  124. package/dist/winrBidAdapter.js +1 -1
  125. package/dist/yahoosspBidAdapter.js +1 -1
  126. package/dist/yieldmoBidAdapter.js +1 -1
  127. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  128. package/modules/adqueryBidAdapter.js +21 -18
  129. package/modules/ixBidAdapter.js +285 -53
  130. package/modules/kargoBidAdapter.js +4 -0
  131. package/modules/mediasquareBidAdapter.js +19 -23
  132. package/modules/oxxionRtdProvider.js +124 -11
  133. package/modules/rubiconBidAdapter.js +13 -1
  134. package/modules/yahoosspBidAdapter.js +8 -7
  135. package/package.json +1 -1
  136. package/test/spec/modules/ixBidAdapter_spec.js +745 -3
  137. package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
  138. package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
  139. package/test/spec/modules/rubiconBidAdapter_spec.js +41 -0
  140. package/test/spec/modules/yahoosspBidAdapter_spec.js +54 -24
@@ -1,7 +1,6 @@
1
1
  import {registerBidder} from '../src/adapters/bidderFactory.js';
2
2
  import {BANNER} from '../src/mediaTypes.js';
3
- import { logInfo, buildUrl, triggerPixel, parseSizesInput } from '../src/utils.js';
4
- import { getStorageManager } from '../src/storageManager.js';
3
+ import {buildUrl, getUniqueIdentifierStr, logInfo, parseSizesInput, triggerPixel} from '../src/utils.js';
5
4
 
6
5
  const ADQUERY_GVLID = 902;
7
6
  const ADQUERY_BIDDER_CODE = 'adquery';
@@ -11,7 +10,6 @@ const ADQUERY_USER_SYNC_DOMAIN = ADQUERY_BIDDER_DOMAIN_PROTOCOL + '://' + ADQUER
11
10
  const ADQUERY_DEFAULT_CURRENCY = 'PLN';
12
11
  const ADQUERY_NET_REVENUE = true;
13
12
  const ADQUERY_TTL = 360;
14
- const storage = getStorageManager({bidderCode: ADQUERY_BIDDER_CODE});
15
13
 
16
14
  /** @type {BidderSpec} */
17
15
  export const spec = {
@@ -57,8 +55,6 @@ export const spec = {
57
55
  interpretResponse: (response, request) => {
58
56
  logInfo(request);
59
57
  logInfo(response);
60
-
61
- let qid = null;
62
58
  const res = response && response.body && response.body.data;
63
59
  let bidResponses = [];
64
60
 
@@ -87,17 +83,6 @@ export const spec = {
87
83
  bidResponses.push(bidResponse);
88
84
  logInfo('bidResponses', bidResponses);
89
85
 
90
- if (res && res.qid) {
91
- if (storage.getDataFromLocalStorage('qid')) {
92
- qid = storage.getDataFromLocalStorage('qid');
93
- if (qid && qid.includes('%7B%22')) {
94
- storage.setDataInLocalStorage('qid', res.qid);
95
- }
96
- } else {
97
- storage.setDataInLocalStorage('qid', res.qid);
98
- }
99
- }
100
-
101
86
  return bidResponses;
102
87
  },
103
88
 
@@ -189,8 +174,26 @@ export const spec = {
189
174
  }
190
175
 
191
176
  };
177
+
192
178
  function buildRequest(validBidRequests, bidderRequest) {
193
179
  let bid = validBidRequests;
180
+ logInfo('buildRequest: ', bid);
181
+
182
+ let userId = null;
183
+ if (window.qid) {
184
+ userId = window.qid;
185
+ }
186
+
187
+ if (bid.userId && bid.userId.qid) {
188
+ userId = bid.userId.qid
189
+ }
190
+
191
+ if (!userId) {
192
+ // onetime User ID
193
+ userId = (getUniqueIdentifierStr() + '_' + getUniqueIdentifierStr()).substring(0, 22);
194
+ window.qid = userId;
195
+ }
196
+
194
197
  let pageUrl = '';
195
198
  if (bidderRequest && bidderRequest.refererInfo) {
196
199
  pageUrl = bidderRequest.refererInfo.page || '';
@@ -199,10 +202,10 @@ function buildRequest(validBidRequests, bidderRequest) {
199
202
  return {
200
203
  v: '$prebid.version$',
201
204
  placementCode: bid.params.placementId,
202
- auctionId: bid.auctionId,
205
+ auctionId: null,
203
206
  type: bid.params.type,
204
207
  adUnitCode: bid.adUnitCode,
205
- bidQid: storage.getDataFromLocalStorage('qid') || null,
208
+ bidQid: userId,
206
209
  bidId: bid.bidId,
207
210
  bidder: bid.bidder,
208
211
  bidPageUrl: pageUrl,
@@ -104,7 +104,9 @@ let hasRegisteredHandler = false;
104
104
  export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
105
105
  export const FEATURE_TOGGLES = {
106
106
  // Update with list of CFTs to be requested from Exchange
107
- REQUESTED_FEATURE_TOGGLES: [],
107
+ REQUESTED_FEATURE_TOGGLES: [
108
+ 'pbjs_enable_multiformat'
109
+ ],
108
110
 
109
111
  featureToggles: {},
110
112
  isFeatureEnabled: function (ft) {
@@ -183,7 +185,7 @@ function bidToBannerImp(bid) {
183
185
  * @param {object} bid A valid bid request config object.
184
186
  * @return {object} A impression object that will be sent to ad server.
185
187
  */
186
- function bidToVideoImp(bid) {
188
+ export function bidToVideoImp(bid) {
187
189
  const imp = bidToImp(bid, VIDEO);
188
190
  const videoAdUnitRef = deepAccess(bid, 'mediaTypes.video');
189
191
  const videoParamRef = deepAccess(bid, 'params.video');
@@ -266,7 +268,7 @@ function verifyVideoPlcmt(imp) {
266
268
  * @param {object} bid A valid bid request config object.
267
269
  * @return {object} A impression object that will be sent to ad server.
268
270
  */
269
- function bidToNativeImp(bid) {
271
+ export function bidToNativeImp(bid) {
270
272
  const imp = bidToImp(bid, NATIVE);
271
273
 
272
274
  const request = bid.nativeOrtbRequest
@@ -364,14 +366,30 @@ function _applyFloor(bid, imp, mediaType) {
364
366
  }
365
367
 
366
368
  // Prioritize module floor over bidder.param floor
369
+ let setFloor = false;
367
370
  if (moduleFloor) {
368
371
  imp.bidfloor = moduleFloor.floor;
369
372
  imp.bidfloorcur = moduleFloor.currency;
370
373
  imp.ext.fl = FLOOR_SOURCE.PBJS;
374
+ setFloor = true;
371
375
  } else if (adapterFloor) {
372
376
  imp.bidfloor = adapterFloor.floor;
373
377
  imp.bidfloorcur = adapterFloor.currency;
374
378
  imp.ext.fl = FLOOR_SOURCE.IX;
379
+ setFloor = true;
380
+ }
381
+
382
+ if (setFloor) {
383
+ if (mediaType == BANNER) {
384
+ deepSetValue(imp, 'banner.ext.bidfloor', imp.bidfloor);
385
+ deepSetValue(imp, 'banner.ext.fl', imp.ext.fl);
386
+ } else if (mediaType == VIDEO) {
387
+ deepSetValue(imp, 'video.ext.bidfloor', imp.bidfloor);
388
+ deepSetValue(imp, 'video.ext.fl', imp.ext.fl);
389
+ } else {
390
+ deepSetValue(imp, 'native.ext.bidfloor', imp.bidfloor);
391
+ deepSetValue(imp, 'native.ext.fl', imp.ext.fl);
392
+ }
375
393
  }
376
394
  }
377
395
 
@@ -680,6 +698,9 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
680
698
 
681
699
  const isLastAdUnit = adUnitIndex === transactionIds.length - 1;
682
700
 
701
+ r = deduplicateImpExtFields(r);
702
+ r = removeSiteIDs(r);
703
+
683
704
  if (isLastAdUnit) {
684
705
  requests.push({
685
706
  method: 'POST',
@@ -889,61 +910,114 @@ function addImpressions(impressions, transactionIds, r, adUnitIndex) {
889
910
  const gpid = impressions[transactionIds[adUnitIndex]].gpid;
890
911
  const dfpAdUnitCode = impressions[transactionIds[adUnitIndex]].dfp_ad_unit_code;
891
912
  const tid = impressions[transactionIds[adUnitIndex]].tid;
892
- const sid = impressions[transactionIds[adUnitIndex]].sid
893
-
894
- if (impressionObjects.length && BANNER in impressionObjects[0]) {
895
- const { id, banner: { topframe } } = impressionObjects[0];
896
- const _bannerImpression = {
897
- id,
898
- banner: {
899
- topframe,
900
- format: impressionObjects.map(({ banner: { w, h }, ext }) => ({ w, h, ext }))
901
- },
902
- };
903
-
904
- for (let i = 0; i < _bannerImpression.banner.format.length; i++) {
905
- // We add sid in imp.ext.sid therefore, remove from banner.format[].ext
906
- if (_bannerImpression.banner.format[i].ext != null && _bannerImpression.banner.format[i].ext.sid != null) {
907
- delete _bannerImpression.banner.format[i].ext.sid;
913
+ const sid = impressions[transactionIds[adUnitIndex]].sid;
914
+ const bannerImpressions = impressionObjects.filter(impression => BANNER in impression);
915
+ const otherImpressions = impressionObjects.filter(impression => !(BANNER in impression));
916
+
917
+ if (bannerImpressions.length > 0) {
918
+ const bannerImpsKeyed = bannerImpressions.reduce((acc, bannerImp) => {
919
+ if (!acc[bannerImp.id]) {
920
+ acc[bannerImp.id] = []
908
921
  }
922
+ acc[bannerImp.id].push(bannerImp);
923
+ return acc;
924
+ }, {});
925
+ for (const impId in bannerImpsKeyed) {
926
+ const bannerImps = bannerImpsKeyed[impId];
927
+ const { id, banner: { topframe } } = bannerImps[0];
928
+ const _bannerImpression = {
929
+ id,
930
+ banner: {
931
+ topframe,
932
+ format: bannerImps.map(({ banner: { w, h }, ext }) => ({ w, h, ext }))
933
+ },
934
+ };
935
+
936
+ for (let i = 0; i < _bannerImpression.banner.format.length; i++) {
937
+ // We add sid in imp.ext.sid therefore, remove from banner.format[].ext
938
+ if (_bannerImpression.banner.format[i].ext != null && _bannerImpression.banner.format[i].ext.sid != null) {
939
+ delete _bannerImpression.banner.format[i].ext.sid;
940
+ }
909
941
 
910
- // add floor per size
911
- if ('bidfloor' in impressionObjects[i]) {
912
- _bannerImpression.banner.format[i].ext.bidfloor = impressionObjects[i].bidfloor;
942
+ // add floor per size
943
+ if ('bidfloor' in bannerImps[i]) {
944
+ _bannerImpression.banner.format[i].ext.bidfloor = bannerImps[i].bidfloor;
945
+ }
913
946
  }
914
- }
915
947
 
916
- const position = impressions[transactionIds[adUnitIndex]].pos;
917
- if (isInteger(position)) {
918
- _bannerImpression.banner.pos = position;
919
- }
948
+ const position = impressions[transactionIds[adUnitIndex]].pos;
949
+ if (isInteger(position)) {
950
+ _bannerImpression.banner.pos = position;
951
+ }
920
952
 
921
- if (dfpAdUnitCode || gpid || tid || sid) {
922
- _bannerImpression.ext = {};
923
- _bannerImpression.ext.dfp_ad_unit_code = dfpAdUnitCode;
924
- _bannerImpression.ext.gpid = gpid;
925
- _bannerImpression.ext.tid = tid;
926
- _bannerImpression.ext.sid = sid;
927
- }
953
+ if (dfpAdUnitCode || gpid || tid || sid) {
954
+ _bannerImpression.ext = {};
955
+ _bannerImpression.ext.dfp_ad_unit_code = dfpAdUnitCode;
956
+ _bannerImpression.ext.gpid = gpid;
957
+ _bannerImpression.ext.tid = tid;
958
+ _bannerImpression.ext.sid = sid;
959
+ }
928
960
 
929
- if ('bidfloor' in impressionObjects[0]) {
930
- _bannerImpression.bidfloor = impressionObjects[0].bidfloor;
931
- }
961
+ if ('bidfloor' in bannerImps[0]) {
962
+ _bannerImpression.bidfloor = bannerImps[0].bidfloor;
963
+ }
932
964
 
933
- if ('bidfloorcur' in impressionObjects[0]) {
934
- _bannerImpression.bidfloorcur = impressionObjects[0].bidfloorcur;
935
- }
965
+ if ('bidfloorcur' in bannerImps[0]) {
966
+ _bannerImpression.bidfloorcur = bannerImps[0].bidfloorcur;
967
+ }
936
968
 
937
- const adUnitFPD = impressions[transactionIds[adUnitIndex]].adUnitFPD
938
- if (adUnitFPD) {
939
- _bannerImpression.ext.data = adUnitFPD;
969
+ const adUnitFPD = impressions[transactionIds[adUnitIndex]].adUnitFPD
970
+ if (adUnitFPD) {
971
+ deepSetValue(_bannerImpression, 'ext.data', adUnitFPD);
972
+ }
973
+ r.imp.push(_bannerImpression);
940
974
  }
941
-
942
- r.imp.push(_bannerImpression);
943
- } else {
944
- // set imp.ext.gpid to resolved gpid for each imp
945
- impressionObjects.forEach(imp => deepSetValue(imp, 'ext.gpid', gpid));
946
- r.imp.push(...impressionObjects);
975
+ }
976
+ if (otherImpressions.length > 0) {
977
+ // Creates multiformat imp if they have the same ID
978
+ // if not same ID, just add the imp to the imp array
979
+ // Removes imp.ext.bidfloor
980
+ // Sets imp.ext.siteID to one of the other [video/native].ext.siteid if imp.ext.siteID doesnt exist
981
+ otherImpressions.forEach(imp => {
982
+ deepSetValue(imp, 'ext.gpid', gpid);
983
+ if (r.imp.length > 0) {
984
+ let matchFound = false;
985
+ r.imp.forEach((rImp, index) => {
986
+ if (imp.id === rImp.id && VIDEO in imp) {
987
+ rImp.video = imp.video;
988
+ rImp.video.ext = Object.assign({}, imp.video.ext, imp.ext);
989
+ if (deepAccess(rImp, 'video.ext.bidfloor', false) && deepAccess(rImp, 'bidfloor', false)) {
990
+ if (rImp.video.ext.bidfloor < rImp.bidfloor) {
991
+ rImp.bidfloor = rImp.video.ext.bidfloor;
992
+ }
993
+ }
994
+ if (!deepAccess(rImp, 'ext.siteID', false) && deepAccess(imp, 'video.ext.siteID')) {
995
+ deepSetValue(rImp, 'ext.siteID', imp.video.ext.siteID);
996
+ deepSetValue(r, 'ext.ixdiag.usid', true);
997
+ }
998
+ matchFound = true;
999
+ } else if (imp.id === rImp.id && NATIVE in imp) {
1000
+ rImp.native = imp.native;
1001
+ rImp.native.ext = Object.assign({}, imp.native.ext, imp.ext);
1002
+ if (deepAccess(rImp, 'native.ext.bidfloor', false) && deepAccess(rImp, 'bidfloor', false)) {
1003
+ if (rImp.native.ext.bidfloor < rImp.bidfloor) {
1004
+ rImp.bidfloor = rImp.native.ext.bidfloor;
1005
+ }
1006
+ }
1007
+ if (!deepAccess(rImp, 'ext.siteID', false) && deepAccess(imp, 'native.ext.siteID', false)) {
1008
+ deepSetValue(rImp, 'ext.siteID', imp.native.ext.siteID);
1009
+ deepSetValue(r, 'ext.ixdiag.usid', true);
1010
+ }
1011
+ matchFound = true;
1012
+ }
1013
+ });
1014
+ if (!matchFound) {
1015
+ r.imp.push(imp);
1016
+ }
1017
+ } else {
1018
+ r.imp.push(imp);
1019
+ }
1020
+ });
947
1021
  }
948
1022
 
949
1023
  return r;
@@ -1643,15 +1717,30 @@ export const spec = {
1643
1717
  }
1644
1718
  }
1645
1719
 
1646
- // Step 4: Build banner, video & native requests
1720
+ // Step 3: Build banner, video & native requests
1721
+ let allImps = [];
1647
1722
  if (Object.keys(bannerImps).length > 0) {
1648
- reqs.push(...buildRequest(validBidRequests, bidderRequest, bannerImps, BANNER_ENDPOINT_VERSION));
1723
+ allImps.push(bannerImps);
1649
1724
  }
1650
1725
  if (Object.keys(videoImps).length > 0) {
1651
- reqs.push(...buildRequest(validBidRequests, bidderRequest, videoImps, VIDEO_ENDPOINT_VERSION));
1726
+ allImps.push(videoImps);
1652
1727
  }
1653
1728
  if (Object.keys(nativeImps).length > 0) {
1654
- reqs.push(...buildRequest(validBidRequests, bidderRequest, nativeImps));
1729
+ allImps.push(nativeImps);
1730
+ }
1731
+
1732
+ if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_multiformat')) {
1733
+ reqs.push(...buildRequest(validBidRequests, bidderRequest, combineImps(allImps)));
1734
+ } else {
1735
+ if (Object.keys(bannerImps).length > 0) {
1736
+ reqs.push(...buildRequest(validBidRequests, bidderRequest, bannerImps, BANNER_ENDPOINT_VERSION));
1737
+ }
1738
+ if (Object.keys(videoImps).length > 0) {
1739
+ reqs.push(...buildRequest(validBidRequests, bidderRequest, videoImps, VIDEO_ENDPOINT_VERSION));
1740
+ }
1741
+ if (Object.keys(nativeImps).length > 0) {
1742
+ reqs.push(...buildRequest(validBidRequests, bidderRequest, nativeImps));
1743
+ }
1655
1744
  }
1656
1745
 
1657
1746
  return reqs;
@@ -1789,4 +1878,147 @@ function buildImgSyncUrl(syncsPerBidder, index) {
1789
1878
  return IMG_USER_SYNC_URL + '&site_id=' + siteID.toString() + '&p=' + syncsPerBidder.toString() + '&i=' + index.toString() + '&gdpr=' + gdprApplies + '&gdpr_consent=' + consentString + '&us_privacy=' + (usPrivacy || '');
1790
1879
  }
1791
1880
 
1881
+ /**
1882
+ * Combines all imps into a single object
1883
+ * @param {array} imps array of imps
1884
+ * @returns object
1885
+ */
1886
+ export function combineImps(imps) {
1887
+ const result = {}
1888
+ imps.forEach((imp) => {
1889
+ Object.keys(imp).forEach((key) => {
1890
+ if (Object.keys(result).includes(key)) {
1891
+ if (result[key].hasOwnProperty('ixImps') && imp[key].hasOwnProperty('ixImps')) {
1892
+ result[key].ixImps = [...result[key].ixImps, ...imp[key].ixImps];
1893
+ } else if (result[key].hasOwnProperty('missingImps') && imp[key].hasOwnProperty('missingImps')) {
1894
+ result[key].missingImps = [...result[key].missingImps, ...imp[key].missingImps];
1895
+ } else if (imp[key].hasOwnProperty('ixImps')) {
1896
+ result[key].ixImps = imp[key].ixImps;
1897
+ } else if (imp[key].hasOwnProperty('missingImps')) {
1898
+ result[key].missingImps = imp[key].missingImps
1899
+ }
1900
+ } else {
1901
+ result[key] = imp[key];
1902
+ }
1903
+ });
1904
+ });
1905
+ return result;
1906
+ }
1907
+
1908
+ /**
1909
+ * Deduplicates ext fields. For example if imp.ext.tid exists, removes imp.banner.ext.tid
1910
+ *
1911
+ * @param {object} r request object
1912
+ * @returns object
1913
+ */
1914
+ export function deduplicateImpExtFields(r) {
1915
+ r.imp.forEach((imp, index) => {
1916
+ const impExt = imp.ext;
1917
+ if (impExt == undefined) {
1918
+ return r;
1919
+ }
1920
+ if (getFormatCount(imp) < 2) {
1921
+ return;
1922
+ }
1923
+ Object.keys(impExt).forEach((key) => {
1924
+ if (BANNER in imp) {
1925
+ const bannerExt = imp.banner.ext;
1926
+ if (bannerExt !== undefined && bannerExt[key] !== undefined && bannerExt[key] == impExt[key]) {
1927
+ delete r.imp[index].banner.ext[key];
1928
+ }
1929
+ if (imp.banner.format !== undefined) {
1930
+ for (let i = 0; i < imp.banner.format.length; i++) {
1931
+ if (imp.banner.format[i].ext != undefined && imp.banner.format[i].ext[key] != undefined && imp.banner.format[i].ext[key] == impExt[key]) {
1932
+ delete r.imp[index].banner.format[i].ext[key];
1933
+ }
1934
+ }
1935
+ }
1936
+ }
1937
+ if (VIDEO in imp) {
1938
+ const videoExt = imp.video.ext;
1939
+ if (videoExt !== undefined && videoExt[key] !== undefined && videoExt[key] == impExt[key]) {
1940
+ delete r.imp[index].video.ext[key];
1941
+ }
1942
+ }
1943
+
1944
+ if (NATIVE in imp) {
1945
+ const nativeExt = imp.native.ext;
1946
+ if (nativeExt !== undefined && nativeExt[key] !== undefined && nativeExt[key] == impExt[key]) {
1947
+ delete r.imp[index].native.ext[key];
1948
+ }
1949
+ }
1950
+ });
1951
+ });
1952
+ return r;
1953
+ }
1954
+
1955
+ /**
1956
+ * Removes ext.siteids in multiformat scenario
1957
+ * Site id will be set only at imp.ext.siteId
1958
+ *
1959
+ * @param {object} r request object
1960
+ * @returns object
1961
+ */
1962
+ export function removeSiteIDs(r) {
1963
+ r.imp.forEach((imp, index) => {
1964
+ const impExt = imp.ext;
1965
+ if (impExt == undefined) {
1966
+ return r;
1967
+ }
1968
+ if (getFormatCount(imp) < 2) {
1969
+ return;
1970
+ }
1971
+
1972
+ if (BANNER in imp) {
1973
+ const bannerExt = imp.banner.ext;
1974
+ if (bannerExt !== undefined && bannerExt.siteID !== undefined) {
1975
+ delete r.imp[index].banner.ext.siteID;
1976
+ }
1977
+ if (imp.banner.format !== undefined) {
1978
+ for (let i = 0; i < imp.banner.format.length; i++) {
1979
+ if (imp.banner.format[i].ext !== undefined && imp.banner.format[i].ext.siteID !== undefined) {
1980
+ deepSetValue(r.imp[index], 'ext.siteID', imp.banner.format[i].ext.siteID);
1981
+ deepSetValue(r, 'ext.ixdiag.usid', true);
1982
+ delete r.imp[index].banner.format[i].ext.siteID;
1983
+ }
1984
+ }
1985
+ }
1986
+ }
1987
+
1988
+ if (VIDEO in imp) {
1989
+ const videoExt = imp.video.ext;
1990
+ if (videoExt !== undefined && videoExt.siteID !== undefined) {
1991
+ delete r.imp[index].video.ext.siteID;
1992
+ }
1993
+ }
1994
+
1995
+ if (NATIVE in imp) {
1996
+ const nativeExt = imp.native.ext;
1997
+ if (nativeExt !== undefined && nativeExt.siteID !== undefined) {
1998
+ delete r.imp[index].native.ext.siteID;
1999
+ }
2000
+ }
2001
+ });
2002
+ return r;
2003
+ }
2004
+
2005
+ /**
2006
+ * Gets count of banner/video/native formats in imp
2007
+ * @param {object} imp
2008
+ * @returns int
2009
+ */
2010
+ function getFormatCount(imp) {
2011
+ let formatCount = 0;
2012
+ if (imp.banner !== undefined) {
2013
+ formatCount += 1;
2014
+ }
2015
+ if (imp.video !== undefined) {
2016
+ formatCount += 1;
2017
+ }
2018
+ if (imp.native !== undefined) {
2019
+ formatCount += 1;
2020
+ }
2021
+ return formatCount;
2022
+ }
2023
+
1792
2024
  registerBidder(spec);
@@ -97,6 +97,10 @@ function buildRequests(validBidRequests, bidderRequest) {
97
97
  user: getUserIds(tdidAdapter, bidderRequest.uspConsent, bidderRequest.gdprConsent, firstBidRequest.userIdAsEids, bidderRequest.gppConsent),
98
98
  });
99
99
 
100
+ if (firstBidRequest.schain && firstBidRequest.schain.nodes) {
101
+ krakenParams.schain = firstBidRequest.schain
102
+ }
103
+
100
104
  const reqCount = getRequestCount()
101
105
  if (reqCount != null) {
102
106
  krakenParams.requestCount = reqCount;
@@ -119,23 +119,17 @@ export const spec = {
119
119
  netRevenue: value['net_revenue'],
120
120
  ttl: value['ttl'],
121
121
  ad: value['ad'],
122
- mediasquare: {
123
- 'bidder': value['bidder'],
124
- 'code': value['code']
125
- },
122
+ mediasquare: {},
126
123
  meta: {
127
124
  'advertiserDomains': value['adomain']
128
125
  }
129
126
  };
130
- if ('context' in value) {
131
- bidResponse['mediasquare']['context'] = value['context'];
132
- }
133
- if ('match' in value) {
134
- bidResponse['mediasquare']['match'] = value['match'];
135
- }
136
- if ('hasConsent' in value) {
137
- bidResponse['mediasquare']['hasConsent'] = value['hasConsent'];
138
- }
127
+ let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment'];
128
+ paramsToSearchFor.forEach(param => {
129
+ if (param in value) {
130
+ bidResponse['mediasquare'][param] = value[param];
131
+ }
132
+ });
139
133
  if ('native' in value) {
140
134
  bidResponse['native'] = value['native'];
141
135
  bidResponse['mediaType'] = 'native';
@@ -179,21 +173,23 @@ export const spec = {
179
173
  }
180
174
  let params = { pbjs: '$prebid.version$', referer: encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation) };
181
175
  let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
182
- let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context'];
176
+ let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment'];
183
177
  if (bid.hasOwnProperty('mediasquare')) {
184
- for (let i = 0; i < paramsToSearchFor.length; i++) {
185
- if (bid['mediasquare'].hasOwnProperty(paramsToSearchFor[i])) {
186
- params[paramsToSearchFor[i]] = bid['mediasquare'][paramsToSearchFor[i]];
178
+ paramsToSearchFor.forEach(param => {
179
+ if (bid['mediasquare'].hasOwnProperty(param)) {
180
+ params[param] = bid['mediasquare'][param];
187
181
  }
188
- }
182
+ });
189
183
  };
190
184
  paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency'];
191
- for (let i = 0; i < paramsToSearchFor.length; i++) {
192
- if (bid.hasOwnProperty(paramsToSearchFor[i])) {
193
- params[paramsToSearchFor[i]] = bid[paramsToSearchFor[i]];
194
- if (typeof params[paramsToSearchFor[i]] == 'number') { params[paramsToSearchFor[i]] = params[paramsToSearchFor[i]].toString() }
185
+ paramsToSearchFor.forEach(param => {
186
+ if (bid.hasOwnProperty(param)) {
187
+ params[param] = bid[param];
188
+ if (typeof params[param] == 'number') {
189
+ params[param] = params[param].toString();
190
+ }
195
191
  }
196
- }
192
+ });
197
193
  ajax(endpoint + BIDDER_ENDPOINT_WINNING, null, JSON.stringify(params), {method: 'POST', withCredentials: true});
198
194
  return true;
199
195
  }