prebid.js 7.45.0 → 7.46.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 (189) 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/admaticBidAdapter.js +1 -1
  7. package/dist/adnuntiusBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/ajaBidAdapter.js +1 -1
  13. package/dist/amxBidAdapter.js +1 -1
  14. package/dist/amxIdSystem.js +1 -1
  15. package/dist/appierAnalyticsAdapter.js +1 -1
  16. package/dist/appnexusBidAdapter.js +1 -1
  17. package/dist/asoBidAdapter.js +1 -1
  18. package/dist/axonixBidAdapter.js +1 -1
  19. package/dist/bidglassBidAdapter.js +1 -1
  20. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  21. package/dist/big-richmediaBidAdapter.js +1 -1
  22. package/dist/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantAnalyticsAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/craftBidAdapter.js +1 -1
  32. package/dist/criteoBidAdapter.js +1 -1
  33. package/dist/cwireBidAdapter.js +1 -1
  34. package/dist/debugging-standalone.js +1 -1
  35. package/dist/dependencies.json +3 -0
  36. package/dist/dspxBidAdapter.js +1 -1
  37. package/dist/eplanningBidAdapter.js +1 -1
  38. package/dist/eskimiBidAdapter.js +1 -0
  39. package/dist/feedadBidAdapter.js +1 -1
  40. package/dist/finativeBidAdapter.js +1 -1
  41. package/dist/freewheel-sspBidAdapter.js +1 -1
  42. package/dist/glimpseBidAdapter.js +1 -1
  43. package/dist/gmosspBidAdapter.js +1 -1
  44. package/dist/goldbachBidAdapter.js +1 -1
  45. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  46. package/dist/gridBidAdapter.js +1 -1
  47. package/dist/gumgumBidAdapter.js +1 -1
  48. package/dist/h12mediaBidAdapter.js +1 -1
  49. package/dist/id5IdSystem.js +1 -1
  50. package/dist/improvedigitalBidAdapter.js +1 -1
  51. package/dist/inmarBidAdapter.js +1 -1
  52. package/dist/insticatorBidAdapter.js +1 -1
  53. package/dist/ixBidAdapter.js +1 -1
  54. package/dist/justpremiumBidAdapter.js +1 -1
  55. package/dist/kargoBidAdapter.js +1 -1
  56. package/dist/konduitAnalyticsAdapter.js +1 -1
  57. package/dist/kueezBidAdapter.js +1 -1
  58. package/dist/kueezRtbBidAdapter.js +1 -1
  59. package/dist/kulturemediaBidAdapter.js +1 -1
  60. package/dist/lassoBidAdapter.js +1 -1
  61. package/dist/lifestreetBidAdapter.js +1 -1
  62. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  63. package/dist/logicadBidAdapter.js +1 -1
  64. package/dist/loglyliftBidAdapter.js +1 -1
  65. package/dist/magniteAnalyticsAdapter.js +1 -1
  66. package/dist/malltvAnalyticsAdapter.js +1 -1
  67. package/dist/marsmediaBidAdapter.js +1 -1
  68. package/dist/mediafuseBidAdapter.js +1 -1
  69. package/dist/mediasquareBidAdapter.js +1 -1
  70. package/dist/mgidBidAdapter.js +1 -1
  71. package/dist/minutemediaBidAdapter.js +1 -1
  72. package/dist/minutemediaplusBidAdapter.js +1 -1
  73. package/dist/nativoBidAdapter.js +1 -1
  74. package/dist/neuwoRtdProvider.js +1 -1
  75. package/dist/nexx360BidAdapter.js +1 -1
  76. package/dist/not-for-prod/prebid.js +132 -131
  77. package/dist/oguryBidAdapter.js +1 -1
  78. package/dist/onetagBidAdapter.js +1 -1
  79. package/dist/ooloAnalyticsAdapter.js +1 -1
  80. package/dist/optidigitalBidAdapter.js +1 -1
  81. package/dist/ortbConverter.js +1 -1
  82. package/dist/outbrainBidAdapter.js +1 -1
  83. package/dist/pairIdSystem.js +1 -0
  84. package/dist/parrableIdSystem.js +1 -1
  85. package/dist/pixfutureBidAdapter.js +1 -1
  86. package/dist/prebid-core.js +1 -1
  87. package/dist/publinkIdSystem.js +1 -1
  88. package/dist/pubmaticBidAdapter.js +1 -1
  89. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  90. package/dist/pxyzBidAdapter.js +1 -1
  91. package/dist/quantcastBidAdapter.js +1 -1
  92. package/dist/readpeakBidAdapter.js +1 -1
  93. package/dist/relaidoBidAdapter.js +1 -1
  94. package/dist/rhythmoneBidAdapter.js +1 -1
  95. package/dist/riseBidAdapter.js +1 -1
  96. package/dist/rubiconAnalyticsAdapter.js +1 -1
  97. package/dist/rubiconBidAdapter.js +1 -1
  98. package/dist/seedingAllianceBidAdapter.js +1 -1
  99. package/dist/seedtagBidAdapter.js +1 -1
  100. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  101. package/dist/sharethroughBidAdapter.js +1 -1
  102. package/dist/shinezBidAdapter.js +1 -1
  103. package/dist/smaatoBidAdapter.js +1 -1
  104. package/dist/smartadserverBidAdapter.js +1 -1
  105. package/dist/smartxBidAdapter.js +1 -1
  106. package/dist/smilewantedBidAdapter.js +1 -1
  107. package/dist/sonobiBidAdapter.js +1 -1
  108. package/dist/sovrnAnalyticsAdapter.js +1 -1
  109. package/dist/sovrnBidAdapter.js +1 -1
  110. package/dist/sspBCBidAdapter.js +1 -1
  111. package/dist/stvBidAdapter.js +1 -1
  112. package/dist/sublimeBidAdapter.js +1 -1
  113. package/dist/synacormediaBidAdapter.js +1 -1
  114. package/dist/targetVideoBidAdapter.js +1 -1
  115. package/dist/teadsBidAdapter.js +1 -1
  116. package/dist/trionBidAdapter.js +1 -1
  117. package/dist/tripleliftBidAdapter.js +1 -1
  118. package/dist/ttdBidAdapter.js +1 -1
  119. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  120. package/dist/uid2IdSystem.js +1 -1
  121. package/dist/underdogmediaBidAdapter.js +1 -1
  122. package/dist/undertoneBidAdapter.js +1 -1
  123. package/dist/userId.js +1 -1
  124. package/dist/vidazooBidAdapter.js +1 -1
  125. package/dist/videobyteBidAdapter.js +1 -1
  126. package/dist/vidoomyBidAdapter.js +1 -1
  127. package/dist/visxBidAdapter.js +1 -1
  128. package/dist/vuukleBidAdapter.js +1 -1
  129. package/dist/widespaceBidAdapter.js +1 -1
  130. package/dist/winrBidAdapter.js +1 -1
  131. package/dist/yahoosspBidAdapter.js +1 -1
  132. package/dist/yieldmoBidAdapter.js +1 -1
  133. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  134. package/integrationExamples/gpt/fledge_example.html +103 -0
  135. package/integrationExamples/gpt/prebidServer_fledge_example.html +111 -0
  136. package/libraries/ortbConverter/processors/video.js +1 -0
  137. package/modules/admaticBidAdapter.js +7 -2
  138. package/modules/adnuntiusBidAdapter.js +3 -1
  139. package/modules/appnexusBidAdapter.js +108 -102
  140. package/modules/bidwatchAnalyticsAdapter.js +2 -0
  141. package/modules/conversantBidAdapter.js +3 -0
  142. package/modules/criteoBidAdapter.js +5 -1
  143. package/modules/eskimiBidAdapter.js +72 -0
  144. package/modules/eskimiBidAdapter.md +34 -0
  145. package/modules/gridBidAdapter.js +42 -19
  146. package/modules/ixBidAdapter.js +30 -0
  147. package/modules/kargoBidAdapter.js +473 -246
  148. package/modules/kueezRtbBidAdapter.js +16 -4
  149. package/modules/mediasquareBidAdapter.js +2 -1
  150. package/modules/minutemediaplusBidAdapter.js +16 -4
  151. package/modules/nativoBidAdapter.js +110 -21
  152. package/modules/neuwoRtdProvider.js +0 -2
  153. package/modules/pairIdSystem.js +79 -0
  154. package/modules/pubmaticBidAdapter.js +12 -9
  155. package/modules/userId/eids.js +6 -0
  156. package/modules/vidoomyBidAdapter.js +11 -3
  157. package/modules/yieldmoBidAdapter.js +15 -5
  158. package/package.json +1 -1
  159. package/src/config.js +78 -127
  160. package/test/spec/modules/1plusXRtdProvider_spec.js +8 -7
  161. package/test/spec/modules/adagioBidAdapter_spec.js +0 -25
  162. package/test/spec/modules/admaticBidAdapter_spec.js +1 -1
  163. package/test/spec/modules/adnuntiusBidAdapter_spec.js +2 -1
  164. package/test/spec/modules/appnexusBidAdapter_spec.js +464 -448
  165. package/test/spec/modules/axonixBidAdapter_spec.js +0 -27
  166. package/test/spec/modules/big-richmediaBidAdapter_spec.js +68 -64
  167. package/test/spec/modules/conversantBidAdapter_spec.js +1 -0
  168. package/test/spec/modules/criteoBidAdapter_spec.js +33 -1
  169. package/test/spec/modules/eskimiBidAdapter_spec.js +155 -0
  170. package/test/spec/modules/gridBidAdapter_spec.js +8 -0
  171. package/test/spec/modules/ixBidAdapter_spec.js +57 -0
  172. package/test/spec/modules/kargoBidAdapter_spec.js +297 -140
  173. package/test/spec/modules/kueezRtbBidAdapter_spec.js +22 -2
  174. package/test/spec/modules/minutemediaplusBidAdapter_spec.js +22 -2
  175. package/test/spec/modules/nativoBidAdapter_spec.js +101 -0
  176. package/test/spec/modules/neuwoRtdProvider_spec.js +0 -1
  177. package/test/spec/modules/ooloAnalyticsAdapter_spec.js +1 -1
  178. package/test/spec/modules/pairIdSystem_spec.js +68 -0
  179. package/test/spec/modules/pubCommonId_spec.js +0 -17
  180. package/test/spec/modules/pubmaticBidAdapter_spec.js +868 -867
  181. package/test/spec/modules/realvuAnalyticsAdapter_spec.js +0 -5
  182. package/test/spec/modules/vidoomyBidAdapter_spec.js +23 -0
  183. package/test/spec/modules/yieldmoBidAdapter_spec.js +19 -1
  184. package/test/spec/unit/pbjs_api_spec.js +19 -3
  185. package/test/test_index.js +13 -3
  186. package/dist/gridNMBidAdapter.js +0 -1
  187. package/modules/gridNMBidAdapter.js +0 -422
  188. package/modules/gridNMBidAdapter.md +0 -39
  189. package/test/spec/modules/gridNMBidAdapter_spec.js +0 -636
@@ -333,14 +333,16 @@ export const spec = {
333
333
  payload.referrer_detection = refererinfo;
334
334
  }
335
335
 
336
- const hasAdPodBid = find(bidRequests, hasAdPod);
337
- if (hasAdPodBid) {
338
- bidRequests.filter(hasAdPod).forEach(adPodBid => {
339
- const adPodTags = createAdPodRequest(tags, adPodBid);
340
- // don't need the original adpod placement because it's in adPodTags
341
- const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
342
- payload.tags = [...nonPodTags, ...adPodTags];
343
- });
336
+ if (FEATURES.VIDEO) {
337
+ const hasAdPodBid = find(bidRequests, hasAdPod);
338
+ if (hasAdPodBid) {
339
+ bidRequests.filter(hasAdPod).forEach(adPodBid => {
340
+ const adPodTags = createAdPodRequest(tags, adPodBid);
341
+ // don't need the original adpod placement because it's in adPodTags
342
+ const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
343
+ payload.tags = [...nonPodTags, ...adPodTags];
344
+ });
345
+ }
344
346
  }
345
347
 
346
348
  if (bidRequests[0].userId) {
@@ -653,7 +655,7 @@ function newBid(serverBid, rtbBid, bidderRequest) {
653
655
  bid.meta = Object.assign({}, bid.meta, { brandId: rtbBid.brand_id });
654
656
  }
655
657
 
656
- if (rtbBid.rtb.video) {
658
+ if (FEATURES.VIDEO && rtbBid.rtb.video) {
657
659
  // shared video properties used for all 3 contexts
658
660
  Object.assign(bid, {
659
661
  width: rtbBid.rtb.video.player_width,
@@ -865,107 +867,111 @@ function bidToTag(bid) {
865
867
  }
866
868
  }
867
869
 
868
- const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
869
- const context = deepAccess(bid, 'mediaTypes.video.context');
870
-
871
- if (videoMediaType && context === 'adpod') {
872
- tag.hb_source = 7;
873
- } else {
874
- tag.hb_source = 1;
875
- }
876
- if (bid.mediaType === VIDEO || videoMediaType) {
877
- tag.ad_types.push(VIDEO);
878
- }
879
-
880
- // instream gets vastUrl, outstream gets vastXml
881
- if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
882
- tag.require_asset_url = true;
883
- }
870
+ if (FEATURES.VIDEO) {
871
+ const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
872
+ const context = deepAccess(bid, 'mediaTypes.video.context');
884
873
 
885
- if (bid.params.video) {
886
- tag.video = {};
887
- // place any valid video params on the tag
888
- Object.keys(bid.params.video)
889
- .filter(param => includes(VIDEO_TARGETING, param))
890
- .forEach(param => {
891
- switch (param) {
892
- case 'context':
893
- case 'playback_method':
894
- let type = bid.params.video[param];
895
- type = (isArray(type)) ? type[0] : type;
896
- tag.video[param] = VIDEO_MAPPING[param][type];
897
- break;
898
- // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
899
- case 'frameworks':
900
- break;
901
- default:
902
- tag.video[param] = bid.params.video[param];
903
- }
904
- });
874
+ if (videoMediaType && context === 'adpod') {
875
+ tag.hb_source = 7;
876
+ } else {
877
+ tag.hb_source = 1;
878
+ }
879
+ if (bid.mediaType === VIDEO || videoMediaType) {
880
+ tag.ad_types.push(VIDEO);
881
+ }
905
882
 
906
- if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
907
- tag['video_frameworks'] = bid.params.video.frameworks;
883
+ // instream gets vastUrl, outstream gets vastXml
884
+ if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
885
+ tag.require_asset_url = true;
908
886
  }
909
- }
910
887
 
911
- // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
912
- if (videoMediaType) {
913
- tag.video = tag.video || {};
914
- Object.keys(videoMediaType)
915
- .filter(param => includes(VIDEO_RTB_TARGETING, param))
916
- .forEach(param => {
917
- switch (param) {
918
- case 'minduration':
919
- case 'maxduration':
920
- if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
921
- break;
922
- case 'skip':
923
- if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
924
- break;
925
- case 'skipafter':
926
- if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
927
- break;
928
- case 'playbackmethod':
929
- if (typeof tag.video['playback_method'] !== 'number') {
930
- let type = videoMediaType[param];
888
+ if (bid.params.video) {
889
+ tag.video = {};
890
+ // place any valid video params on the tag
891
+ Object.keys(bid.params.video)
892
+ .filter(param => includes(VIDEO_TARGETING, param))
893
+ .forEach(param => {
894
+ switch (param) {
895
+ case 'context':
896
+ case 'playback_method':
897
+ let type = bid.params.video[param];
931
898
  type = (isArray(type)) ? type[0] : type;
899
+ tag.video[param] = VIDEO_MAPPING[param][type];
900
+ break;
901
+ // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
902
+ case 'frameworks':
903
+ break;
904
+ default:
905
+ tag.video[param] = bid.params.video[param];
906
+ }
907
+ });
932
908
 
933
- // we only support iab's options 1-4 at this time.
934
- if (type >= 1 && type <= 4) {
935
- tag.video['playback_method'] = type;
936
- }
937
- }
938
- break;
939
- case 'api':
940
- if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
941
- // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
942
- let apiTmp = videoMediaType[param].map(val => {
943
- let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
944
-
945
- if (v >= 1 && v <= 5) {
946
- return v;
909
+ if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
910
+ tag['video_frameworks'] = bid.params.video.frameworks;
911
+ }
912
+ }
913
+
914
+ // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
915
+ if (videoMediaType) {
916
+ tag.video = tag.video || {};
917
+ Object.keys(videoMediaType)
918
+ .filter(param => includes(VIDEO_RTB_TARGETING, param))
919
+ .forEach(param => {
920
+ switch (param) {
921
+ case 'minduration':
922
+ case 'maxduration':
923
+ if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
924
+ break;
925
+ case 'skip':
926
+ if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
927
+ break;
928
+ case 'skipafter':
929
+ if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
930
+ break;
931
+ case 'playbackmethod':
932
+ if (typeof tag.video['playback_method'] !== 'number') {
933
+ let type = videoMediaType[param];
934
+ type = (isArray(type)) ? type[0] : type;
935
+
936
+ // we only support iab's options 1-4 at this time.
937
+ if (type >= 1 && type <= 4) {
938
+ tag.video['playback_method'] = type;
947
939
  }
948
- }).filter(v => v);
949
- tag['video_frameworks'] = apiTmp;
950
- }
951
- break;
952
-
953
- case 'startdelay':
954
- case 'placement':
955
- const contextKey = 'context';
956
- if (typeof tag.video[contextKey] !== 'number') {
957
- const placement = videoMediaType['placement'];
958
- const startdelay = videoMediaType['startdelay'];
959
- const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
960
- tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
961
- }
962
- break;
963
- }
964
- });
965
- }
940
+ }
941
+ break;
942
+ case 'api':
943
+ if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
944
+ // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
945
+ let apiTmp = videoMediaType[param].map(val => {
946
+ let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
947
+
948
+ if (v >= 1 && v <= 5) {
949
+ return v;
950
+ }
951
+ }).filter(v => v);
952
+ tag['video_frameworks'] = apiTmp;
953
+ }
954
+ break;
955
+
956
+ case 'startdelay':
957
+ case 'placement':
958
+ const contextKey = 'context';
959
+ if (typeof tag.video[contextKey] !== 'number') {
960
+ const placement = videoMediaType['placement'];
961
+ const startdelay = videoMediaType['startdelay'];
962
+ const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
963
+ tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
964
+ }
965
+ break;
966
+ }
967
+ });
968
+ }
966
969
 
967
- if (bid.renderer) {
968
- tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
970
+ if (bid.renderer) {
971
+ tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
972
+ }
973
+ } else {
974
+ tag.hb_source = 1;
969
975
  }
970
976
 
971
977
  if (bid.params.frameworks && isArray(bid.params.frameworks)) {
@@ -2,6 +2,7 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
2
2
  import adapterManager from '../src/adapterManager.js';
3
3
  import CONSTANTS from '../src/constants.json';
4
4
  import { ajax } from '../src/ajax.js';
5
+ import { getRefererInfo } from '../src/refererDetection.js';
5
6
 
6
7
  const analyticsType = 'endpoint';
7
8
  const url = 'URL_TO_SERVER_ENDPOINT';
@@ -145,6 +146,7 @@ function handleBidWon(args) {
145
146
  });
146
147
  }
147
148
  args['cpmIncrement'] = increment;
149
+ args['referer'] = encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation);
148
150
  if (typeof saveEvents.bidRequested == 'object' && saveEvents.bidRequested.length > 0 && saveEvents.bidRequested[0].gdprConsent) { args.gdpr = saveEvents.bidRequested[0].gdprConsent; }
149
151
  ajax(endpoint + '.bidwatch.io/analytics/bid_won', null, JSON.stringify(args), {method: 'POST', withCredentials: true});
150
152
  }
@@ -124,6 +124,9 @@ export const spec = {
124
124
  const payload = {
125
125
  id: requestId,
126
126
  imp: conversantImps,
127
+ source: {
128
+ tid: requestId
129
+ },
127
130
  site: {
128
131
  id: siteId,
129
132
  mobile: document.querySelector('meta[name="viewport"][content*="width=device-width"]') !== null ? 1 : 0,
@@ -223,7 +223,7 @@ export const spec = {
223
223
  creativeId: slot.creativecode,
224
224
  width: slot.width,
225
225
  height: slot.height,
226
- dealId: slot.dealCode,
226
+ dealId: slot.deal,
227
227
  };
228
228
  if (body.ext?.paf?.transmission && slot.ext?.paf?.content_id) {
229
229
  const pafResponseMeta = {
@@ -514,6 +514,10 @@ function buildCdbRequest(context, bidRequests, bidderRequest) {
514
514
  if (bidderRequest && bidderRequest.uspConsent) {
515
515
  request.user.uspIab = bidderRequest.uspConsent;
516
516
  }
517
+ if (bidderRequest && bidderRequest.ortb2?.device?.sua) {
518
+ request.user.ext = request.user.ext || {};
519
+ request.user.ext.sua = bidderRequest.ortb2?.device?.sua || {};
520
+ }
517
521
  return request;
518
522
  }
519
523
 
@@ -0,0 +1,72 @@
1
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
2
+ import {BANNER} from '../src/mediaTypes.js';
3
+ import * as utils from '../src/utils.js';
4
+ import {ortbConverter} from '../libraries/ortbConverter/converter.js'
5
+
6
+ const BIDDER_CODE = 'eskimi';
7
+ // const ENDPOINT = 'https://hb.eskimi.com/bids'
8
+ const ENDPOINT = 'https://sspback.eskimi.com/bid-request'
9
+
10
+ const DEFAULT_BID_TTL = 30;
11
+ const DEFAULT_CURRENCY = 'USD';
12
+ const DEFAULT_NET_REVENUE = true;
13
+ const GVLID = 814;
14
+
15
+ export const spec = {
16
+ code: BIDDER_CODE,
17
+ gvlid: GVLID,
18
+ supportedMediaTypes: [BANNER],
19
+
20
+ isBidRequestValid: function (bid) {
21
+ return !!bid.params.placementId;
22
+ },
23
+
24
+ buildRequests(bidRequests, bidderRequest) {
25
+ const data = converter.toORTB({bidRequests, bidderRequest})
26
+
27
+ let bid = bidRequests.find((b) => b.params.placementId)
28
+ if (!data.site) data.site = {}
29
+ data.site.ext = {placementId: bid.params.placementId}
30
+
31
+ if (bidderRequest.gdprConsent) {
32
+ if (!data.user) data.user = {};
33
+ if (!data.user.ext) data.user.ext = {};
34
+ if (!data.regs) data.regs = {};
35
+ if (!data.regs.ext) data.regs.ext = {};
36
+ data.user.ext.consent = bidderRequest.gdprConsent.consentString;
37
+ data.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
38
+ }
39
+
40
+ return [{
41
+ method: 'POST',
42
+ url: ENDPOINT,
43
+ data,
44
+ options: {contentType: 'application/json;charset=UTF-8', withCredentials: false}
45
+ }]
46
+ },
47
+
48
+ interpretResponse(response, request) {
49
+ return converter.fromORTB({response: response.body, request: request.data}).bids;
50
+ },
51
+
52
+ /**
53
+ * Register bidder specific code, which will execute if a bid from this bidder won the auction
54
+ * @param {Bid} bid The bid that won the auction
55
+ */
56
+ onBidWon: function (bid) {
57
+ if (bid.burl) {
58
+ utils.triggerPixel(bid.burl);
59
+ }
60
+ }
61
+ }
62
+
63
+ const converter = ortbConverter({
64
+ context: {
65
+ netRevenue: DEFAULT_NET_REVENUE,
66
+ ttl: DEFAULT_BID_TTL,
67
+ currency: DEFAULT_CURRENCY,
68
+ mediaType: BANNER // TODO: support more types, we should set mtype on the winning bid
69
+ }
70
+ });
71
+
72
+ registerBidder(spec);
@@ -0,0 +1,34 @@
1
+ # Overview
2
+
3
+ Module Name: ESKIMI Bidder Adapter
4
+ Module Type: Bidder Adapter
5
+ Maintainer: tech@eskimi.com
6
+
7
+ # Description
8
+
9
+ An adapter to get a bid from Eskimi DSP.
10
+
11
+ # Test Parameters
12
+ ```javascript
13
+ var adUnits = [{
14
+ code: 'div-gpt-ad-1460505748561-0',
15
+ mediaTypes: {
16
+ banner: {
17
+ sizes: [[300, 250], [300, 600]]
18
+ }
19
+ },
20
+
21
+ bids: [{
22
+ bidder: 'eskimi',
23
+ params: {
24
+ placementId: 612
25
+ }
26
+ }]
27
+
28
+ }];
29
+ ```
30
+
31
+ Where:
32
+
33
+ * placementId - Placement ID of the ad unit (required)
34
+
@@ -6,7 +6,10 @@ import {
6
6
  generateUUID,
7
7
  mergeDeep,
8
8
  logWarn,
9
- parseUrl, isArray, isNumber
9
+ parseUrl,
10
+ isArray,
11
+ isNumber,
12
+ isStr
10
13
  } from '../src/utils.js';
11
14
  import { registerBidder } from '../src/adapters/bidderFactory.js';
12
15
  import { Renderer } from '../src/Renderer.js';
@@ -52,7 +55,12 @@ const ALIAS_CONFIG = {
52
55
  bidResponseExternal: {
53
56
  netRevenue: false
54
57
  }
55
- }
58
+ },
59
+ 'gridNM': {
60
+ defaultParams: {
61
+ multiRequest: true
62
+ }
63
+ },
56
64
  };
57
65
 
58
66
  let hasSynced = false;
@@ -60,7 +68,7 @@ let hasSynced = false;
60
68
  export const spec = {
61
69
  code: BIDDER_CODE,
62
70
  gvlid: GVLID,
63
- aliases: ['playwire', 'adlivetech', { code: 'trustx', skipPbsAliasing: true }],
71
+ aliases: ['playwire', 'adlivetech', 'gridNM', { code: 'trustx', skipPbsAliasing: true }],
64
72
  supportedMediaTypes: [ BANNER, VIDEO ],
65
73
  /**
66
74
  * Determines whether or not the given bid request is valid.
@@ -126,8 +134,9 @@ export const spec = {
126
134
  if (!endpoint) {
127
135
  endpoint = ALIAS_CONFIG[bid.bidder] && ALIAS_CONFIG[bid.bidder].endpoint;
128
136
  }
129
- const { params: { uid, keywords, forceBidder, multiRequest }, mediaTypes, bidId, adUnitCode, rtd, ortb2Imp } = bid;
130
- const { secid, pubid, source, content: bidParamsContent } = bid.params;
137
+ const { params, mediaTypes, bidId, adUnitCode, rtd, ortb2Imp } = bid;
138
+ const { defaultParams } = ALIAS_CONFIG[bid.bidder] || {};
139
+ const { secid, pubid, source, uid, keywords, forceBidder, multiRequest, content: bidParamsContent, video: videoParams } = { ...defaultParams, ...params };
131
140
  const bidFloor = _getFloor(mediaTypes || {}, bid);
132
141
  const jwTargeting = rtd && rtd.jwplayer && rtd.jwplayer.targeting;
133
142
  if (jwTargeting && !content && jwTargeting.content) {
@@ -178,7 +187,7 @@ export const spec = {
178
187
  }
179
188
  }
180
189
  if (mediaTypes && mediaTypes[VIDEO]) {
181
- const video = createVideoRequest(bid, mediaTypes[VIDEO]);
190
+ const video = createVideoRequest(videoParams, mediaTypes[VIDEO], bid.sizes);
182
191
  if (video) {
183
192
  impObj.video = video;
184
193
  }
@@ -588,27 +597,41 @@ function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst, bid
588
597
  }
589
598
  }
590
599
 
591
- function createVideoRequest(bid, mediaType) {
592
- const { playerSize, mimes, durationRangeSec, protocols } = mediaType;
593
- const size = (playerSize || bid.sizes || [])[0];
594
- if (!size) return;
600
+ function createVideoRequest(videoParams, mediaType, bidSizes) {
601
+ const { mind, maxd, size, playerSize, protocols, durationRangeSec = [], ...videoData } = { ...mediaType, ...videoParams };
602
+ if (size && isStr(size)) {
603
+ const sizeArray = size.split('x');
604
+ if (sizeArray.length === 2 && parseInt(sizeArray[0]) && parseInt(sizeArray[1])) {
605
+ videoData.w = parseInt(sizeArray[0]);
606
+ videoData.h = parseInt(sizeArray[1]);
607
+ }
608
+ }
609
+ if (!videoData.w || !videoData.h) {
610
+ const pSizesString = (playerSize || bidSizes || []).toString();
611
+ const pSizeString = (pSizesString.match(/^\d+,\d+/) || [])[0];
612
+ const pSize = pSizeString && pSizeString.split(',').map((d) => parseInt(d));
613
+ if (pSize && pSize.length === 2) {
614
+ Object.assign(videoData, parseGPTSingleSizeArrayToRtbSize(pSize));
615
+ }
616
+ }
595
617
 
596
- let result = parseGPTSingleSizeArrayToRtbSize(size);
618
+ if (!videoData.w || !videoData.h) return;
597
619
 
598
- if (mimes) {
599
- result.mimes = mimes;
600
- }
620
+ const minDur = mind || durationRangeSec[0] || videoData.minduration;
621
+ const maxDur = maxd || durationRangeSec[1] || videoData.maxduration;
601
622
 
602
- if (durationRangeSec && durationRangeSec.length === 2) {
603
- result.minduration = durationRangeSec[0];
604
- result.maxduration = durationRangeSec[1];
623
+ if (minDur) {
624
+ videoData.minduration = minDur;
625
+ }
626
+ if (maxDur) {
627
+ videoData.maxduration = maxDur;
605
628
  }
606
629
 
607
630
  if (protocols && protocols.length) {
608
- result.protocols = protocols;
631
+ videoData.protocols = protocols;
609
632
  }
610
633
 
611
- return result;
634
+ return videoData;
612
635
  }
613
636
 
614
637
  function createBannerRequest(bid, mediaType) {
@@ -195,6 +195,9 @@ function bidToVideoImp(bid) {
195
195
  // populate imp level transactionId
196
196
  imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
197
197
 
198
+ // AdUnit-Specific First Party Data
199
+ addAdUnitFPD(imp, bid)
200
+
198
201
  // copy all video properties to imp object
199
202
  for (const adUnitProperty in videoAdUnitRef) {
200
203
  if (VIDEO_PARAMS_ALLOW_LIST.indexOf(adUnitProperty) !== -1 && !imp.video.hasOwnProperty(adUnitProperty)) {
@@ -268,6 +271,9 @@ function bidToNativeImp(bid) {
268
271
  // populate imp level transactionId
269
272
  imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
270
273
 
274
+ // AdUnit-Specific First Party Data
275
+ addAdUnitFPD(imp, bid)
276
+
271
277
  _applyFloor(bid, imp, NATIVE);
272
278
 
273
279
  return imp;
@@ -956,6 +962,11 @@ function addImpressions(impressions, transactionIds, r, adUnitIndex) {
956
962
  _bannerImpression.bidfloorcur = impressionObjects[0].bidfloorcur;
957
963
  }
958
964
 
965
+ const adUnitFPD = impressions[transactionIds[adUnitIndex]].adUnitFPD
966
+ if (adUnitFPD) {
967
+ _bannerImpression.ext.data = adUnitFPD;
968
+ }
969
+
959
970
  r.imp.push(_bannerImpression);
960
971
  } else {
961
972
  // set imp.ext.gpid to resolved gpid for each imp
@@ -1011,6 +1022,19 @@ function addFPD(bidderRequest, r, fpd, site, user) {
1011
1022
  return r;
1012
1023
  }
1013
1024
 
1025
+ /**
1026
+ * Adds First-Party Data (FPD) from the bid object to the imp object.
1027
+ *
1028
+ * @param {Object} imp - The imp object, representing an impression in the OpenRTB format.
1029
+ * @param {Object} bid - The bid object, containing information about the bid request.
1030
+ */
1031
+ function addAdUnitFPD(imp, bid) {
1032
+ const adUnitFPD = deepAccess(bid, 'ortb2Imp.ext.data');
1033
+ if (adUnitFPD) {
1034
+ deepSetValue(imp, 'ext.data', adUnitFPD)
1035
+ }
1036
+ }
1037
+
1014
1038
  /**
1015
1039
  * addIdentifiersInfo adds indentifier info to ixDaig.
1016
1040
  *
@@ -1196,6 +1220,12 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
1196
1220
  bannerImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
1197
1221
  bannerImps[validBidRequest.transactionId].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos');
1198
1222
 
1223
+ // AdUnit-Specific First Party Data
1224
+ const adUnitFPD = deepAccess(validBidRequest, 'ortb2Imp.ext.data');
1225
+ if (adUnitFPD) {
1226
+ bannerImps[validBidRequest.transactionId].adUnitFPD = adUnitFPD;
1227
+ }
1228
+
1199
1229
  const sid = deepAccess(validBidRequest, 'params.id');
1200
1230
  if (sid && (typeof sid === 'string' || typeof sid === 'number')) {
1201
1231
  bannerImps[validBidRequest.transactionId].sid = String(sid);