prebid.js 7.14.0 → 7.16.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 (239) hide show
  1. package/.circleci/config.yml +3 -0
  2. package/dist/1plusXRtdProvider.js +1 -1
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adfBidAdapter.js +1 -1
  7. package/dist/adgenerationBidAdapter.js +1 -1
  8. package/dist/adkernelAdnBidAdapter.js +1 -1
  9. package/dist/adkernelBidAdapter.js +1 -1
  10. package/dist/adlooxAdServerVideo.js +1 -1
  11. package/dist/adlooxRtdProvider.js +1 -1
  12. package/dist/adrelevantisBidAdapter.js +1 -1
  13. package/dist/adtrgtmeBidAdapter.js +1 -1
  14. package/dist/adtrueBidAdapter.js +1 -1
  15. package/dist/adxcgBidAdapter.js +1 -1
  16. package/dist/airgridRtdProvider.js +1 -1
  17. package/dist/ajaBidAdapter.js +1 -1
  18. package/dist/amxBidAdapter.js +1 -1
  19. package/dist/amxIdSystem.js +1 -1
  20. package/dist/aolBidAdapter.js +1 -1
  21. package/dist/appierAnalyticsAdapter.js +1 -1
  22. package/dist/appnexusBidAdapter.js +1 -1
  23. package/dist/asoBidAdapter.js +1 -1
  24. package/dist/axonixBidAdapter.js +1 -1
  25. package/dist/beachfrontBidAdapter.js +1 -1
  26. package/dist/bidglassBidAdapter.js +1 -1
  27. package/dist/big-richmediaBidAdapter.js +1 -1
  28. package/dist/bizzclickBidAdapter.js +1 -1
  29. package/dist/bliinkBidAdapter.js +1 -1
  30. package/dist/bluebillywigBidAdapter.js +1 -1
  31. package/dist/brandmetricsRtdProvider.js +1 -1
  32. package/dist/bridgewellBidAdapter.js +1 -1
  33. package/dist/brightMountainMediaBidAdapter.js +1 -1
  34. package/dist/brightcomBidAdapter.js +1 -1
  35. package/dist/browsiRtdProvider.js +1 -1
  36. package/dist/categoryTranslation.js +1 -1
  37. package/dist/concertBidAdapter.js +1 -1
  38. package/dist/connectadBidAdapter.js +1 -1
  39. package/dist/consentManagement.js +1 -1
  40. package/dist/consentManagementUsp.js +1 -1
  41. package/dist/consumableBidAdapter.js +1 -1
  42. package/dist/conversantBidAdapter.js +1 -1
  43. package/dist/cpmstarBidAdapter.js +1 -1
  44. package/dist/craftBidAdapter.js +1 -1
  45. package/dist/criteoBidAdapter.js +1 -1
  46. package/dist/currency.js +1 -1
  47. package/dist/dataControllerModule.js +1 -1
  48. package/dist/dchain.js +1 -1
  49. package/dist/deepintentBidAdapter.js +1 -1
  50. package/dist/dependencies.json +3 -0
  51. package/dist/dgkeywordRtdProvider.js +1 -1
  52. package/dist/dianomiBidAdapter.js +1 -1
  53. package/dist/distroscaleBidAdapter.js +1 -1
  54. package/dist/dspxBidAdapter.js +1 -1
  55. package/dist/eplanningBidAdapter.js +1 -1
  56. package/dist/etargetBidAdapter.js +1 -1
  57. package/dist/feedadBidAdapter.js +1 -1
  58. package/dist/finativeBidAdapter.js +1 -1
  59. package/dist/fpdModule.js +1 -1
  60. package/dist/gamoshiBidAdapter.js +1 -1
  61. package/dist/glimpseBidAdapter.js +1 -1
  62. package/dist/gmosspBidAdapter.js +1 -1
  63. package/dist/goldbachBidAdapter.js +1 -1
  64. package/dist/gothamadsBidAdapter.js +1 -1
  65. package/dist/gridBidAdapter.js +1 -1
  66. package/dist/gridNMBidAdapter.js +1 -1
  67. package/dist/gumgumBidAdapter.js +1 -1
  68. package/dist/h12mediaBidAdapter.js +1 -1
  69. package/dist/iasRtdProvider.js +1 -1
  70. package/dist/id5IdSystem.js +1 -1
  71. package/dist/imRtdProvider.js +1 -1
  72. package/dist/impactifyBidAdapter.js +1 -1
  73. package/dist/improvedigitalBidAdapter.js +1 -1
  74. package/dist/inmarBidAdapter.js +1 -1
  75. package/dist/insticatorBidAdapter.js +1 -1
  76. package/dist/ixBidAdapter.js +1 -1
  77. package/dist/justpremiumBidAdapter.js +1 -1
  78. package/dist/konduitAnalyticsAdapter.js +1 -1
  79. package/dist/kueezBidAdapter.js +1 -1
  80. package/dist/lassoBidAdapter.js +1 -1
  81. package/dist/lifestreetBidAdapter.js +1 -1
  82. package/dist/liveIntentAnalyticsAdapter.js +1 -0
  83. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  84. package/dist/logicadBidAdapter.js +1 -1
  85. package/dist/loglyliftBidAdapter.js +1 -1
  86. package/dist/luponmediaBidAdapter.js +1 -1
  87. package/dist/malltvAnalyticsAdapter.js +1 -1
  88. package/dist/marsmediaBidAdapter.js +1 -1
  89. package/dist/mass.js +1 -1
  90. package/dist/mediafuseBidAdapter.js +1 -1
  91. package/dist/mediakeysBidAdapter.js +1 -1
  92. package/dist/mediasniperBidAdapter.js +1 -1
  93. package/dist/mediasquareBidAdapter.js +1 -1
  94. package/dist/mgidBidAdapter.js +1 -1
  95. package/dist/minutemediaBidAdapter.js +1 -1
  96. package/dist/multibid.js +1 -1
  97. package/dist/naveggIdSystem.js +1 -1
  98. package/dist/newspassidBidAdapter.js +1 -1
  99. package/dist/nextMillenniumBidAdapter.js +1 -1
  100. package/dist/not-for-prod/prebid.js +172 -171
  101. package/dist/oguryBidAdapter.js +1 -1
  102. package/dist/oneKeyRtdProvider.js +1 -1
  103. package/dist/onetagBidAdapter.js +1 -1
  104. package/dist/ooloAnalyticsAdapter.js +1 -1
  105. package/dist/openxBidAdapter.js +1 -1
  106. package/dist/openxOrtbBidAdapter.js +1 -1
  107. package/dist/operaadsBidAdapter.js +1 -1
  108. package/dist/outbrainBidAdapter.js +1 -1
  109. package/dist/ozoneBidAdapter.js +1 -1
  110. package/dist/parrableIdSystem.js +1 -1
  111. package/dist/permutiveRtdProvider.js +1 -1
  112. package/dist/pixfutureBidAdapter.js +1 -1
  113. package/dist/prebid-core.js +2 -2
  114. package/dist/prebidServerBidAdapter.js +1 -1
  115. package/dist/priceFloors.js +1 -1
  116. package/dist/pubCommonId.js +1 -1
  117. package/dist/pubgeniusBidAdapter.js +1 -1
  118. package/dist/publinkIdSystem.js +1 -1
  119. package/dist/pubmaticBidAdapter.js +1 -1
  120. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  121. package/dist/pubwiseBidAdapter.js +1 -1
  122. package/dist/pubxBidAdapter.js +1 -1
  123. package/dist/pxyzBidAdapter.js +1 -1
  124. package/dist/quantcastBidAdapter.js +1 -1
  125. package/dist/readpeakBidAdapter.js +1 -1
  126. package/dist/relaidoBidAdapter.js +1 -1
  127. package/dist/rhythmoneBidAdapter.js +1 -1
  128. package/dist/riseBidAdapter.js +1 -1
  129. package/dist/rtdModule.js +1 -1
  130. package/dist/rubiconAnalyticsAdapter.js +1 -1
  131. package/dist/rubiconBidAdapter.js +1 -1
  132. package/dist/seedingAllianceBidAdapter.js +1 -1
  133. package/dist/seedtagBidAdapter.js +1 -1
  134. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  135. package/dist/sharethroughBidAdapter.js +1 -1
  136. package/dist/shinezBidAdapter.js +1 -1
  137. package/dist/sirdataRtdProvider.js +1 -1
  138. package/dist/smaatoBidAdapter.js +1 -1
  139. package/dist/smartadserverBidAdapter.js +1 -1
  140. package/dist/smartxBidAdapter.js +1 -1
  141. package/dist/smilewantedBidAdapter.js +1 -1
  142. package/dist/sonobiBidAdapter.js +1 -1
  143. package/dist/sovrnAnalyticsAdapter.js +1 -1
  144. package/dist/sovrnBidAdapter.js +1 -1
  145. package/dist/spotxBidAdapter.js +1 -1
  146. package/dist/sspBCBidAdapter.js +1 -1
  147. package/dist/stroeerCoreBidAdapter.js +1 -1
  148. package/dist/sublimeBidAdapter.js +1 -1
  149. package/dist/synacormediaBidAdapter.js +1 -1
  150. package/dist/targetVideoBidAdapter.js +1 -1
  151. package/dist/teadsBidAdapter.js +1 -1
  152. package/dist/trionBidAdapter.js +1 -1
  153. package/dist/tripleliftBidAdapter.js +1 -1
  154. package/dist/ttdBidAdapter.js +1 -1
  155. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  156. package/dist/ucfunnelBidAdapter.js +1 -1
  157. package/dist/underdogmediaBidAdapter.js +1 -1
  158. package/dist/undertoneBidAdapter.js +1 -1
  159. package/dist/userId.js +1 -1
  160. package/dist/vidazooBidAdapter.js +1 -1
  161. package/dist/videobyteBidAdapter.js +1 -1
  162. package/dist/viewability.js +1 -1
  163. package/dist/visxBidAdapter.js +1 -1
  164. package/dist/vuukleBidAdapter.js +1 -1
  165. package/dist/weboramaRtdProvider.js +1 -1
  166. package/dist/widespaceBidAdapter.js +1 -1
  167. package/dist/winrBidAdapter.js +1 -1
  168. package/dist/yahoosspBidAdapter.js +1 -1
  169. package/dist/yieldliftBidAdapter.js +1 -1
  170. package/dist/yieldmoBidAdapter.js +1 -1
  171. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  172. package/dist/zeta_global_sspBidAdapter.js +1 -1
  173. package/modules/amxBidAdapter.js +98 -78
  174. package/modules/appnexusBidAdapter.js +73 -12
  175. package/modules/categoryTranslation.js +9 -8
  176. package/modules/consentManagement.js +4 -2
  177. package/modules/consentManagementUsp.js +17 -14
  178. package/modules/cpmstarBidAdapter.js +2 -1
  179. package/modules/currency.js +4 -3
  180. package/modules/dataControllerModule/index.js +4 -3
  181. package/modules/dchain.js +3 -2
  182. package/modules/dianomiBidAdapter.js +17 -14
  183. package/modules/dianomiBidAdapter.md +1 -1
  184. package/modules/feedadBidAdapter.js +40 -8
  185. package/modules/fpdModule/index.js +3 -2
  186. package/modules/iasRtdProvider.js +17 -3
  187. package/modules/ixBidAdapter.js +2 -5
  188. package/modules/liveIntentAnalyticsAdapter.js +148 -0
  189. package/modules/liveIntentAnalyticsAdapter.md +22 -0
  190. package/modules/mass.js +5 -3
  191. package/modules/multibid/index.js +4 -2
  192. package/modules/naveggIdSystem.js +53 -22
  193. package/modules/nextMillenniumBidAdapter.js +168 -55
  194. package/modules/openxOrtbBidAdapter.js +1 -1
  195. package/modules/prebidServerBidAdapter/index.js +18 -4
  196. package/modules/priceFloors.js +5 -4
  197. package/modules/pubCommonId.js +3 -2
  198. package/modules/rtdModule/index.js +3 -2
  199. package/modules/sharethroughBidAdapter.js +8 -6
  200. package/modules/spotxBidAdapter.js +1 -0
  201. package/modules/stroeerCoreBidAdapter.js +129 -92
  202. package/modules/stroeerCoreBidAdapter.md +52 -14
  203. package/modules/teadsBidAdapter.js +32 -10
  204. package/modules/ucfunnelBidAdapter.js +9 -10
  205. package/modules/userId/index.js +73 -48
  206. package/modules/viewability.js +2 -170
  207. package/package.json +3 -3
  208. package/src/adapterManager.js +21 -13
  209. package/src/adapters/bidderFactory.js +28 -6
  210. package/src/auction.js +17 -4
  211. package/src/auctionManager.js +5 -0
  212. package/src/constants.json +2 -0
  213. package/src/native.js +5 -2
  214. package/src/prebid.js +52 -23
  215. package/src/secureCreatives.js +1 -1
  216. package/src/utils/perfMetrics.js +386 -0
  217. package/src/utils.js +1 -1
  218. package/test/helpers/testing-utils.js +4 -3
  219. package/test/spec/modules/adriverIdSystem_spec.js +7 -3
  220. package/test/spec/modules/amxBidAdapter_spec.js +250 -192
  221. package/test/spec/modules/appnexusBidAdapter_spec.js +61 -6
  222. package/test/spec/modules/consentManagementUsp_spec.js +6 -2
  223. package/test/spec/modules/dianomiBidAdapter_spec.js +326 -6
  224. package/test/spec/modules/feedadBidAdapter_spec.js +147 -11
  225. package/test/spec/modules/iasRtdProvider_spec.js +3 -1
  226. package/test/spec/modules/ixBidAdapter_spec.js +0 -64
  227. package/test/spec/modules/liveIntentAnalyticsAdapter_spec.js +297 -0
  228. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +103 -1
  229. package/test/spec/modules/openxOrtbBidAdapter_spec.js +31 -0
  230. package/test/spec/modules/sharethroughBidAdapter_spec.js +23 -2
  231. package/test/spec/modules/spotxBidAdapter_spec.js +6 -0
  232. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +315 -33
  233. package/test/spec/modules/teadsBidAdapter_spec.js +65 -11
  234. package/test/spec/modules/ucfunnelBidAdapter_spec.js +24 -10
  235. package/test/spec/native_spec.js +11 -0
  236. package/test/spec/unit/utils/perfMetrics_spec.js +394 -0
  237. package/wdio.conf.js +1 -0
  238. package/modules/viewability.md +0 -87
  239. package/test/spec/modules/viewability_spec.js +0 -280
@@ -1,7 +1,21 @@
1
- import { isStr, _each, parseUrl, getWindowTop, getBidIdParameter } from '../src/utils.js';
2
- import { getRefererInfo } from '../src/refererDetection.js';
1
+ import {
2
+ _each,
3
+ createTrackPixelHtml,
4
+ deepAccess,
5
+ isStr,
6
+ getWindowTop,
7
+ getBidIdParameter,
8
+ logMessage,
9
+ parseUrl,
10
+ triggerPixel,
11
+ } from '../src/utils.js';
12
+
13
+ import CONSTANTS from '../src/constants.json';
14
+ import { BANNER, VIDEO } from '../src/mediaTypes.js';
15
+ import * as events from '../src/events.js';
16
+
3
17
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
- import { BANNER } from '../src/mediaTypes.js';
18
+ import { getRefererInfo } from '../src/refererDetection.js';
5
19
 
6
20
  const BIDDER_CODE = 'nextMillennium';
7
21
  const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction';
@@ -9,9 +23,15 @@ const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction';
9
23
  const SYNC_ENDPOINT = 'https://statics.nextmillmedia.com/load-cookie.html?v=4';
10
24
  const TIME_TO_LIVE = 360;
11
25
 
26
+ const EXPIRENCE_WURL = 20 * 60000;
27
+ const wurlMap = {};
28
+
29
+ events.on(CONSTANTS.EVENTS.BID_WON, bidWonHandler);
30
+ cleanWurl();
31
+
12
32
  export const spec = {
13
33
  code: BIDDER_CODE,
14
- supportedMediaTypes: [BANNER],
34
+ supportedMediaTypes: [BANNER, VIDEO],
15
35
 
16
36
  isBidRequestValid: function(bid) {
17
37
  return !!(
@@ -25,12 +45,14 @@ export const spec = {
25
45
 
26
46
  _each(validBidRequests, function(bid) {
27
47
  window.nmmRefreshCounts[bid.adUnitCode] = window.nmmRefreshCounts[bid.adUnitCode] || 0;
28
- const id = getPlacementId(bid)
29
- let sizes = bid.sizes
30
- if (sizes && !Array.isArray(sizes[0])) sizes = [sizes]
48
+ const id = getPlacementId(bid);
49
+ const auctionId = bid.auctionId;
50
+ const bidId = bid.bidId;
51
+ let sizes = bid.sizes;
52
+ if (sizes && !Array.isArray(sizes[0])) sizes = [sizes];
31
53
 
32
- const site = getSiteObj()
33
- const device = getDeviceObj()
54
+ const site = getSiteObj();
55
+ const device = getDeviceObj();
34
56
 
35
57
  const postBody = {
36
58
  'id': bid.auctionId,
@@ -47,12 +69,14 @@ export const spec = {
47
69
  'scrollTop': window.pageYOffset || document.documentElement.scrollTop
48
70
  }
49
71
  },
72
+
50
73
  device,
51
74
  site,
52
75
  'imp': [{
53
76
  'banner': {
54
77
  'format': (sizes || []).map(s => { return {w: s[0], h: s[1]} })
55
78
  },
79
+
56
80
  'ext': {
57
81
  'prebid': {
58
82
  'storedrequest': {
@@ -61,30 +85,30 @@ export const spec = {
61
85
  }
62
86
  }
63
87
  }]
64
- }
88
+ };
65
89
 
66
90
  const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
67
- const uspConsent = bidderRequest && bidderRequest.uspConsent
91
+ const uspConsent = bidderRequest && bidderRequest.uspConsent;
68
92
 
69
93
  if (gdprConsent || uspConsent) {
70
- postBody.regs = { ext: {} }
94
+ postBody.regs = { ext: {} };
71
95
 
72
96
  if (uspConsent) {
73
97
  postBody.regs.ext.us_privacy = uspConsent;
74
- }
98
+ };
75
99
 
76
100
  if (gdprConsent) {
77
101
  if (typeof gdprConsent.gdprApplies !== 'undefined') {
78
102
  postBody.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0;
79
- }
103
+ };
80
104
 
81
105
  if (typeof gdprConsent.consentString !== 'undefined') {
82
106
  postBody.user = {
83
107
  ext: { consent: gdprConsent.consentString }
84
- }
85
- }
86
- }
87
- }
108
+ };
109
+ };
110
+ };
111
+ };
88
112
 
89
113
  const urlParameters = parseUrl(getWindowTop().location.href).search;
90
114
  const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test';
@@ -97,7 +121,9 @@ export const spec = {
97
121
  contentType: 'application/json',
98
122
  withCredentials: true
99
123
  },
100
- bidId: bid.bidId
124
+
125
+ bidId,
126
+ auctionId,
101
127
  });
102
128
  });
103
129
 
@@ -110,8 +136,15 @@ export const spec = {
110
136
 
111
137
  _each(response.seatbid, (resp) => {
112
138
  _each(resp.bid, (bid) => {
113
- bidResponses.push({
114
- requestId: bidRequest.bidId,
139
+ const requestId = bidRequest.bidId;
140
+ const auctionId = bidRequest.auctionId;
141
+ const wurl = deepAccess(bid, 'ext.prebid.events.win');
142
+ addWurl({auctionId, requestId, wurl});
143
+
144
+ const {ad, adUrl, vastUrl, vastXml} = getAd(bid);
145
+
146
+ const bidResponse = {
147
+ requestId,
115
148
  cpm: bid.price,
116
149
  width: bid.w,
117
150
  height: bid.h,
@@ -121,10 +154,20 @@ export const spec = {
121
154
  ttl: TIME_TO_LIVE,
122
155
  meta: {
123
156
  advertiserDomains: bid.adomain || []
124
- },
157
+ }
158
+ };
159
+
160
+ if (vastUrl || vastXml) {
161
+ bidResponse.mediaType = VIDEO;
125
162
 
126
- ad: bid.adm
127
- });
163
+ if (vastUrl) bidResponse.vastUrl = vastUrl;
164
+ if (vastXml) bidResponse.vastXml = vastXml;
165
+ } else {
166
+ bidResponse.ad = ad;
167
+ bidResponse.adUrl = adUrl;
168
+ };
169
+
170
+ bidResponses.push(bidResponse);
128
171
  });
129
172
  });
130
173
 
@@ -133,22 +176,22 @@ export const spec = {
133
176
 
134
177
  getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
135
178
  if (!syncOptions.iframeEnabled) {
136
- return
137
- }
179
+ return;
180
+ };
138
181
 
139
- let syncurl = gdprConsent && gdprConsent.gdprApplies ? `${SYNC_ENDPOINT}&gdpr=1&gdpr_consent=${gdprConsent.consentString}` : SYNC_ENDPOINT
182
+ let syncurl = gdprConsent && gdprConsent.gdprApplies ? `${SYNC_ENDPOINT}&gdpr=1&gdpr_consent=${gdprConsent.consentString}` : SYNC_ENDPOINT;
140
183
 
141
- let bidders = []
184
+ let bidders = [];
142
185
  if (responses) {
143
186
  _each(responses, (response) => {
144
- if (!(response && response.body && response.body.ext && response.body.ext.responsetimemillis)) return
145
- _each(Object.keys(response.body.ext.responsetimemillis), b => bidders.push(b))
146
- })
147
- }
187
+ if (!(response && response.body && response.body.ext && response.body.ext.responsetimemillis)) return;
188
+ _each(Object.keys(response.body.ext.responsetimemillis), b => bidders.push(b));
189
+ });
190
+ };
148
191
 
149
192
  if (bidders.length) {
150
- syncurl += `&bidders=${bidders.join(',')}`
151
- }
193
+ syncurl += `&bidders=${bidders.join(',')}`;
194
+ };
152
195
 
153
196
  return [{
154
197
  type: 'iframe',
@@ -156,6 +199,7 @@ export const spec = {
156
199
  }];
157
200
  },
158
201
  };
202
+
159
203
  function getAdEl(bid) {
160
204
  // best way I could think of to get El, is by matching adUnitCode to google slots...
161
205
  const slot = window.googletag && window.googletag.pubads && window.googletag.pubads().getSlots().find(slot => slot.getAdUnitPath() === bid.adUnitCode);
@@ -163,58 +207,127 @@ function getAdEl(bid) {
163
207
  if (!slotElementId) return null;
164
208
  return document.querySelector('#' + slotElementId);
165
209
  }
210
+
166
211
  function getBoundingClient(bid) {
167
- // console.log(bid)
168
- const el = getAdEl(bid)
169
- if (!el) return {}
212
+ const el = getAdEl(bid);
213
+ if (!el) return {};
170
214
  return el.getBoundingClientRect();
171
215
  }
172
216
 
173
217
  function getPlacementId(bid) {
174
- const groupId = getBidIdParameter('group_id', bid.params)
175
- const placementId = getBidIdParameter('placement_id', bid.params)
176
- if (!groupId) return placementId
218
+ const groupId = getBidIdParameter('group_id', bid.params);
219
+ const placementId = getBidIdParameter('placement_id', bid.params);
220
+ if (!groupId) return placementId;
177
221
 
178
- let windowTop = getTopWindow(window)
179
- let size = []
222
+ let windowTop = getTopWindow(window);
223
+ let sizes = [];
180
224
  if (bid.mediaTypes) {
181
- if (bid.mediaTypes.banner) size = bid.mediaTypes.banner.sizes && bid.mediaTypes.banner.sizes[0]
182
- if (bid.mediaTypes.video) size = bid.mediaTypes.video.playerSize
183
- }
225
+ if (bid.mediaTypes.banner) sizes = bid.mediaTypes.banner.sizes;
226
+ if (bid.mediaTypes.video) sizes = [bid.mediaTypes.video.playerSize];
227
+ };
184
228
 
185
- const host = (windowTop && windowTop.location && windowTop.location.host) || ''
186
- return `g${groupId};${size.join('x')};${host}`
229
+ const host = (windowTop && windowTop.location && windowTop.location.host) || '';
230
+ return `g${groupId};${sizes.map(size => size.join('x')).join('|')};${host}`;
187
231
  }
188
232
 
189
233
  function getTopWindow(curWindow, nesting = 0) {
190
234
  if (nesting > 10) {
191
- return curWindow
192
- }
235
+ return curWindow;
236
+ };
193
237
 
194
238
  try {
195
239
  if (curWindow.parent.document) {
196
- return getTopWindow(curWindow.parent.window, ++nesting)
197
- }
240
+ return getTopWindow(curWindow.parent.window, ++nesting);
241
+ };
198
242
  } catch (err) {
199
- return curWindow
243
+ return curWindow;
244
+ };
245
+ }
246
+
247
+ function getAd(bid) {
248
+ let ad, adUrl, vastXml, vastUrl;
249
+
250
+ switch (deepAccess(bid, 'ext.prebid.type')) {
251
+ case VIDEO:
252
+ if (bid.adm.substr(0, 4) === 'http') {
253
+ vastUrl = bid.adm;
254
+ } else {
255
+ vastXml = bid.adm;
256
+ };
257
+
258
+ break;
259
+ default:
260
+ if (bid.adm && bid.nurl) {
261
+ ad = bid.adm;
262
+ ad += createTrackPixelHtml(decodeURIComponent(bid.nurl));
263
+ } else if (bid.adm) {
264
+ ad = bid.adm;
265
+ } else if (bid.nurl) {
266
+ adUrl = bid.nurl;
267
+ };
200
268
  }
269
+
270
+ return {ad, adUrl, vastXml, vastUrl};
201
271
  }
202
272
 
203
273
  function getSiteObj() {
204
- const refInfo = (getRefererInfo && getRefererInfo()) || {}
274
+ const refInfo = (getRefererInfo && getRefererInfo()) || {};
205
275
 
206
276
  return {
207
277
  page: refInfo.page,
208
278
  ref: refInfo.ref,
209
279
  domain: refInfo.domain
210
- }
280
+ };
211
281
  }
212
282
 
213
283
  function getDeviceObj() {
214
284
  return {
215
285
  w: window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth || 0,
216
286
  h: window.innerHeight || window.document.documentElement.clientHeight || window.document.body.clientHeight || 0,
217
- }
287
+ };
288
+ }
289
+
290
+ function getKeyWurl({auctionId, requestId}) {
291
+ return `${auctionId}-${requestId}`;
292
+ }
293
+
294
+ function addWurl({wurl, requestId, auctionId}) {
295
+ if (!wurl) return;
296
+
297
+ const expirence = Date.now() + EXPIRENCE_WURL;
298
+ const key = getKeyWurl({auctionId, requestId});
299
+ wurlMap[key] = {wurl, expirence};
300
+ }
301
+
302
+ function removeWurl({auctionId, requestId}) {
303
+ const key = getKeyWurl({auctionId, requestId});
304
+ delete wurlMap[key];
305
+ }
306
+
307
+ function getWurl({auctionId, requestId}) {
308
+ const key = getKeyWurl({auctionId, requestId});
309
+ return wurlMap[key] && wurlMap[key].wurl;
310
+ }
311
+
312
+ function bidWonHandler(bid) {
313
+ const {auctionId, requestId} = bid;
314
+ const wurl = getWurl({auctionId, requestId});
315
+ if (wurl) {
316
+ logMessage(`(nextmillennium) Invoking image pixel for wurl on BID_WIN: "${wurl}"`);
317
+ triggerPixel(wurl);
318
+ removeWurl({auctionId, requestId});
319
+ };
320
+ }
321
+
322
+ function cleanWurl() {
323
+ const dateNow = Date.now();
324
+ Object.keys(wurlMap).forEach(key => {
325
+ if (dateNow >= wurlMap[key].expirence) {
326
+ delete wurlMap[key];
327
+ };
328
+ });
329
+
330
+ setTimeout(cleanWurl, 60000);
218
331
  }
219
332
 
220
333
  registerBidder(spec);
@@ -275,7 +275,7 @@ function interpretOrtbResponse(resp, req) {
275
275
  }
276
276
 
277
277
  const respBody = resp.body;
278
- if (!respBody || 'nbr' in respBody) {
278
+ if (!respBody || 'nbr' in respBody || !Array.isArray(respBody.seatbid)) {
279
279
  return [];
280
280
  }
281
281
 
@@ -39,6 +39,7 @@ import {ajax} from '../../src/ajax.js';
39
39
  import {hook} from '../../src/hook.js';
40
40
  import {getGlobal} from '../../src/prebidGlobal.js';
41
41
  import {hasPurpose1Consent} from '../../src/utils/gpdr.js';
42
+ import {useMetrics} from '../../src/utils/perfMetrics.js';
42
43
 
43
44
  const getConfig = config.getConfig;
44
45
 
@@ -1097,6 +1098,12 @@ export function PrebidServer() {
1097
1098
 
1098
1099
  /* Prebid executes this function when the page asks to send out bid requests */
1099
1100
  baseAdapter.callBids = function(s2sBidRequest, bidRequests, addBidResponse, done, ajax) {
1101
+ const adapterMetrics = s2sBidRequest.metrics = useMetrics(deepAccess(bidRequests, '0.metrics'))
1102
+ .newMetrics()
1103
+ .renameWith((n) => [`adapter.s2s.${n}`, `adapters.s2s.${s2sBidRequest.s2sConfig.defaultVendor}.${n}`])
1104
+ done = adapterMetrics.startTiming('total').stopBefore(done);
1105
+ bidRequests.forEach(req => useMetrics(req.metrics).join(adapterMetrics, {continuePropagation: false}));
1106
+
1100
1107
  let { gdprConsent, uspConsent } = getConsentData(bidRequests);
1101
1108
 
1102
1109
  if (Array.isArray(_s2sConfigs)) {
@@ -1118,7 +1125,9 @@ export function PrebidServer() {
1118
1125
  },
1119
1126
  onError: done,
1120
1127
  onBid: function ({adUnit, bid}) {
1121
- if (isValid(adUnit, bid)) {
1128
+ const metrics = bid.metrics = s2sBidRequest.metrics.fork().renameWith();
1129
+ metrics.checkpoint('addBidResponse');
1130
+ if (metrics.measureTime('addBidResponse.validate', () => isValid(adUnit, bid))) {
1122
1131
  addBidResponse(adUnit, bid);
1123
1132
  }
1124
1133
  }
@@ -1157,19 +1166,21 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques
1157
1166
  .filter(uniques);
1158
1167
 
1159
1168
  const ortb2 = new ORTB2(s2sBidRequest, bidRequests, adUnits, requestedBidders);
1160
- const request = ortb2.buildRequest();
1169
+ const request = s2sBidRequest.metrics.measureTime('buildRequests', () => ortb2.buildRequest());
1161
1170
  const requestJson = request && JSON.stringify(request);
1162
1171
  logInfo('BidRequest: ' + requestJson);
1163
1172
  const endpointUrl = getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent);
1164
1173
  if (request && requestJson && endpointUrl) {
1174
+ const networkDone = s2sBidRequest.metrics.startTiming('net');
1165
1175
  ajax(
1166
1176
  endpointUrl,
1167
1177
  {
1168
1178
  success: function (response) {
1179
+ networkDone();
1169
1180
  let result;
1170
1181
  try {
1171
1182
  result = JSON.parse(response);
1172
- const bids = ortb2.interpretResponse(result);
1183
+ const bids = s2sBidRequest.metrics.measureTime('interpretResponse', () => ortb2.interpretResponse(result));
1173
1184
  bids.forEach(onBid);
1174
1185
  } catch (error) {
1175
1186
  logError(error);
@@ -1181,7 +1192,10 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques
1181
1192
  onResponse(true, requestedBidders);
1182
1193
  }
1183
1194
  },
1184
- error: onError
1195
+ error: function () {
1196
+ networkDone();
1197
+ onError.apply(this, arguments);
1198
+ }
1185
1199
  },
1186
1200
  requestJson,
1187
1201
  {contentType: 'text/plain', withCredentials: true}
@@ -25,6 +25,7 @@ import {find} from '../src/polyfill.js';
25
25
  import {getRefererInfo} from '../src/refererDetection.js';
26
26
  import {bidderSettings} from '../src/bidderSettings.js';
27
27
  import {auctionManager} from '../src/auctionManager.js';
28
+ import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js';
28
29
 
29
30
  /**
30
31
  * @summary This Module is intended to provide users with the ability to dynamically set and enforce price floors on a per auction basis.
@@ -501,7 +502,7 @@ export function parseFloorData(floorsData, location) {
501
502
  * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
502
503
  * @param {function} fn required; The next function in the chain, used by hook.js
503
504
  */
504
- export function requestBidsHook(fn, reqBidsConfigObj) {
505
+ export const requestBidsHook = timedAuctionHook('priceFloors', function requestBidsHook(fn, reqBidsConfigObj) {
505
506
  // preserves all module related variables for the current auction instance (used primiarily for concurrent auctions)
506
507
  const hookConfig = {
507
508
  reqBidsConfigObj,
@@ -522,7 +523,7 @@ export function requestBidsHook(fn, reqBidsConfigObj) {
522
523
  } else {
523
524
  continueAuction(hookConfig);
524
525
  }
525
- }
526
+ });
526
527
 
527
528
  /**
528
529
  * @summary If an auction was queued to be delayed (waiting for a fetch) then this function will resume
@@ -693,7 +694,7 @@ function shouldFloorBid(floorData, floorInfo, bid) {
693
694
  * @summary The main driving force of floors. On bidResponse we hook in and intercept bidResponses.
694
695
  * And if the rule we find determines a bid should be floored we will do so.
695
696
  */
696
- export function addBidResponseHook(fn, adUnitCode, bid) {
697
+ export const addBidResponseHook = timedBidResponseHook('priceFloors', function addBidResponseHook(fn, adUnitCode, bid) {
697
698
  let floorData = _floorDataForAuction[bid.auctionId];
698
699
  // if no floor data then bail
699
700
  if (!floorData || !bid || floorData.skipped) {
@@ -755,6 +756,6 @@ export function addBidResponseHook(fn, adUnitCode, bid) {
755
756
  return fn.call(this, adUnitCode, flooredBid);
756
757
  }
757
758
  return fn.call(this, adUnitCode, bid);
758
- }
759
+ });
759
760
 
760
761
  config.getConfig('floors', config => handleSetFloorsConfig(config.floors));
@@ -8,6 +8,7 @@ import { config } from '../src/config.js';
8
8
  import * as events from '../src/events.js';
9
9
  import CONSTANTS from '../src/constants.json';
10
10
  import { getStorageManager } from '../src/storageManager.js';
11
+ import {timedAuctionHook} from '../src/utils/perfMetrics.js';
11
12
 
12
13
  const storage = getStorageManager({moduleName: 'pubCommonId'});
13
14
 
@@ -165,7 +166,7 @@ export function getPubcidConfig() { return pubcidConfig; }
165
166
  * @param {function} next The next function in the chain
166
167
  */
167
168
 
168
- export function requestBidHook(next, config) {
169
+ export const requestBidHook = timedAuctionHook('pubCommonId', function requestBidHook(next, config) {
169
170
  let adUnits = config.adUnits || $$PREBID_GLOBAL$$.adUnits;
170
171
  let pubcid = null;
171
172
 
@@ -221,7 +222,7 @@ export function requestBidHook(next, config) {
221
222
  }
222
223
 
223
224
  return next.call(this, config);
224
- }
225
+ });
225
226
 
226
227
  // Helper to set a cookie
227
228
  export function setCookie(name, value, expires, sameSite) {
@@ -158,6 +158,7 @@ import * as events from '../../src/events.js';
158
158
  import CONSTANTS from '../../src/constants.json';
159
159
  import {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js';
160
160
  import {find} from '../../src/polyfill.js';
161
+ import {timedAuctionHook} from '../../src/utils/perfMetrics.js';
161
162
 
162
163
  /** @type {string} */
163
164
  const MODULE_NAME = 'realTimeData';
@@ -266,7 +267,7 @@ function initSubModules() {
266
267
  * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
267
268
  * @param {function} fn required; The next function in the chain, used by hook.js
268
269
  */
269
- export function setBidRequestsData(fn, reqBidsConfigObj) {
270
+ export const setBidRequestsData = timedAuctionHook('rtd', function setBidRequestsData(fn, reqBidsConfigObj) {
270
271
  _userConsent = getConsentData();
271
272
 
272
273
  const relevantSubModules = [];
@@ -317,7 +318,7 @@ export function setBidRequestsData(fn, reqBidsConfigObj) {
317
318
  clearTimeout(waitTimeout);
318
319
  fn.call(this, reqBidsConfigObj);
319
320
  }
320
- }
321
+ });
321
322
 
322
323
  /**
323
324
  * loop through configured data providers If the data provider has registered getTargetingData,
@@ -4,7 +4,7 @@ import { config } from '../src/config.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
5
  import { createEidsArray } from './userId/eids.js';
6
6
 
7
- const VERSION = '4.2.0';
7
+ const VERSION = '4.3.0';
8
8
  const BIDDER_CODE = 'sharethrough';
9
9
  const SUPPLY_ID = 'WYu2BXv1';
10
10
 
@@ -52,6 +52,7 @@ export const sharethroughAdapterSpec = {
52
52
  ext: {},
53
53
  },
54
54
  source: {
55
+ tid: bidRequests[0].transactionId,
55
56
  ext: {
56
57
  version: '$prebid.version$',
57
58
  str: VERSION,
@@ -80,12 +81,13 @@ export const sharethroughAdapterSpec = {
80
81
  }
81
82
 
82
83
  const imps = bidRequests.map(bidReq => {
83
- const impression = {};
84
+ const impression = { ext: {} };
84
85
 
85
- const gpid = deepAccess(bidReq, 'ortb2Imp.ext.data.pbadslot');
86
- if (gpid) {
87
- impression.ext = { gpid: gpid };
88
- }
86
+ // mergeDeep(impression, bidReq.ortb2Imp); // leaving this out for now as we may want to leave stuff out on purpose
87
+ const tid = deepAccess(bidReq, 'ortb2Imp.ext.tid');
88
+ if (tid) impression.ext.tid = tid;
89
+ const gpid = deepAccess(bidReq, 'ortb2Imp.ext.gpid', deepAccess(bidReq, 'ortb2Imp.ext.data.pbadslot'));
90
+ if (gpid) impression.ext.gpid = gpid;
89
91
 
90
92
  const videoRequest = deepAccess(bidReq, 'mediaTypes.video');
91
93
 
@@ -365,6 +365,7 @@ export const spec = {
365
365
  const renderer = Renderer.install({
366
366
  id: 0,
367
367
  renderNow: true,
368
+ url: '/',
368
369
  config: {
369
370
  adText: 'SpotX Outstream Video Ad via Prebid.js',
370
371
  player_width: playersize[0][0],