prebid.js 6.0.0 → 6.4.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 (201) hide show
  1. package/.babelrc.js +1 -7
  2. package/.circleci/config.yml +1 -1
  3. package/README.md +1 -1
  4. package/browsers.json +13 -29
  5. package/gulpfile.js +88 -82
  6. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  7. package/karma.conf.maker.js +2 -2
  8. package/modules/33acrossBidAdapter.js +189 -102
  9. package/modules/adagioBidAdapter.js +1 -1
  10. package/modules/addefendBidAdapter.js +1 -0
  11. package/modules/adheseBidAdapter.js +7 -2
  12. package/modules/adkernelBidAdapter.js +147 -61
  13. package/modules/adlivetechBidAdapter.md +61 -0
  14. package/modules/adlooxAdServerVideo.js +2 -2
  15. package/modules/adlooxAnalyticsAdapter.js +4 -4
  16. package/modules/admanBidAdapter.js +1 -0
  17. package/modules/admixerBidAdapter.js +3 -2
  18. package/modules/adnuntiusBidAdapter.js +5 -2
  19. package/modules/adomikAnalyticsAdapter.js +16 -4
  20. package/modules/adplusBidAdapter.js +203 -0
  21. package/modules/adplusBidAdapter.md +39 -0
  22. package/modules/adxcgBidAdapter.js +311 -359
  23. package/modules/adxcgBidAdapter.md +22 -21
  24. package/modules/adyoulikeBidAdapter.js +7 -2
  25. package/modules/aniviewBidAdapter.js +1 -1
  26. package/modules/appnexusBidAdapter.js +23 -3
  27. package/modules/beachfrontBidAdapter.js +14 -17
  28. package/modules/beopBidAdapter.js +6 -4
  29. package/modules/bidViewability.js +3 -3
  30. package/modules/bidViewabilityIO.js +3 -3
  31. package/modules/codefuelBidAdapter.js +1 -3
  32. package/modules/codefuelBidAdapter.md +3 -3
  33. package/modules/colossussspBidAdapter.js +7 -0
  34. package/modules/compassBidAdapter.js +201 -0
  35. package/modules/compassBidAdapter.md +79 -0
  36. package/modules/craftBidAdapter.js +5 -3
  37. package/modules/criteoBidAdapter.js +1 -1
  38. package/modules/currency.js +2 -2
  39. package/modules/cwireBidAdapter.js +3 -0
  40. package/modules/dailyhuntBidAdapter.js +435 -0
  41. package/modules/dailyhuntBidAdapter.md +4 -0
  42. package/modules/datablocksBidAdapter.js +3 -3
  43. package/modules/dchain.js +149 -0
  44. package/modules/dchain.md +45 -0
  45. package/modules/deepintentBidAdapter.js +1 -1
  46. package/modules/dspxBidAdapter.js +1 -1
  47. package/modules/emx_digitalBidAdapter.js +9 -1
  48. package/modules/engageyaBidAdapter.js +68 -54
  49. package/modules/feedadBidAdapter.js +2 -2
  50. package/modules/feedadBidAdapter.md +4 -2
  51. package/modules/freewheel-sspBidAdapter.js +6 -0
  52. package/modules/futureads.md +48 -0
  53. package/modules/glimpseBidAdapter.js +44 -16
  54. package/modules/goldbachBidAdapter.js +1176 -0
  55. package/modules/goldbachBidAdapter.md +151 -0
  56. package/modules/gptPreAuction.js +11 -5
  57. package/modules/gridBidAdapter.js +5 -4
  58. package/modules/gumgumBidAdapter.js +7 -3
  59. package/modules/id5IdSystem.md +6 -6
  60. package/modules/imRtdProvider.js +31 -0
  61. package/modules/improvedigitalBidAdapter.js +19 -3
  62. package/modules/instreamTracking.js +4 -4
  63. package/modules/intersectionRtdProvider.js +114 -0
  64. package/modules/invibesBidAdapter.js +64 -14
  65. package/modules/invibesBidAdapter.md +2 -1
  66. package/modules/ipromBidAdapter.js +79 -0
  67. package/modules/ixBidAdapter.js +185 -22
  68. package/modules/kinessoIdSystem.js +1 -1
  69. package/modules/limelightDigitalBidAdapter.js +2 -1
  70. package/modules/livewrappedBidAdapter.js +8 -2
  71. package/modules/lotamePanoramaIdSystem.js +80 -8
  72. package/modules/luponmediaBidAdapter.js +570 -0
  73. package/modules/mediasquareBidAdapter.js +1 -9
  74. package/modules/merkleIdSystem.js +5 -0
  75. package/modules/missenaBidAdapter.js +89 -0
  76. package/modules/nativoBidAdapter.js +27 -1
  77. package/modules/nextMillenniumBidAdapter.js +37 -7
  78. package/modules/oguryBidAdapter.js +2 -1
  79. package/modules/openxBidAdapter.js +6 -1
  80. package/modules/prebidServerBidAdapter/index.js +19 -15
  81. package/modules/pubgeniusBidAdapter.js +1 -1
  82. package/modules/pubmaticBidAdapter.js +5 -3
  83. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  84. package/modules/relaidoBidAdapter.js +86 -65
  85. package/modules/richaudienceBidAdapter.js +2 -3
  86. package/modules/rtdModule/index.js +48 -18
  87. package/modules/rubiconBidAdapter.js +31 -19
  88. package/modules/saambaaBidAdapter.js +420 -0
  89. package/modules/saambaaBidAdapter.md +65 -68
  90. package/modules/seedtagBidAdapter.js +6 -0
  91. package/modules/sharedIdSystem.js +27 -1
  92. package/modules/smaatoBidAdapter.js +9 -1
  93. package/modules/smartxBidAdapter.js +17 -1
  94. package/modules/sspBCBidAdapter.js +34 -3
  95. package/modules/tappxBidAdapter.js +3 -1
  96. package/modules/targetVideoBidAdapter.js +187 -0
  97. package/modules/targetVideoBidAdapter.md +34 -0
  98. package/modules/telariaBidAdapter.js +2 -2
  99. package/modules/trustxBidAdapter.js +18 -17
  100. package/modules/undertoneBidAdapter.js +8 -1
  101. package/modules/userId/index.js +27 -2
  102. package/modules/ventes.md +71 -0
  103. package/modules/ventesBidAdapter.js +104 -64
  104. package/modules/ventesBidAdapter.md +0 -1
  105. package/modules/vidoomyBidAdapter.js +65 -108
  106. package/modules/visxBidAdapter.js +20 -3
  107. package/modules/visxBidAdapter.md +4 -6
  108. package/modules/weboramaRtdProvider.js +288 -73
  109. package/modules/weboramaRtdProvider.md +27 -10
  110. package/modules/yahoosspBidAdapter.js +5 -1
  111. package/modules/yahoosspBidAdapter.md +1 -1
  112. package/modules/yieldlabBidAdapter.js +41 -10
  113. package/modules/yieldlabBidAdapter.md +91 -48
  114. package/modules/yieldoneBidAdapter.js +115 -11
  115. package/modules/zetaSspBidAdapter.md +33 -1
  116. package/modules/zeta_global_sspBidAdapter.js +22 -1
  117. package/package.json +6 -1
  118. package/plugins/pbjsGlobals.js +28 -1
  119. package/src/adapterManager.js +14 -8
  120. package/src/auction.js +5 -4
  121. package/src/prebid.js +1 -2
  122. package/src/targeting.js +24 -3
  123. package/src/utils.js +41 -7
  124. package/test/helpers/prebidGlobal.js +1 -0
  125. package/test/spec/integration/faker/googletag.js +6 -0
  126. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  127. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  128. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  129. package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
  130. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
  131. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  132. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  133. package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
  134. package/test/spec/modules/appnexusBidAdapter_spec.js +63 -1
  135. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  136. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  137. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  138. package/test/spec/modules/bidViewability_spec.js +4 -4
  139. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  140. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  141. package/test/spec/modules/compassBidAdapter_spec.js +397 -0
  142. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  143. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  144. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  145. package/test/spec/modules/dchain_spec.js +329 -0
  146. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  147. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  148. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  149. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  150. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  151. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  152. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  153. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  154. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  155. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  156. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -1
  157. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  158. package/test/spec/modules/invibesBidAdapter_spec.js +148 -4
  159. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  160. package/test/spec/modules/ixBidAdapter_spec.js +293 -2
  161. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  162. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
  163. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  164. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  165. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  166. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  167. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  168. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  169. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  170. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  171. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  172. package/test/spec/modules/openxBidAdapter_spec.js +5 -0
  173. package/test/spec/modules/prebidServerBidAdapter_spec.js +62 -2
  174. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  175. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  176. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  177. package/test/spec/modules/realTimeDataModule_spec.js +135 -49
  178. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  179. package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
  180. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  181. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  182. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  183. package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
  184. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  185. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  186. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  187. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  188. package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
  189. package/test/spec/modules/userId_spec.js +51 -0
  190. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  191. package/test/spec/modules/visxBidAdapter_spec.js +121 -5
  192. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  193. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  194. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  195. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  196. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  197. package/test/spec/unit/core/adapterManager_spec.js +24 -6
  198. package/test/spec/unit/core/targeting_spec.js +116 -0
  199. package/test/spec/utils_spec.js +38 -0
  200. package/test/test_deps.js +3 -0
  201. package/test/test_index.js +1 -3
@@ -1,4 +1,4 @@
1
- import { mergeDeep, _each, logError, deepAccess, deepSetValue, isStr, isNumber, logWarn, convertTypes, isArray, parseSizesInput, logMessage } from '../src/utils.js';
1
+ import { mergeDeep, _each, logError, deepAccess, deepSetValue, isStr, isNumber, logWarn, convertTypes, isArray, parseSizesInput, logMessage, formatQS } 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';
@@ -765,21 +765,23 @@ export const spec = {
765
765
  getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
766
766
  if (!hasSynced && syncOptions.iframeEnabled) {
767
767
  // data is only assigned if params are available to pass to syncEndpoint
768
- let params = '';
768
+ let params = {};
769
769
 
770
- if (gdprConsent && typeof gdprConsent.consentString === 'string') {
771
- // add 'gdpr' only if 'gdprApplies' is defined
770
+ if (gdprConsent) {
772
771
  if (typeof gdprConsent.gdprApplies === 'boolean') {
773
- params += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
774
- } else {
775
- params += `?gdpr_consent=${gdprConsent.consentString}`;
772
+ params['gdpr'] = Number(gdprConsent.gdprApplies);
773
+ }
774
+ if (typeof gdprConsent.consentString === 'string') {
775
+ params['gdpr_consent'] = gdprConsent.consentString;
776
776
  }
777
777
  }
778
778
 
779
779
  if (uspConsent) {
780
- params += `${params ? '&' : '?'}us_privacy=${encodeURIComponent(uspConsent)}`;
780
+ params['us_privacy'] = encodeURIComponent(uspConsent);
781
781
  }
782
782
 
783
+ params = Object.keys(params).length ? `?${formatQS(params)}` : '';
784
+
783
785
  hasSynced = true;
784
786
  return {
785
787
  type: 'iframe',
@@ -992,6 +994,8 @@ function applyFPD(bidRequest, mediaType, data) {
992
994
 
993
995
  let fpd = mergeDeep({}, config.getConfig('ortb2') || {}, BID_FPD);
994
996
  let impData = deepAccess(bidRequest.ortb2Imp, 'ext.data') || {};
997
+
998
+ const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid');
995
999
  const SEGTAX = {user: [4], site: [1, 2, 5, 6]};
996
1000
  const MAP = {user: 'tg_v.', site: 'tg_i.', adserver: 'tg_i.dfp_ad_unit_code', pbadslot: 'tg_i.pbadslot', keywords: 'kw'};
997
1001
  const validate = function(prop, key, parentName) {
@@ -1020,16 +1024,6 @@ function applyFPD(bidRequest, mediaType, data) {
1020
1024
  data[loc] = (data[loc]) ? data[loc].concat(',', val) : val;
1021
1025
  }
1022
1026
 
1023
- Object.keys(impData).forEach((key) => {
1024
- if (key === 'adserver') {
1025
- ['name', 'adslot'].forEach(prop => {
1026
- if (impData[key][prop]) impData[key][prop] = impData[key][prop].toString().replace(/^\/+/, '');
1027
- });
1028
- } else if (key === 'pbadslot') {
1029
- impData[key] = impData[key].toString().replace(/^\/+/, '');
1030
- }
1031
- });
1032
-
1033
1027
  if (mediaType === BANNER) {
1034
1028
  ['site', 'user'].forEach(name => {
1035
1029
  Object.keys(fpd[name]).forEach((key) => {
@@ -1045,12 +1039,30 @@ function applyFPD(bidRequest, mediaType, data) {
1045
1039
  });
1046
1040
  });
1047
1041
  Object.keys(impData).forEach((key) => {
1048
- (key === 'adserver') ? addBannerData(impData[key].adslot, name, key) : addBannerData(impData[key], 'site', key);
1042
+ if (key !== 'adserver') {
1043
+ addBannerData(impData[key], 'site', key);
1044
+ } else if (impData[key].name === 'gam') {
1045
+ addBannerData(impData[key].adslot, name, key)
1046
+ }
1049
1047
  });
1048
+
1049
+ // add in gpid
1050
+ if (gpid) {
1051
+ data['p_gpid'] = gpid;
1052
+ }
1053
+
1054
+ // only send one of pbadslot or dfp adunit code (prefer pbadslot)
1055
+ if (data['tg_i.pbadslot']) {
1056
+ delete data['tg_i.dfp_ad_unit_code'];
1057
+ }
1050
1058
  } else {
1051
1059
  if (Object.keys(impData).length) {
1052
1060
  mergeDeep(data.imp[0].ext, {data: impData});
1053
1061
  }
1062
+ // add in gpid
1063
+ if (gpid) {
1064
+ data.imp[0].ext.gpid = gpid;
1065
+ }
1054
1066
 
1055
1067
  mergeDeep(data, fpd);
1056
1068
  }
@@ -0,0 +1,420 @@
1
+ import { deepAccess, isFn, generateUUID, parseUrl, isEmpty, parseSizesInput } from '../src/utils.js';
2
+ import { config } from '../src/config.js';
3
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
4
+ import { VIDEO, BANNER } from '../src/mediaTypes.js';
5
+ import find from 'core-js-pure/features/array/find.js';
6
+ import includes from 'core-js-pure/features/array/includes.js';
7
+
8
+ const ADAPTER_VERSION = '1.0';
9
+ const BIDDER_CODE = 'saambaa';
10
+
11
+ export const VIDEO_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid=';
12
+ export const BANNER_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid=';
13
+ export const OUTSTREAM_SRC = 'https://player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js';
14
+ export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip', 'playerSize', 'context'];
15
+ export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
16
+
17
+ let pubid = '';
18
+
19
+ export const spec = {
20
+ code: BIDDER_CODE,
21
+ supportedMediaTypes: [BANNER, VIDEO],
22
+
23
+ isBidRequestValid(bidRequest) {
24
+ if (typeof bidRequest != 'undefined') {
25
+ if (bidRequest.bidder !== BIDDER_CODE && typeof bidRequest.params === 'undefined') { return false; }
26
+ if (bidRequest === '' || bidRequest.params.placement === '' || bidRequest.params.pubid === '') { return false; }
27
+ return true;
28
+ } else { return false; }
29
+ },
30
+
31
+ buildRequests(bids, bidderRequest) {
32
+ let requests = [];
33
+ let videoBids = bids.filter(bid => isVideoBidValid(bid));
34
+ let bannerBids = bids.filter(bid => isBannerBidValid(bid));
35
+ videoBids.forEach(bid => {
36
+ pubid = getVideoBidParam(bid, 'pubid');
37
+ requests.push({
38
+ method: 'POST',
39
+ url: VIDEO_ENDPOINT + pubid,
40
+ data: createVideoRequestData(bid, bidderRequest),
41
+ bidRequest: bid
42
+ });
43
+ });
44
+
45
+ bannerBids.forEach(bid => {
46
+ pubid = getBannerBidParam(bid, 'pubid');
47
+
48
+ requests.push({
49
+ method: 'POST',
50
+ url: BANNER_ENDPOINT + pubid,
51
+ data: createBannerRequestData(bid, bidderRequest),
52
+ bidRequest: bid
53
+ });
54
+ });
55
+ return requests;
56
+ },
57
+
58
+ interpretResponse(serverResponse, {bidRequest}) {
59
+ let response = serverResponse.body;
60
+ if (response !== null && isEmpty(response) == false) {
61
+ if (isVideoBid(bidRequest)) {
62
+ let bidResponse = {
63
+ requestId: response.id,
64
+ bidderCode: BIDDER_CODE,
65
+ cpm: response.seatbid[0].bid[0].price,
66
+ width: response.seatbid[0].bid[0].w,
67
+ height: response.seatbid[0].bid[0].h,
68
+ ttl: response.seatbid[0].bid[0].ttl || 60,
69
+ creativeId: response.seatbid[0].bid[0].crid,
70
+ currency: response.cur,
71
+ meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain },
72
+ mediaType: VIDEO,
73
+ netRevenue: true
74
+ }
75
+
76
+ if (response.seatbid[0].bid[0].adm) {
77
+ bidResponse.vastXml = response.seatbid[0].bid[0].adm;
78
+ bidResponse.adResponse = {
79
+ content: response.seatbid[0].bid[0].adm
80
+ };
81
+ } else {
82
+ bidResponse.vastUrl = response.seatbid[0].bid[0].nurl;
83
+ }
84
+
85
+ return bidResponse;
86
+ } else {
87
+ return {
88
+ requestId: response.id,
89
+ bidderCode: BIDDER_CODE,
90
+ cpm: response.seatbid[0].bid[0].price,
91
+ width: response.seatbid[0].bid[0].w,
92
+ height: response.seatbid[0].bid[0].h,
93
+ ad: response.seatbid[0].bid[0].adm,
94
+ ttl: response.seatbid[0].bid[0].ttl || 60,
95
+ creativeId: response.seatbid[0].bid[0].crid,
96
+ currency: response.cur,
97
+ meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain },
98
+ mediaType: BANNER,
99
+ netRevenue: true
100
+ }
101
+ }
102
+ }
103
+ }
104
+ };
105
+
106
+ function isBannerBid(bid) {
107
+ return deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid);
108
+ }
109
+
110
+ function isVideoBid(bid) {
111
+ return deepAccess(bid, 'mediaTypes.video');
112
+ }
113
+
114
+ function getBannerBidFloor(bid) {
115
+ let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'banner', size: '*' }) : {};
116
+ return floorInfo.floor || getBannerBidParam(bid, 'bidfloor');
117
+ }
118
+
119
+ function getVideoBidFloor(bid) {
120
+ let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'video', size: '*' }) : {};
121
+ return floorInfo.floor || getVideoBidParam(bid, 'bidfloor');
122
+ }
123
+
124
+ function isVideoBidValid(bid) {
125
+ return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement');
126
+ }
127
+
128
+ function isBannerBidValid(bid) {
129
+ return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement');
130
+ }
131
+
132
+ function getVideoBidParam(bid, key) {
133
+ return deepAccess(bid, 'params.video.' + key) || deepAccess(bid, 'params.' + key);
134
+ }
135
+
136
+ function getBannerBidParam(bid, key) {
137
+ return deepAccess(bid, 'params.banner.' + key) || deepAccess(bid, 'params.' + key);
138
+ }
139
+
140
+ function isMobile() {
141
+ return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent);
142
+ }
143
+
144
+ function isConnectedTV() {
145
+ return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
146
+ }
147
+
148
+ function getDoNotTrack() {
149
+ return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes';
150
+ }
151
+
152
+ function findAndFillParam(o, key, value) {
153
+ try {
154
+ if (typeof value === 'function') {
155
+ o[key] = value();
156
+ } else {
157
+ o[key] = value;
158
+ }
159
+ } catch (ex) {}
160
+ }
161
+
162
+ function getOsVersion() {
163
+ let clientStrings = [
164
+ { s: 'Android', r: /Android/ },
165
+ { s: 'iOS', r: /(iPhone|iPad|iPod)/ },
166
+ { s: 'Mac OS X', r: /Mac OS X/ },
167
+ { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ },
168
+ { s: 'Linux', r: /(Linux|X11)/ },
169
+ { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ },
170
+ { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ },
171
+ { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ },
172
+ { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ },
173
+ { s: 'Windows Vista', r: /Windows NT 6.0/ },
174
+ { s: 'Windows Server 2003', r: /Windows NT 5.2/ },
175
+ { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ },
176
+ { s: 'UNIX', r: /UNIX/ },
177
+ { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ }
178
+ ];
179
+ let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent));
180
+ return cs ? cs.s : 'unknown';
181
+ }
182
+
183
+ function getFirstSize(sizes) {
184
+ return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined };
185
+ }
186
+
187
+ function parseSizes(sizes) {
188
+ return parseSizesInput(sizes).map(size => {
189
+ let [ width, height ] = size.split('x');
190
+ return {
191
+ w: parseInt(width, 10) || undefined,
192
+ h: parseInt(height, 10) || undefined
193
+ };
194
+ });
195
+ }
196
+
197
+ function getVideoSizes(bid) {
198
+ return parseSizes(deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes);
199
+ }
200
+
201
+ function getBannerSizes(bid) {
202
+ return parseSizes(deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes);
203
+ }
204
+
205
+ function getTopWindowReferrer() {
206
+ try {
207
+ return window.top.document.referrer;
208
+ } catch (e) {
209
+ return '';
210
+ }
211
+ }
212
+
213
+ function getVideoTargetingParams(bid) {
214
+ const result = {};
215
+ const excludeProps = ['playerSize', 'context', 'w', 'h'];
216
+ Object.keys(Object(bid.mediaTypes.video))
217
+ .filter(key => !includes(excludeProps, key))
218
+ .forEach(key => {
219
+ result[ key ] = bid.mediaTypes.video[ key ];
220
+ });
221
+ Object.keys(Object(bid.params.video))
222
+ .filter(key => includes(VIDEO_TARGETING, key))
223
+ .forEach(key => {
224
+ result[ key ] = bid.params.video[ key ];
225
+ });
226
+ return result;
227
+ }
228
+
229
+ function createVideoRequestData(bid, bidderRequest) {
230
+ let topLocation = getTopWindowLocation(bidderRequest);
231
+ let topReferrer = getTopWindowReferrer();
232
+
233
+ // if size is explicitly given via adapter params
234
+ let paramSize = getVideoBidParam(bid, 'size');
235
+ let sizes = [];
236
+ let coppa = config.getConfig('coppa');
237
+
238
+ if (typeof paramSize !== 'undefined' && paramSize != '') {
239
+ sizes = parseSizes(paramSize);
240
+ } else {
241
+ sizes = getVideoSizes(bid);
242
+ }
243
+ const firstSize = getFirstSize(sizes);
244
+ let floor = (getVideoBidFloor(bid) == null || typeof getVideoBidFloor(bid) == 'undefined') ? 0.5 : getVideoBidFloor(bid);
245
+ let video = getVideoTargetingParams(bid);
246
+ const o = {
247
+ 'device': {
248
+ 'langauge': (global.navigator.language).split('-')[0],
249
+ 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
250
+ 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
251
+ 'js': 1,
252
+ 'os': getOsVersion()
253
+ },
254
+ 'at': 2,
255
+ 'site': {},
256
+ 'tmax': 3000,
257
+ 'cur': ['USD'],
258
+ 'id': bid.bidId,
259
+ 'imp': [],
260
+ 'regs': {
261
+ 'ext': {
262
+ }
263
+ },
264
+ 'user': {
265
+ 'ext': {
266
+ }
267
+ }
268
+ };
269
+
270
+ o.site['page'] = topLocation.href;
271
+ o.site['domain'] = topLocation.hostname;
272
+ o.site['search'] = topLocation.search;
273
+ o.site['domain'] = topLocation.hostname;
274
+ o.site['ref'] = topReferrer;
275
+ o.site['mobile'] = isMobile() ? 1 : 0;
276
+ const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
277
+
278
+ o.device['dnt'] = getDoNotTrack() ? 1 : 0;
279
+
280
+ findAndFillParam(o.site, 'name', function() {
281
+ return global.top.document.title;
282
+ });
283
+
284
+ findAndFillParam(o.device, 'h', function() {
285
+ return global.screen.height;
286
+ });
287
+ findAndFillParam(o.device, 'w', function() {
288
+ return global.screen.width;
289
+ });
290
+
291
+ let placement = getVideoBidParam(bid, 'placement');
292
+
293
+ for (let j = 0; j < sizes.length; j++) {
294
+ o.imp.push({
295
+ 'id': '' + j,
296
+ 'displaymanager': '' + BIDDER_CODE,
297
+ 'displaymanagerver': '' + ADAPTER_VERSION,
298
+ 'tagId': placement,
299
+ 'bidfloor': floor,
300
+ 'bidfloorcur': 'USD',
301
+ 'secure': secure,
302
+ 'video': Object.assign({
303
+ 'id': generateUUID(),
304
+ 'pos': 0,
305
+ 'w': firstSize.w,
306
+ 'h': firstSize.h,
307
+ 'mimes': DEFAULT_MIMES
308
+ }, video)
309
+
310
+ });
311
+ }
312
+ if (coppa) {
313
+ o.regs.ext = {'coppa': 1};
314
+ }
315
+ if (bidderRequest && bidderRequest.gdprConsent) {
316
+ let { gdprApplies, consentString } = bidderRequest.gdprConsent;
317
+ o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
318
+ o.user.ext = {'consent': consentString};
319
+ }
320
+
321
+ return o;
322
+ }
323
+
324
+ function getTopWindowLocation(bidderRequest) {
325
+ let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
326
+ return parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true });
327
+ }
328
+
329
+ function createBannerRequestData(bid, bidderRequest) {
330
+ let topLocation = getTopWindowLocation(bidderRequest);
331
+ let topReferrer = getTopWindowReferrer();
332
+
333
+ // if size is explicitly given via adapter params
334
+
335
+ let paramSize = getBannerBidParam(bid, 'size');
336
+ let sizes = [];
337
+ let coppa = config.getConfig('coppa');
338
+ if (typeof paramSize !== 'undefined' && paramSize != '') {
339
+ sizes = parseSizes(paramSize);
340
+ } else {
341
+ sizes = getBannerSizes(bid);
342
+ }
343
+
344
+ let floor = (getBannerBidFloor(bid) == null || typeof getBannerBidFloor(bid) == 'undefined') ? 0.1 : getBannerBidFloor(bid);
345
+ const o = {
346
+ 'device': {
347
+ 'langauge': (global.navigator.language).split('-')[0],
348
+ 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
349
+ 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
350
+ 'js': 1
351
+ },
352
+ 'at': 2,
353
+ 'site': {},
354
+ 'tmax': 3000,
355
+ 'cur': ['USD'],
356
+ 'id': bid.bidId,
357
+ 'imp': [],
358
+ 'regs': {
359
+ 'ext': {
360
+ }
361
+ },
362
+ 'user': {
363
+ 'ext': {
364
+ }
365
+ }
366
+ };
367
+
368
+ o.site['page'] = topLocation.href;
369
+ o.site['domain'] = topLocation.hostname;
370
+ o.site['search'] = topLocation.search;
371
+ o.site['domain'] = topLocation.hostname;
372
+ o.site['ref'] = topReferrer;
373
+ o.site['mobile'] = isMobile() ? 1 : 0;
374
+ const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
375
+
376
+ o.device['dnt'] = getDoNotTrack() ? 1 : 0;
377
+
378
+ findAndFillParam(o.site, 'name', function() {
379
+ return global.top.document.title;
380
+ });
381
+
382
+ findAndFillParam(o.device, 'h', function() {
383
+ return global.screen.height;
384
+ });
385
+ findAndFillParam(o.device, 'w', function() {
386
+ return global.screen.width;
387
+ });
388
+
389
+ let placement = getBannerBidParam(bid, 'placement');
390
+ for (let j = 0; j < sizes.length; j++) {
391
+ let size = sizes[j];
392
+
393
+ o.imp.push({
394
+ 'id': '' + j,
395
+ 'displaymanager': '' + BIDDER_CODE,
396
+ 'displaymanagerver': '' + ADAPTER_VERSION,
397
+ 'tagId': placement,
398
+ 'bidfloor': floor,
399
+ 'bidfloorcur': 'USD',
400
+ 'secure': secure,
401
+ 'banner': {
402
+ 'id': generateUUID(),
403
+ 'pos': 0,
404
+ 'w': size['w'],
405
+ 'h': size['h']
406
+ }
407
+ });
408
+ }
409
+ if (coppa) {
410
+ o.regs.ext = {'coppa': 1};
411
+ }
412
+ if (bidderRequest && bidderRequest.gdprConsent) {
413
+ let { gdprApplies, consentString } = bidderRequest.gdprConsent;
414
+ o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
415
+ o.user.ext = {'consent': consentString};
416
+ }
417
+
418
+ return o;
419
+ }
420
+ registerBidder(spec);
@@ -1,69 +1,66 @@
1
- # Overview
2
-
3
- ```
4
- Module Name: Saambaa Bidder Adapter
5
- Module Type: Bidder Adapter
6
- Maintainer: matt.voigt@saambaa.com
7
- ```
8
-
9
- # Description
10
-
11
- Connects to Saambaa exchange for bids.
12
-
13
- Saambaa bid adapter supports Banner and Video ads currently.
14
-
15
- For more informatio
16
-
17
- # Sample Display Ad Unit: For Publishers
18
- ```javascript
19
-
20
- var displayAdUnit = [
21
- {
22
- code: 'display',
23
- mediaTypes: {
24
- banner: {
25
- sizes: [[300, 250],[320, 50]]
26
- }
27
- }
28
- bids: [{
29
- bidder: 'saambaa',
30
- params: {
31
- pubid: '121ab139faf7ac67428a23f1d0a9a71b',
32
- placement: 1234,
33
- size: '320x50'
34
- }
35
- }]
36
- }];
37
- ```
38
-
39
- # Sample Video Ad Unit: For Publishers
40
- ```javascript
41
-
42
- var videoAdUnit = {
43
- code: 'video',
44
- sizes: [320,480],
45
- mediaTypes: {
46
- video: {
47
- playerSize : [[320, 480]],
48
- context: 'instream'
49
- }
50
- },
51
- bids: [
52
- {
53
- bidder: 'saambaa',
54
- params: {
55
- pubid: '121ab139faf7ac67428a23f1d0a9a71b',
56
- placement: 1234,
57
- size: "320x480",
58
- video: {
59
- id: 123,
60
- skip: 1,
61
- mimes : ['video/mp4', 'application/javascript'],
62
- playbackmethod : [2,6],
63
- maxduration: 30
64
- }
65
- }
66
- }
67
- ]
68
- };
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Saambaa Bidder Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: matt.voigt@saambaa.com
7
+ ```
8
+
9
+ # Description
10
+
11
+ Connects to Saambaa exchange for bids.
12
+
13
+ Saambaa bid adapter supports Banner and Video ads currently.
14
+
15
+ For more informatio
16
+
17
+ # Sample Display Ad Unit: For Publishers
18
+ ```javascript
19
+
20
+ var displayAdUnit = [
21
+ {
22
+ code: 'display',
23
+ mediaTypes: {
24
+ banner: {
25
+ sizes: [[300, 250],[320, 50]]
26
+ }
27
+ }
28
+ bids: [{
29
+ bidder: 'saambaa',
30
+ params: {
31
+ pubid: '121ab139faf7ac67428a23f1d0a9a71b',
32
+ placement: 1234,
33
+ size: '320x50'
34
+ }
35
+ }]
36
+ }];
37
+ ```
38
+
39
+ # Sample Video Ad Unit: For Publishers
40
+ ```javascript
41
+
42
+ var videoAdUnit = {
43
+ code: 'video',
44
+ sizes: [320,480],
45
+ mediaTypes: {
46
+ video: {
47
+ playerSize : [[320, 480]],
48
+ context: 'instream',
49
+ skip: 1,
50
+ mimes : ['video/mp4', 'application/javascript'],
51
+ playbackmethod : [2,6],
52
+ maxduration: 30
53
+ }
54
+ },
55
+ bids: [
56
+ {
57
+ bidder: 'saambaa',
58
+ params: {
59
+ pubid: '121ab139faf7ac67428a23f1d0a9a71b',
60
+ placement: 1234,
61
+ size: "320x480"
62
+ }
63
+ }
64
+ ]
65
+ };
69
66
  ```
@@ -13,6 +13,11 @@ const ALLOWED_PLACEMENTS = {
13
13
  banner: true,
14
14
  video: true
15
15
  }
16
+
17
+ // Global Vendor List Id
18
+ // https://iabeurope.eu/vendor-list-tcf-v2-0/
19
+ const GVLID = 157;
20
+
16
21
  const mediaTypesMap = {
17
22
  [BANNER]: 'display',
18
23
  [VIDEO]: 'video'
@@ -158,6 +163,7 @@ export function getTimeoutUrl (data) {
158
163
 
159
164
  export const spec = {
160
165
  code: BIDDER_CODE,
166
+ gvlid: GVLID,
161
167
  aliases: [SEEDTAG_ALIAS],
162
168
  supportedMediaTypes: [BANNER, VIDEO],
163
169
  /**