prebid.js 6.4.0 → 6.8.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 (147) hide show
  1. package/integrationExamples/gpt/amp/creative.html +11 -33
  2. package/integrationExamples/gpt/x-domain/creative.html +53 -26
  3. package/modules/.submodules.json +2 -1
  4. package/modules/adagioBidAdapter.js +0 -8
  5. package/modules/adagioBidAdapter.md +1 -1
  6. package/modules/adbookpspBidAdapter.js +27 -10
  7. package/modules/adhashBidAdapter.js +3 -3
  8. package/modules/adkernelBidAdapter.js +2 -1
  9. package/modules/admanBidAdapter.js +10 -4
  10. package/modules/adomikAnalyticsAdapter.js +23 -11
  11. package/modules/adqueryIdSystem.js +103 -0
  12. package/modules/adqueryIdSystem.md +35 -0
  13. package/modules/adyoulikeBidAdapter.js +13 -9
  14. package/modules/appnexusBidAdapter.js +11 -0
  15. package/modules/bliinkBidAdapter.js +3 -2
  16. package/modules/brandmetricsRtdProvider.js +168 -0
  17. package/modules/brandmetricsRtdProvider.md +40 -0
  18. package/modules/colossussspBidAdapter.js +12 -8
  19. package/modules/colossussspBidAdapter.md +15 -1
  20. package/modules/compassBidAdapter.js +10 -3
  21. package/modules/consentManagement.js +7 -1
  22. package/modules/consumableBidAdapter.md +1 -1
  23. package/modules/criteoBidAdapter.js +10 -1
  24. package/modules/criteoIdSystem.js +29 -7
  25. package/modules/currency.js +26 -1
  26. package/modules/displayioBidAdapter.js +157 -0
  27. package/modules/displayioBidAdapter.md +148 -0
  28. package/modules/docereeBidAdapter.js +10 -1
  29. package/modules/docereeBidAdapter.md +2 -0
  30. package/modules/e_volutionBidAdapter.js +158 -0
  31. package/modules/glimpseBidAdapter.js +66 -44
  32. package/modules/gnetBidAdapter.js +3 -3
  33. package/modules/gnetBidAdapter.md +4 -4
  34. package/modules/gptPreAuction.js +55 -7
  35. package/modules/gumgumBidAdapter.js +56 -42
  36. package/modules/idImportLibrary.js +45 -8
  37. package/modules/idImportLibrary.md +4 -0
  38. package/modules/improvedigitalBidAdapter.js +24 -2
  39. package/modules/interactiveOffersBidAdapter.js +9 -6
  40. package/modules/ixBidAdapter.js +29 -12
  41. package/modules/jwplayerRtdProvider.js +71 -6
  42. package/modules/jwplayerRtdProvider.md +27 -11
  43. package/modules/kargoBidAdapter.js +2 -2
  44. package/modules/limelightDigitalBidAdapter.js +2 -1
  45. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  46. package/modules/loglyliftBidAdapter.js +79 -0
  47. package/modules/loglyliftBidAdapter.md +55 -0
  48. package/modules/nextMillenniumBidAdapter.js +3 -1
  49. package/modules/oguryBidAdapter.js +9 -2
  50. package/modules/onetagBidAdapter.js +4 -2
  51. package/modules/optimeraRtdProvider.js +8 -1
  52. package/modules/ozoneBidAdapter.js +21 -64
  53. package/modules/pilotxBidAdapter.js +147 -0
  54. package/modules/pilotxBidAdapter.md +50 -0
  55. package/modules/proxistoreBidAdapter.js +0 -2
  56. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  57. package/modules/richaudienceBidAdapter.js +3 -2
  58. package/modules/riseBidAdapter.js +1 -1
  59. package/modules/rtbhouseBidAdapter.js +14 -4
  60. package/modules/rtdModule/index.js +14 -15
  61. package/modules/rubiconAnalyticsAdapter.js +3 -2
  62. package/modules/seedingAllianceBidAdapter.js +3 -3
  63. package/modules/sharethroughBidAdapter.js +12 -17
  64. package/modules/showheroes-bsBidAdapter.js +13 -2
  65. package/modules/sovrnBidAdapter.js +93 -18
  66. package/modules/sovrnBidAdapter.md +80 -2
  67. package/modules/synacormediaBidAdapter.js +31 -10
  68. package/modules/tappxBidAdapter.js +8 -5
  69. package/modules/teadsBidAdapter.js +1 -2
  70. package/modules/undertoneBidAdapter.js +17 -1
  71. package/modules/userId/eids.js +7 -1
  72. package/modules/userId/userId.md +8 -0
  73. package/modules/viewability.js +177 -0
  74. package/modules/viewability.md +87 -0
  75. package/modules/welectBidAdapter.js +106 -0
  76. package/modules/yahoosspBidAdapter.js +2 -0
  77. package/modules/yieldmoBidAdapter.js +23 -5
  78. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  79. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  80. package/package.json +1 -1
  81. package/src/adRendering.js +38 -0
  82. package/src/auction.js +44 -9
  83. package/src/config.js +27 -3
  84. package/src/hook.js +5 -1
  85. package/src/prebid.js +21 -21
  86. package/src/secureCreatives.js +114 -44
  87. package/src/utils.js +25 -4
  88. package/test/helpers/syncPromise.js +71 -0
  89. package/test/spec/auctionmanager_spec.js +148 -16
  90. package/test/spec/config_spec.js +279 -0
  91. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  92. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  93. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  94. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  95. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  96. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  97. package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
  98. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  99. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  100. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  101. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  102. package/test/spec/modules/compassBidAdapter_spec.js +1 -0
  103. package/test/spec/modules/consentManagement_spec.js +20 -0
  104. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  105. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  106. package/test/spec/modules/currency_spec.js +21 -6
  107. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  108. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  109. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  110. package/test/spec/modules/eids_spec.js +15 -0
  111. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  112. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  113. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  114. package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
  115. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  116. package/test/spec/modules/improvedigitalBidAdapter_spec.js +42 -0
  117. package/test/spec/modules/ixBidAdapter_spec.js +104 -62
  118. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  119. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  120. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
  121. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  122. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  123. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
  124. package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
  125. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  126. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  127. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  128. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  129. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  130. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  131. package/test/spec/modules/riseBidAdapter_spec.js +1 -1
  132. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  133. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +30 -0
  134. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  135. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  136. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  137. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  138. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  139. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  140. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  141. package/test/spec/modules/userId_spec.js +68 -19
  142. package/test/spec/modules/viewability_spec.js +280 -0
  143. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  144. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  145. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  146. package/test/spec/unit/pbjs_api_spec.js +20 -2
  147. package/test/spec/unit/secureCreatives_spec.js +85 -0
@@ -0,0 +1,147 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ const BIDDER_CODE = 'pilotx';
3
+ const ENDPOINT_URL = '//adn.pilotx.tv/hb'
4
+ export const spec = {
5
+ code: BIDDER_CODE,
6
+ supportedMediaTypes: ['banner', 'video'],
7
+ aliases: ['pilotx'], // short code
8
+ /**
9
+ * Determines whether or not the given bid request is valid.
10
+ *
11
+ * @param {BidRequest} bid The bid params to validate.
12
+ * @return boolean True if this is a valid bid, and false otherwise.
13
+ */
14
+ isBidRequestValid: function (bid) {
15
+ let sizesCheck = !!bid.sizes
16
+ let paramSizesCheck = !!bid.params.sizes
17
+ var sizeConfirmed = false
18
+ if (sizesCheck) {
19
+ if (bid.sizes.length < 1) {
20
+ return false
21
+ } else {
22
+ sizeConfirmed = true
23
+ }
24
+ }
25
+ if (paramSizesCheck) {
26
+ if (bid.params.sizes.length < 1 && !sizeConfirmed) {
27
+ return false
28
+ } else {
29
+ sizeConfirmed = true
30
+ }
31
+ }
32
+ if (!sizeConfirmed) {
33
+ return false
34
+ }
35
+ return !!(bid.params.placementId);
36
+ },
37
+ /**
38
+ * Make a server request from the list of BidRequests.
39
+ *
40
+ * @param {validBidRequests[]} - an array of bids
41
+ * @return ServerRequest Info describing the request to the server.
42
+ */
43
+ buildRequests: function (validBidRequests, bidderRequest) {
44
+ let payloadItems = {};
45
+ validBidRequests.forEach(bidRequest => {
46
+ let sizes = [];
47
+ let placementId = this.setPlacementID(bidRequest.params.placementId)
48
+ payloadItems[placementId] = {}
49
+ if (bidRequest.sizes.length > 0) {
50
+ if (Array.isArray(bidRequest.sizes[0])) {
51
+ for (let i = 0; i < bidRequest.sizes.length; i++) {
52
+ sizes[i] = [(bidRequest.sizes[i])[0], (bidRequest.sizes[i])[1]]
53
+ }
54
+ } else {
55
+ sizes[0] = [bidRequest.sizes[0], bidRequest.sizes[1]]
56
+ }
57
+ payloadItems[placementId]['sizes'] = sizes
58
+ }
59
+ if (bidRequest.mediaTypes != null) {
60
+ for (let i in bidRequest.mediaTypes) {
61
+ payloadItems[placementId][i] = {
62
+ ...bidRequest.mediaTypes[i]
63
+ }
64
+ }
65
+ }
66
+ let consentTemp = ''
67
+ let consentRequiredTemp = false
68
+ if (bidderRequest && bidderRequest.gdprConsent) {
69
+ consentTemp = bidderRequest.gdprConsent.consentString
70
+ // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true
71
+ consentRequiredTemp = (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true
72
+ }
73
+
74
+ payloadItems[placementId]['gdprConsentString'] = consentTemp
75
+ payloadItems[placementId]['gdprConsentRequired'] = consentRequiredTemp
76
+ payloadItems[placementId]['bidId'] = bidRequest.bidId
77
+ });
78
+ const payload = payloadItems;
79
+ const payloadString = JSON.stringify(payload);
80
+ return {
81
+ method: 'POST',
82
+ url: ENDPOINT_URL,
83
+ data: payloadString,
84
+ };
85
+ },
86
+ /**
87
+ * Unpack the response from the server into a list of bids.
88
+ *
89
+ * @param {ServerResponse} serverResponse A successful response from the server.
90
+ * @return {Bid[]} An array of bids which were nested inside the server.
91
+ */
92
+ interpretResponse: function (serverResponse, bidRequest) {
93
+ const serverBody = serverResponse.body;
94
+ const bidResponses = [];
95
+ if (serverBody.mediaType == 'banner') {
96
+ const bidResponse = {
97
+ requestId: serverBody.requestId,
98
+ cpm: serverBody.cpm,
99
+ width: serverBody.width,
100
+ height: serverBody.height,
101
+ creativeId: serverBody.creativeId,
102
+ currency: serverBody.currency,
103
+ netRevenue: false,
104
+ ttl: serverBody.ttl,
105
+ ad: serverBody.ad,
106
+ mediaType: 'banner',
107
+ meta: {
108
+ mediaType: 'banner',
109
+ advertiserDomains: serverBody.advertiserDomains
110
+ }
111
+ }
112
+ bidResponses.push(bidResponse)
113
+ } else if (serverBody.mediaType == 'video') {
114
+ const bidResponse = {
115
+ requestId: serverBody.requestId,
116
+ cpm: serverBody.cpm,
117
+ width: serverBody.width,
118
+ height: serverBody.height,
119
+ creativeId: serverBody.creativeId,
120
+ currency: serverBody.currency,
121
+ netRevenue: false,
122
+ ttl: serverBody.ttl,
123
+ vastUrl: serverBody.vastUrl,
124
+ mediaType: 'video',
125
+ meta: {
126
+ mediaType: 'video',
127
+ advertiserDomains: serverBody.advertiserDomains
128
+ }
129
+ }
130
+ bidResponses.push(bidResponse)
131
+ }
132
+
133
+ return bidResponses;
134
+ },
135
+
136
+ /**
137
+ * Formats placement ids for adserver ingestion purposes
138
+ * @param {string[]} The placement ID/s in an array
139
+ */
140
+ setPlacementID: function (placementId) {
141
+ if (Array.isArray(placementId)) {
142
+ return placementId.join('#')
143
+ }
144
+ return placementId
145
+ },
146
+ }
147
+ registerBidder(spec);
@@ -0,0 +1,50 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Pilotx Prebid Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: tony@pilotx.tv
7
+ ```
8
+
9
+ # Description
10
+
11
+ Connects to Pilotx
12
+
13
+ Pilotx's bid adapter supports banner and video.
14
+
15
+ # Test Parameters
16
+ ```
17
+ // Banner adUnit
18
+ var adUnits = [{
19
+ code: 'div-gpt-ad-1460505748561-0',
20
+ mediaTypes: {
21
+ banner: {
22
+ sizes: [[300, 250], [300,600]],
23
+ }
24
+ },
25
+ bids: [{
26
+ bidder: 'pilotx',
27
+ params: {
28
+ placementId: ["1423"]
29
+ }
30
+ }]
31
+
32
+ }];
33
+
34
+ // Video adUnit
35
+ var videoAdUnit = {
36
+ code: 'video1',
37
+ mediaTypes: {
38
+ video: {
39
+ context: 'instream',
40
+ playerSize: [640, 480],
41
+ }
42
+ },
43
+ bids: [{
44
+ bidder: 'pilotx',
45
+ params: {
46
+ placementId: '1422',
47
+ }
48
+ }]
49
+ };
50
+ ```
@@ -172,8 +172,6 @@ function interpretResponse(serverResponse, bidRequest) {
172
172
 
173
173
  function _assignFloor(bid) {
174
174
  if (!isFn(bid.getFloor)) {
175
- // eslint-disable-next-line no-console
176
- console.log(bid.params.bidFloor);
177
175
  return bid.params.bidFloor ? bid.params.bidFloor : null;
178
176
  }
179
177
  const floor = bid.getFloor({
@@ -200,6 +200,21 @@ function getAdapterNameForAlias(aliasName) {
200
200
  return adapterManager.aliasRegistry[aliasName] || aliasName;
201
201
  }
202
202
 
203
+ function getAdDomain(bidResponse) {
204
+ if (bidResponse.meta && bidResponse.meta.advertiserDomains) {
205
+ let adomain = bidResponse.meta.advertiserDomains[0]
206
+ if (adomain) {
207
+ try {
208
+ let hostname = (new URL(adomain));
209
+ return hostname.hostname.replace('www.', '');
210
+ } catch (e) {
211
+ logWarn(LOG_PRE_FIX + 'Adomain URL (Not a proper URL):', adomain);
212
+ return adomain.replace('www.', '');
213
+ }
214
+ }
215
+ }
216
+ }
217
+
203
218
  function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
204
219
  highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null;
205
220
  return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) {
@@ -218,6 +233,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
218
233
  'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING,
219
234
  'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0,
220
235
  'l2': 0,
236
+ 'adv': bid.bidResponse ? getAdDomain(bid.bidResponse) || undefined : undefined,
221
237
  'ss': (s2sBidders.indexOf(bid.bidder) > -1) ? 1 : 0,
222
238
  't': (bid.status == ERROR && bid.error.code == TIMEOUT_ERROR) ? 1 : 0,
223
239
  'wb': (highestBid && highestBid.requestId === bid.bidId ? 1 : 0),
@@ -1,4 +1,4 @@
1
- import { isEmpty, deepAccess, isStr } from '../src/utils.js';
1
+ import {isEmpty, deepAccess, isStr} 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';
@@ -52,7 +52,8 @@ export const spec = {
52
52
  videoData: raiGetVideoInfo(bid),
53
53
  scr_rsl: raiGetResolution(),
54
54
  cpuc: (typeof window.navigator != 'undefined' ? window.navigator.hardwareConcurrency : null),
55
- kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null)
55
+ kws: (!isEmpty(bid.params.keywords) ? bid.params.keywords : null),
56
+ schain: bid.schain
56
57
  };
57
58
 
58
59
  REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null)
@@ -159,7 +159,7 @@ function getSupplyChain(schainObject) {
159
159
  scStr += '!';
160
160
  scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
161
161
  scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
162
- scStr += `${getEncodedValIfNotEmpty(node.hp)},`;
162
+ scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`;
163
163
  scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
164
164
  scStr += `${getEncodedValIfNotEmpty(node.name)},`;
165
165
  scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
@@ -165,16 +165,26 @@ function mapBanner(slot) {
165
165
  * @returns {object} Site by OpenRTB 2.5 §3.2.13
166
166
  */
167
167
  function mapSite(slot, bidderRequest) {
168
- const pubId = slot && slot.length > 0
169
- ? slot[0].params.publisherId
170
- : 'unknown';
171
- return {
168
+ let pubId = 'unknown';
169
+ let channel = null;
170
+ if (slot && slot.length > 0) {
171
+ pubId = slot[0].params.publisherId;
172
+ channel = slot[0].params.channel &&
173
+ slot[0].params.channel
174
+ .toString()
175
+ .slice(0, 50);
176
+ }
177
+ let siteData = {
172
178
  publisher: {
173
179
  id: pubId.toString(),
174
180
  },
175
181
  page: bidderRequest.refererInfo.referer,
176
182
  name: getOrigin()
183
+ };
184
+ if (channel) {
185
+ siteData.channel = channel;
177
186
  }
187
+ return siteData;
178
188
  }
179
189
 
180
190
  /**
@@ -152,7 +152,7 @@
152
152
 
153
153
  import {config} from '../../src/config.js';
154
154
  import {module} from '../../src/hook.js';
155
- import {logError, logWarn} from '../../src/utils.js';
155
+ import {logError, logInfo, logWarn} from '../../src/utils.js';
156
156
  import events from '../../src/events.js';
157
157
  import CONSTANTS from '../../src/constants.json';
158
158
  import {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js';
@@ -197,12 +197,13 @@ const setEventsListeners = (function () {
197
197
  return function setEventsListeners() {
198
198
  if (!registered) {
199
199
  Object.entries({
200
- [CONSTANTS.EVENTS.AUCTION_INIT]: 'onAuctionInitEvent',
201
- [CONSTANTS.EVENTS.AUCTION_END]: 'onAuctionEndEvent',
202
- [CONSTANTS.EVENTS.BID_RESPONSE]: 'onBidResponseEvent',
203
- [CONSTANTS.EVENTS.BID_REQUESTED]: 'onBidRequestEvent'
204
- }).forEach(([ev, handler]) => {
200
+ [CONSTANTS.EVENTS.AUCTION_INIT]: ['onAuctionInitEvent'],
201
+ [CONSTANTS.EVENTS.AUCTION_END]: ['onAuctionEndEvent', getAdUnitTargeting],
202
+ [CONSTANTS.EVENTS.BID_RESPONSE]: ['onBidResponseEvent'],
203
+ [CONSTANTS.EVENTS.BID_REQUESTED]: ['onBidRequestEvent']
204
+ }).forEach(([ev, [handler, preprocess]]) => {
205
205
  events.on(ev, (args) => {
206
+ preprocess && preprocess(args);
206
207
  subModules.forEach(sm => {
207
208
  try {
208
209
  sm[handler] && sm[handler](args, sm.config, _userConsent)
@@ -255,6 +256,7 @@ function initSubModules() {
255
256
  }
256
257
  });
257
258
  subModules = subModulesByOrder;
259
+ logInfo(`Real time data module enabled, using submodules: ${subModules.map((m) => m.name).join(', ')}`);
258
260
  }
259
261
 
260
262
  /**
@@ -289,18 +291,12 @@ export function setBidRequestsData(fn, reqBidsConfigObj) {
289
291
  return exitHook();
290
292
  }
291
293
 
292
- if (shouldDelayAuction) {
293
- waitTimeout = setTimeout(exitHook, _moduleConfig.auctionDelay);
294
- }
294
+ waitTimeout = setTimeout(exitHook, shouldDelayAuction ? _moduleConfig.auctionDelay : 0);
295
295
 
296
296
  relevantSubModules.forEach(sm => {
297
297
  sm.getBidRequestData(reqBidsConfigObj, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent)
298
298
  });
299
299
 
300
- if (!shouldDelayAuction) {
301
- return exitHook();
302
- }
303
-
304
300
  function onGetBidRequestDataCallback() {
305
301
  if (isDone) {
306
302
  return;
@@ -308,12 +304,15 @@ export function setBidRequestsData(fn, reqBidsConfigObj) {
308
304
  if (this.config && this.config.waitForIt) {
309
305
  callbacksExpected--;
310
306
  }
311
- if (callbacksExpected <= 0) {
312
- return exitHook();
307
+ if (callbacksExpected === 0) {
308
+ setTimeout(exitHook, 0);
313
309
  }
314
310
  }
315
311
 
316
312
  function exitHook() {
313
+ if (isDone) {
314
+ return;
315
+ }
317
316
  isDone = true;
318
317
  clearTimeout(waitTimeout);
319
318
  fn.call(this, reqBidsConfigObj);
@@ -384,8 +384,9 @@ export function parseBidResponse(bid, previousBidResponse, auctionFloorData) {
384
384
  'floorRuleValue', () => deepAccess(bid, 'floorData.floorRuleValue'),
385
385
  'floorRule', () => debugTurnedOn() ? deepAccess(bid, 'floorData.floorRule') : undefined,
386
386
  'adomains', () => {
387
- let adomains = deepAccess(bid, 'meta.advertiserDomains');
388
- return Array.isArray(adomains) && adomains.length > 0 ? adomains.slice(0, 10) : undefined
387
+ const adomains = deepAccess(bid, 'meta.advertiserDomains');
388
+ const validAdomains = Array.isArray(adomains) && adomains.filter(domain => typeof domain === 'string');
389
+ return validAdomains && validAdomains.length > 0 ? validAdomains.slice(0, 10) : undefined
389
390
  }
390
391
  ]);
391
392
  }
@@ -152,10 +152,10 @@ export const spec = {
152
152
 
153
153
  const { seatbid, cur } = serverResponse.body;
154
154
 
155
- const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => {
155
+ const bidResponses = (typeof seatbid != 'undefined') ? flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => {
156
156
  result[bid.impid - 1] = bid;
157
157
  return result;
158
- }, []);
158
+ }, []) : [];
159
159
 
160
160
  return bids
161
161
  .map((bid, id) => {
@@ -167,7 +167,7 @@ export const spec = {
167
167
  cpm: bidResponse.price,
168
168
  creativeId: bidResponse.crid,
169
169
  ttl: 1000,
170
- netRevenue: bid.netRevenue === 'net',
170
+ netRevenue: (!bid.netRevenue || bid.netRevenue === 'net'),
171
171
  currency: cur,
172
172
  mediaType: NATIVE,
173
173
  bidderCode: BIDDER_CODE,
@@ -1,10 +1,10 @@
1
- import { generateUUID, deepAccess, inIframe } from '../src/utils.js';
1
+ import { deepAccess, generateUUID, inIframe } 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';
5
5
  import { createEidsArray } from './userId/eids.js';
6
6
 
7
- const VERSION = '4.0.1';
7
+ const VERSION = '4.1.0';
8
8
  const BIDDER_CODE = 'sharethrough';
9
9
  const SUPPLY_ID = 'WYu2BXv1';
10
10
 
@@ -23,6 +23,7 @@ export const sharethroughAdapterSpec = {
23
23
 
24
24
  buildRequests: (bidRequests, bidderRequest) => {
25
25
  const timeout = config.getConfig('bidderTimeout');
26
+ const firstPartyData = config.getConfig('ortb2') || {};
26
27
 
27
28
  const nonHttp = sharethroughInternal.getProtocol().indexOf('http') < 0;
28
29
  const secure = nonHttp || (sharethroughInternal.getProtocol().indexOf('https') > -1);
@@ -35,12 +36,8 @@ export const sharethroughAdapterSpec = {
35
36
  site: {
36
37
  domain: window.location.hostname,
37
38
  page: window.location.href,
38
- ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null,
39
- },
40
- user: {
41
- ext: {
42
- eids: userIdAsEids(bidRequests[0]),
43
- },
39
+ ref: deepAccess(bidderRequest, 'refererInfo.referer'),
40
+ ...firstPartyData.site,
44
41
  },
45
42
  device: {
46
43
  ua: navigator.userAgent,
@@ -66,6 +63,10 @@ export const sharethroughAdapterSpec = {
66
63
  test: 0,
67
64
  };
68
65
 
66
+ req.user = nullish(firstPartyData.user, {});
67
+ if (!req.user.ext) req.user.ext = {};
68
+ req.user.ext.eids = userIdAsEids(bidRequests[0]);
69
+
69
70
  if (bidderRequest.gdprConsent) {
70
71
  const gdprApplies = bidderRequest.gdprConsent.gdprApplies === true;
71
72
  req.regs.ext.gdpr = gdprApplies ? 1 : 0;
@@ -86,15 +87,9 @@ export const sharethroughAdapterSpec = {
86
87
  impression.ext = { gpid: gpid };
87
88
  }
88
89
 
89
- // if request is for video, we only support instream
90
- if (bidReq.mediaTypes && bidReq.mediaTypes.video && bidReq.mediaTypes.video.context === 'outstream') {
91
- // return null so we can easily remove this imp from the array of imps that we send to adserver
92
- return null;
93
- }
94
-
95
- if (bidReq.mediaTypes && bidReq.mediaTypes.video) {
96
- const videoRequest = bidReq.mediaTypes.video;
90
+ const videoRequest = deepAccess(bidReq, 'mediaTypes.video');
97
91
 
92
+ if (videoRequest) {
98
93
  // default playerSize, only change this if we know width and height are properly defined in the request
99
94
  let [w, h] = [640, 360];
100
95
  if (videoRequest.playerSize && videoRequest.playerSize[0] && videoRequest.playerSize[1]) {
@@ -117,9 +112,9 @@ export const sharethroughAdapterSpec = {
117
112
  startdelay: nullish(videoRequest.startdelay, 0),
118
113
  skipmin: nullish(videoRequest.skipmin, 0),
119
114
  skipafter: nullish(videoRequest.skipafter, 0),
115
+ placement: videoRequest.context === 'instream' ? 1 : +deepAccess(videoRequest, 'placement', 4),
120
116
  };
121
117
 
122
- if (videoRequest.placement) impression.video.placement = videoRequest.placement;
123
118
  if (videoRequest.delivery) impression.video.delivery = videoRequest.delivery;
124
119
  if (videoRequest.companiontype) impression.video.companiontype = videoRequest.companiontype;
125
120
  if (videoRequest.companionad) impression.video.companionad = videoRequest.companionad;
@@ -61,15 +61,24 @@ export const spec = {
61
61
  }
62
62
  }
63
63
 
64
+ const consentData = bidderRequest.gdprConsent || {};
65
+
66
+ const gdprConsent = {
67
+ apiVersion: consentData.apiVersion || 2,
68
+ gdprApplies: consentData.gdprApplies || 0,
69
+ consentString: consentData.consentString || '',
70
+ }
71
+
64
72
  return {
65
73
  type: streamType,
74
+ adUnitCode: bid.adUnitCode,
66
75
  bidId: bid.bidId,
67
76
  mediaType: type,
68
77
  context: context,
69
78
  playerId: getBidIdParameter('playerId', bid.params),
70
79
  auctionId: bidderRequest.auctionId,
71
80
  bidderCode: BIDDER_CODE,
72
- gdprConsent: bidderRequest.gdprConsent,
81
+ gdprConsent: gdprConsent,
73
82
  start: +new Date(),
74
83
  timeout: 3000,
75
84
  size: {
@@ -159,6 +168,7 @@ function createBids(bidRes, reqData) {
159
168
  let bidUnit = {};
160
169
  bidUnit.cpm = bid.cpm;
161
170
  bidUnit.requestId = bid.bidId;
171
+ bidUnit.adUnitCode = reqBid.adUnitCode;
162
172
  bidUnit.currency = bid.currency;
163
173
  bidUnit.mediaType = bid.mediaType || VIDEO;
164
174
  bidUnit.ttl = TTL;
@@ -183,7 +193,8 @@ function createBids(bidRes, reqData) {
183
193
  } else if (bid.context === 'outstream') {
184
194
  const renderer = Renderer.install({
185
195
  id: bid.bidId,
186
- url: '//',
196
+ url: 'https://static.showheroes.com/renderer.js',
197
+ adUnitCode: reqBid.adUnitCode,
187
198
  config: {
188
199
  playerId: reqBid.playerId,
189
200
  width: bid.size.width,