prebid.js 6.7.0 → 6.11.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 (160) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/{haloRtdProvider_example.html → hadronRtdProvider_example.html} +9 -9
  3. package/integrationExamples/gpt/idImportLibrary_example.html +2 -2
  4. package/integrationExamples/gpt/userId_example.html +2 -2
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  6. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  7. package/modules/.submodules.json +3 -0
  8. package/modules/adagioBidAdapter.js +0 -8
  9. package/modules/adagioBidAdapter.md +1 -1
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/adnuntiusRtdProvider.js +96 -0
  12. package/modules/adnuntiusRtdProvider.md +41 -0
  13. package/modules/adotBidAdapter.js +516 -567
  14. package/modules/adotBidAdapter.md +6 -44
  15. package/modules/adpod.js +12 -14
  16. package/modules/adyoulikeBidAdapter.js +2 -0
  17. package/modules/appnexusBidAdapter.js +14 -2
  18. package/modules/asealBidAdapter.js +58 -0
  19. package/modules/asealBidAdapter.md +52 -0
  20. package/modules/brandmetricsRtdProvider.js +168 -0
  21. package/modules/brandmetricsRtdProvider.md +40 -0
  22. package/modules/conversantBidAdapter.js +7 -0
  23. package/modules/criteoBidAdapter.js +9 -0
  24. package/modules/currency.js +27 -5
  25. package/modules/displayioBidAdapter.js +157 -0
  26. package/modules/displayioBidAdapter.md +148 -0
  27. package/modules/dspxBidAdapter.js +69 -29
  28. package/modules/dspxBidAdapter.md +2 -1
  29. package/modules/e_volutionBidAdapter.js +158 -0
  30. package/modules/gridBidAdapter.js +15 -1
  31. package/modules/gumgumBidAdapter.js +52 -38
  32. package/modules/hadronIdSystem.js +96 -0
  33. package/modules/hadronIdSystem.md +35 -0
  34. package/modules/hadronRtdProvider.js +254 -0
  35. package/modules/hadronRtdProvider.md +126 -0
  36. package/modules/haloIdSystem.md +4 -35
  37. package/modules/haloRtdProvider.md +3 -126
  38. package/modules/imRtdProvider.js +10 -0
  39. package/modules/improvedigitalBidAdapter.js +5 -0
  40. package/modules/interactiveOffersBidAdapter.js +9 -6
  41. package/modules/iqzoneBidAdapter.js +10 -3
  42. package/modules/iqzoneBidAdapter.md +16 -0
  43. package/modules/ixBidAdapter.js +2 -6
  44. package/modules/kubientBidAdapter.js +50 -19
  45. package/modules/lunamediahbBidAdapter.js +32 -4
  46. package/modules/malltvBidAdapter.js +7 -3
  47. package/modules/malltvBidAdapter.md +64 -51
  48. package/modules/mass.js +3 -5
  49. package/modules/mediakeysBidAdapter.js +0 -5
  50. package/modules/medianetAnalyticsAdapter.js +1 -1
  51. package/modules/mediasquareBidAdapter.js +9 -1
  52. package/modules/nextMillenniumBidAdapter.js +1 -0
  53. package/modules/oguryBidAdapter.js +7 -14
  54. package/modules/prebidServerBidAdapter/index.js +61 -39
  55. package/modules/priceFloors.js +20 -12
  56. package/modules/pubmaticBidAdapter.js +1 -1
  57. package/modules/richaudienceBidAdapter.js +8 -3
  58. package/modules/riseBidAdapter.js +17 -6
  59. package/modules/rtbhouseBidAdapter.js +2 -0
  60. package/modules/rubiconAnalyticsAdapter.js +5 -0
  61. package/modules/rubiconBidAdapter.js +2 -2
  62. package/modules/sizeMappingV2.js +1 -8
  63. package/modules/sortableAnalyticsAdapter.js +5 -4
  64. package/modules/sovrnBidAdapter.js +93 -18
  65. package/modules/sovrnBidAdapter.md +80 -2
  66. package/modules/sspBCBidAdapter.js +53 -20
  67. package/modules/telariaBidAdapter.js +22 -29
  68. package/modules/trustpidSystem.js +197 -0
  69. package/modules/trustpidSystem.md +45 -0
  70. package/modules/undertoneBidAdapter.js +17 -1
  71. package/modules/userId/eids.js +16 -1
  72. package/modules/userId/eids.md +10 -2
  73. package/modules/userId/userId.md +17 -2
  74. package/modules/vibrantmediaBidAdapter.js +220 -0
  75. package/modules/vibrantmediaBidAdapter.md +92 -0
  76. package/modules/vidoomyBidAdapter.js +8 -0
  77. package/modules/vidoomyBidAdapter.md +4 -2
  78. package/modules/weboramaRtdProvider.js +264 -34
  79. package/modules/weboramaRtdProvider.md +110 -40
  80. package/modules/yahoosspBidAdapter.js +3 -1
  81. package/modules/yieldoneBidAdapter.js +6 -0
  82. package/package.json +2 -1
  83. package/src/adRendering.js +38 -0
  84. package/src/adapterManager.js +24 -19
  85. package/src/adapters/bidderFactory.js +14 -11
  86. package/src/adloader.js +2 -1
  87. package/src/auction.js +138 -115
  88. package/src/auctionIndex.js +85 -0
  89. package/src/auctionManager.js +3 -0
  90. package/src/bidderSettings.js +69 -0
  91. package/src/bidfactory.js +18 -6
  92. package/src/native.js +29 -21
  93. package/src/prebid.js +3 -19
  94. package/src/secureCreatives.js +128 -45
  95. package/src/targeting.js +11 -2
  96. package/src/utils.js +14 -17
  97. package/src/video.js +10 -11
  98. package/src/videoCache.js +10 -9
  99. package/test/fixtures/fixtures.js +2 -1
  100. package/test/helpers/indexStub.js +28 -0
  101. package/test/helpers/syncPromise.js +71 -0
  102. package/test/spec/auctionmanager_spec.js +268 -89
  103. package/test/spec/config_spec.js +24 -1
  104. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  105. package/test/spec/modules/adnuntiusRtdProvider_spec.js +145 -0
  106. package/test/spec/modules/adotBidAdapter_spec.js +294 -3124
  107. package/test/spec/modules/adpod_spec.js +91 -156
  108. package/test/spec/modules/adyoulikeBidAdapter_spec.js +4 -0
  109. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  110. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  111. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  112. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  113. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  114. package/test/spec/modules/currency_spec.js +36 -15
  115. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  116. package/test/spec/modules/dspxBidAdapter_spec.js +20 -15
  117. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  118. package/test/spec/modules/eids_spec.js +2 -2
  119. package/test/spec/modules/gridBidAdapter_spec.js +18 -0
  120. package/test/spec/modules/gumgumBidAdapter_spec.js +49 -3
  121. package/test/spec/modules/hadronIdSystem_spec.js +57 -0
  122. package/test/spec/modules/hadronRtdProvider_spec.js +762 -0
  123. package/test/spec/modules/imRtdProvider_spec.js +30 -1
  124. package/test/spec/modules/improvedigitalBidAdapter_spec.js +19 -0
  125. package/test/spec/modules/iqzoneBidAdapter_spec.js +1 -0
  126. package/test/spec/modules/ixBidAdapter_spec.js +1 -1
  127. package/test/spec/modules/kubientBidAdapter_spec.js +182 -84
  128. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  129. package/test/spec/modules/mass_spec.js +2 -14
  130. package/test/spec/modules/mediakeysBidAdapter_spec.js +9 -5
  131. package/test/spec/modules/mediasquareBidAdapter_spec.js +25 -1
  132. package/test/spec/modules/oguryBidAdapter_spec.js +63 -5
  133. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -6
  134. package/test/spec/modules/priceFloors_spec.js +83 -24
  135. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  136. package/test/spec/modules/riseBidAdapter_spec.js +30 -4
  137. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +31 -1
  138. package/test/spec/modules/rubiconBidAdapter_spec.js +1 -1
  139. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  140. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  141. package/test/spec/modules/sspBCBidAdapter_spec.js +7 -7
  142. package/test/spec/modules/telariaBidAdapter_spec.js +1 -3
  143. package/test/spec/modules/trustpidSystem_spec.js +232 -0
  144. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  145. package/test/spec/modules/userId_spec.js +39 -39
  146. package/test/spec/modules/vibrantmediaBidAdapter_spec.js +1237 -0
  147. package/test/spec/modules/vidoomyBidAdapter_spec.js +7 -1
  148. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  149. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  150. package/test/spec/modules/yieldoneBidAdapter_spec.js +33 -0
  151. package/test/spec/native_spec.js +62 -40
  152. package/test/spec/unit/core/adapterManager_spec.js +22 -0
  153. package/test/spec/unit/core/auctionIndex_spec.js +129 -0
  154. package/test/spec/unit/core/bidderFactory_spec.js +65 -12
  155. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  156. package/test/spec/unit/core/targeting_spec.js +93 -0
  157. package/test/spec/unit/pbjs_api_spec.js +80 -42
  158. package/test/spec/unit/secureCreatives_spec.js +143 -24
  159. package/test/spec/videoCache_spec.js +18 -19
  160. package/test/spec/video_spec.js +51 -61
package/src/bidfactory.js CHANGED
@@ -14,16 +14,18 @@ import { getUniqueIdentifierStr } from './utils.js';
14
14
  dealId,
15
15
  priceKeyString;
16
16
  */
17
- function Bid(statusCode, bidRequest) {
18
- var _bidSrc = (bidRequest && bidRequest.src) || 'client';
17
+ function Bid(statusCode, {src = 'client', bidder = '', bidId, transactionId, auctionId} = {}) {
18
+ var _bidSrc = src;
19
19
  var _statusCode = statusCode || 0;
20
20
 
21
- this.bidderCode = (bidRequest && bidRequest.bidder) || '';
21
+ this.bidderCode = bidder;
22
22
  this.width = 0;
23
23
  this.height = 0;
24
24
  this.statusMessage = _getStatus();
25
25
  this.adId = getUniqueIdentifierStr();
26
- this.requestId = bidRequest && bidRequest.bidId;
26
+ this.requestId = bidId;
27
+ this.transactionId = transactionId;
28
+ this.auctionId = auctionId;
27
29
  this.mediaType = 'banner';
28
30
  this.source = _bidSrc;
29
31
 
@@ -48,9 +50,19 @@ function Bid(statusCode, bidRequest) {
48
50
  this.getSize = function () {
49
51
  return this.width + 'x' + this.height;
50
52
  };
53
+
54
+ this.getIdentifiers = function () {
55
+ return {
56
+ src: this.source,
57
+ bidder: this.bidderCode,
58
+ bidId: this.requestId,
59
+ transactionId: this.transactionId,
60
+ auctionId: this.auctionId
61
+ }
62
+ }
51
63
  }
52
64
 
53
65
  // Bid factory function.
54
- export function createBid(statusCode, bidRequest) {
55
- return new Bid(statusCode, bidRequest);
66
+ export function createBid(statusCode, identifiers) {
67
+ return new Bid(statusCode, identifiers);
56
68
  }
package/src/native.js CHANGED
@@ -1,5 +1,6 @@
1
- import { deepAccess, getBidRequest, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils.js';
1
+ import { deepAccess, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils.js';
2
2
  import includes from 'core-js-pure/features/array/includes.js';
3
+ import {auctionManager} from './auctionManager.js';
3
4
 
4
5
  const CONSTANTS = require('./constants.json');
5
6
 
@@ -35,6 +36,16 @@ export function processNativeAdUnitParams(params) {
35
36
  return params;
36
37
  }
37
38
 
39
+ export function decorateAdUnitsWithNativeParams(adUnits) {
40
+ adUnits.forEach(adUnit => {
41
+ const nativeParams =
42
+ adUnit.nativeParams || deepAccess(adUnit, 'mediaTypes.native');
43
+ if (nativeParams) {
44
+ adUnit.nativeParams = processNativeAdUnitParams(nativeParams);
45
+ }
46
+ });
47
+ }
48
+
38
49
  /**
39
50
  * Check if the native type specified in the adUnit is supported by Prebid.
40
51
  */
@@ -68,16 +79,13 @@ export const hasNonNativeBidder = adUnit =>
68
79
  * @param {BidRequest[]} bidRequests All bid requests for an auction
69
80
  * @return {Boolean} If object is valid
70
81
  */
71
- export function nativeBidIsValid(bid, bidRequests) {
72
- const bidRequest = getBidRequest(bid.requestId, bidRequests);
73
- if (!bidRequest) { return false; }
74
-
82
+ export function nativeBidIsValid(bid, {index = auctionManager.index} = {}) {
75
83
  // all native bid responses must define a landing page url
76
84
  if (!deepAccess(bid, 'native.clickUrl')) {
77
85
  return false;
78
86
  }
79
87
 
80
- const requestedAssets = bidRequest.nativeParams;
88
+ const requestedAssets = index.getAdUnit(bid).nativeParams;
81
89
  if (!requestedAssets) {
82
90
  return true;
83
91
  }
@@ -139,21 +147,21 @@ export function fireNativeTrackers(message, adObject) {
139
147
  * @param {Object} bid
140
148
  * @return {Object} targeting
141
149
  */
142
- export function getNativeTargeting(bid, bidReq) {
150
+ export function getNativeTargeting(bid, {index = auctionManager.index} = {}) {
143
151
  let keyValues = {};
144
-
145
- if (deepAccess(bidReq, 'nativeParams.rendererUrl')) {
146
- bid['native']['rendererUrl'] = getAssetValue(bidReq.nativeParams['rendererUrl']);
147
- } else if (deepAccess(bidReq, 'nativeParams.adTemplate')) {
148
- bid['native']['adTemplate'] = getAssetValue(bidReq.nativeParams['adTemplate']);
152
+ const adUnit = index.getAdUnit(bid);
153
+ if (deepAccess(adUnit, 'nativeParams.rendererUrl')) {
154
+ bid['native']['rendererUrl'] = getAssetValue(adUnit.nativeParams['rendererUrl']);
155
+ } else if (deepAccess(adUnit, 'nativeParams.adTemplate')) {
156
+ bid['native']['adTemplate'] = getAssetValue(adUnit.nativeParams['adTemplate']);
149
157
  }
150
158
 
151
159
  const globalSendTargetingKeys = deepAccess(
152
- bidReq,
160
+ adUnit,
153
161
  `nativeParams.sendTargetingKeys`
154
162
  ) !== false;
155
163
 
156
- const nativeKeys = getNativeKeys(bidReq);
164
+ const nativeKeys = getNativeKeys(adUnit);
157
165
 
158
166
  const flatBidNativeKeys = { ...bid.native, ...bid.native.ext };
159
167
  delete flatBidNativeKeys.ext;
@@ -166,9 +174,9 @@ export function getNativeTargeting(bid, bidReq) {
166
174
  return;
167
175
  }
168
176
 
169
- let sendPlaceholder = deepAccess(bidReq, `nativeParams.${asset}.sendId`);
177
+ let sendPlaceholder = deepAccess(adUnit, `nativeParams.${asset}.sendId`);
170
178
  if (typeof sendPlaceholder !== 'boolean') {
171
- sendPlaceholder = deepAccess(bidReq, `nativeParams.ext.${asset}.sendId`);
179
+ sendPlaceholder = deepAccess(adUnit, `nativeParams.ext.${asset}.sendId`);
172
180
  }
173
181
 
174
182
  if (sendPlaceholder) {
@@ -176,9 +184,9 @@ export function getNativeTargeting(bid, bidReq) {
176
184
  value = placeholder;
177
185
  }
178
186
 
179
- let assetSendTargetingKeys = deepAccess(bidReq, `nativeParams.${asset}.sendTargetingKeys`)
187
+ let assetSendTargetingKeys = deepAccess(adUnit, `nativeParams.${asset}.sendTargetingKeys`)
180
188
  if (typeof assetSendTargetingKeys !== 'boolean') {
181
- assetSendTargetingKeys = deepAccess(bidReq, `nativeParams.ext.${asset}.sendTargetingKeys`);
189
+ assetSendTargetingKeys = deepAccess(adUnit, `nativeParams.ext.${asset}.sendTargetingKeys`);
182
190
  }
183
191
 
184
192
  const sendTargeting = typeof assetSendTargetingKeys === 'boolean' ? assetSendTargetingKeys : globalSendTargetingKeys;
@@ -259,11 +267,11 @@ function getAssetValue(value) {
259
267
  return value;
260
268
  }
261
269
 
262
- function getNativeKeys(bidReq) {
270
+ function getNativeKeys(adUnit) {
263
271
  const extraNativeKeys = {}
264
272
 
265
- if (deepAccess(bidReq, 'nativeParams.ext')) {
266
- Object.keys(bidReq.nativeParams.ext).forEach(extKey => {
273
+ if (deepAccess(adUnit, 'nativeParams.ext')) {
274
+ Object.keys(adUnit.nativeParams.ext).forEach(extKey => {
267
275
  extraNativeKeys[extKey] = `hb_native_${extKey}`;
268
276
  })
269
277
  }
package/src/prebid.js CHANGED
@@ -19,6 +19,7 @@ import { adunitCounter } from './adUnits.js';
19
19
  import { executeRenderer, isRendererRequired } from './Renderer.js';
20
20
  import { createBid } from './bidfactory.js';
21
21
  import { storageCallbacks } from './storageManager.js';
22
+ import { emitAdRenderSucceeded, emitAdRenderFail } from './adRendering.js';
22
23
 
23
24
  const $$PREBID_GLOBAL$$ = getGlobal();
24
25
  const CONSTANTS = require('./constants.json');
@@ -27,7 +28,7 @@ const events = require('./events.js');
27
28
  const { triggerUserSyncs } = userSync;
28
29
 
29
30
  /* private variables */
30
- const { ADD_AD_UNITS, BID_WON, REQUEST_BIDS, SET_TARGETING, AD_RENDER_FAILED, AD_RENDER_SUCCEEDED, STALE_RENDER } = CONSTANTS.EVENTS;
31
+ const { ADD_AD_UNITS, BID_WON, REQUEST_BIDS, SET_TARGETING, STALE_RENDER } = CONSTANTS.EVENTS;
31
32
  const { PREVENT_WRITING_ON_MAIN_DOCUMENT, NO_AD, EXCEPTION, CANNOT_FIND_AD, MISSING_DOC_OR_ADID } = CONSTANTS.AD_RENDER_FAILED_REASON;
32
33
 
33
34
  const eventValidators = {
@@ -146,7 +147,7 @@ function validateNativeMediaType(adUnit) {
146
147
  function validateAdUnitPos(adUnit, mediaType) {
147
148
  let pos = deepAccess(adUnit, `mediaTypes.${mediaType}.pos`);
148
149
 
149
- if (!pos || !isNumber(pos) || !isFinite(pos)) {
150
+ if (!isNumber(pos) || isNaN(pos) || !isFinite(pos)) {
150
151
  let warning = `Value of property 'pos' on ad unit ${adUnit.code} should be of type: Number`;
151
152
 
152
153
  logWarn(warning);
@@ -385,23 +386,6 @@ $$PREBID_GLOBAL$$.setTargetingForAst = function (adUnitCodes) {
385
386
  events.emit(SET_TARGETING, targeting.getAllTargeting());
386
387
  };
387
388
 
388
- function emitAdRenderFail({ reason, message, bid, id }) {
389
- const data = { reason, message };
390
- if (bid) data.bid = bid;
391
- if (id) data.adId = id;
392
-
393
- logError(message);
394
- events.emit(AD_RENDER_FAILED, data);
395
- }
396
-
397
- function emitAdRenderSucceeded({ doc, bid, id }) {
398
- const data = { doc };
399
- if (bid) data.bid = bid;
400
- if (id) data.adId = id;
401
-
402
- events.emit(AD_RENDER_SUCCEEDED, data);
403
- }
404
-
405
389
  /**
406
390
  * This function will check for presence of given node in given parent. If not present - will inject it.
407
391
  * @param {Node} node node, whose existance is in question
@@ -4,22 +4,47 @@
4
4
  */
5
5
 
6
6
  import events from './events.js';
7
- import { fireNativeTrackers, getAssetMessage, getAllAssetsMessage } from './native.js';
7
+ import {fireNativeTrackers, getAllAssetsMessage, getAssetMessage} from './native.js';
8
8
  import constants from './constants.json';
9
- import { logWarn, replaceAuctionPrice, deepAccess, isGptPubadsDefined, isApnGetTagDefined } from './utils.js';
10
- import { auctionManager } from './auctionManager.js';
9
+ import {deepAccess, isApnGetTagDefined, isGptPubadsDefined, logError, logWarn, replaceAuctionPrice} from './utils.js';
10
+ import {auctionManager} from './auctionManager.js';
11
11
  import find from 'core-js-pure/features/array/find.js';
12
- import { isRendererRequired, executeRenderer } from './Renderer.js';
12
+ import {executeRenderer, isRendererRequired} from './Renderer.js';
13
13
  import includes from 'core-js-pure/features/array/includes.js';
14
- import { config } from './config.js';
14
+ import {config} from './config.js';
15
+ import {emitAdRenderFail, emitAdRenderSucceeded} from './adRendering.js';
15
16
 
16
17
  const BID_WON = constants.EVENTS.BID_WON;
17
18
  const STALE_RENDER = constants.EVENTS.STALE_RENDER;
18
19
 
20
+ const HANDLER_MAP = {
21
+ 'Prebid Request': handleRenderRequest,
22
+ 'Prebid Native': handleNativeRequest,
23
+ 'Prebid Event': handleEventRequest,
24
+ }
25
+
19
26
  export function listenMessagesFromCreative() {
20
27
  window.addEventListener('message', receiveMessage, false);
21
28
  }
22
29
 
30
+ export function getReplier(ev) {
31
+ if (ev.origin == null && ev.ports.length === 0) {
32
+ return function () {
33
+ const msg = 'Cannot post message to a frame with null origin. Please update creatives to use MessageChannel, see https://github.com/prebid/Prebid.js/issues/7870'
34
+ logError(msg)
35
+ throw new Error(msg);
36
+ }
37
+ } else if (ev.ports.length > 0) {
38
+ return function (message) {
39
+ ev.ports[0].postMessage(JSON.stringify(message));
40
+ }
41
+ } else {
42
+ return function (message) {
43
+ ev.source.postMessage(JSON.stringify(message), ev.origin);
44
+ }
45
+ }
46
+ }
47
+
23
48
  export function receiveMessage(ev) {
24
49
  var key = ev.message ? 'message' : 'data';
25
50
  var data = {};
@@ -29,70 +54,128 @@ export function receiveMessage(ev) {
29
54
  return;
30
55
  }
31
56
 
32
- if (data && data.adId) {
57
+ if (data && data.adId && data.message) {
33
58
  const adObject = find(auctionManager.getBidsReceived(), function (bid) {
34
59
  return bid.adId === data.adId;
35
60
  });
61
+ if (HANDLER_MAP.hasOwnProperty(data.message)) {
62
+ HANDLER_MAP[data.message](getReplier(ev), data, adObject);
63
+ }
64
+ }
65
+ }
36
66
 
37
- if (adObject && data.message === 'Prebid Request') {
38
- if (adObject.status === constants.BID_STATUS.RENDERED) {
39
- logWarn(`Ad id ${adObject.adId} has been rendered before`);
40
- events.emit(STALE_RENDER, adObject);
41
- if (deepAccess(config.getConfig('auctionOptions'), 'suppressStaleRender')) {
42
- return;
43
- }
44
- }
67
+ function handleRenderRequest(reply, data, adObject) {
68
+ if (adObject == null) {
69
+ emitAdRenderFail({
70
+ reason: constants.AD_RENDER_FAILED_REASON.CANNOT_FIND_AD,
71
+ message: `Cannot find ad '${data.adId}' for cross-origin render request`,
72
+ id: data.adId
73
+ });
74
+ return;
75
+ }
76
+ if (adObject.status === constants.BID_STATUS.RENDERED) {
77
+ logWarn(`Ad id ${adObject.adId} has been rendered before`);
78
+ events.emit(STALE_RENDER, adObject);
79
+ if (deepAccess(config.getConfig('auctionOptions'), 'suppressStaleRender')) {
80
+ return;
81
+ }
82
+ }
45
83
 
46
- _sendAdToCreative(adObject, ev);
84
+ try {
85
+ _sendAdToCreative(adObject, reply);
86
+ } catch (e) {
87
+ emitAdRenderFail({
88
+ reason: constants.AD_RENDER_FAILED_REASON.EXCEPTION,
89
+ message: e.message,
90
+ id: data.adId,
91
+ bid: adObject
92
+ });
93
+ return;
94
+ }
47
95
 
48
- // save winning bids
49
- auctionManager.addWinningBid(adObject);
96
+ // save winning bids
97
+ auctionManager.addWinningBid(adObject);
50
98
 
51
- events.emit(BID_WON, adObject);
52
- }
99
+ events.emit(BID_WON, adObject);
100
+ }
53
101
 
54
- // handle this script from native template in an ad server
55
- // window.parent.postMessage(JSON.stringify({
56
- // message: 'Prebid Native',
57
- // adId: '%%PATTERN:hb_adid%%'
58
- // }), '*');
59
- if (adObject && data.message === 'Prebid Native') {
60
- if (data.action === 'assetRequest') {
61
- const message = getAssetMessage(data, adObject);
62
- ev.source.postMessage(JSON.stringify(message), ev.origin);
63
- } else if (data.action === 'allAssetRequest') {
64
- const message = getAllAssetsMessage(data, adObject);
65
- ev.source.postMessage(JSON.stringify(message), ev.origin);
66
- } else if (data.action === 'resizeNativeHeight') {
67
- adObject.height = data.height;
68
- adObject.width = data.width;
69
- resizeRemoteCreative(adObject);
70
- } else {
71
- const trackerType = fireNativeTrackers(data, adObject);
72
- if (trackerType === 'click') { return; }
73
-
74
- auctionManager.addWinningBid(adObject);
75
- events.emit(BID_WON, adObject);
102
+ function handleNativeRequest(reply, data, adObject) {
103
+ // handle this script from native template in an ad server
104
+ // window.parent.postMessage(JSON.stringify({
105
+ // message: 'Prebid Native',
106
+ // adId: '%%PATTERN:hb_adid%%'
107
+ // }), '*');
108
+ if (adObject == null) {
109
+ logError(`Cannot find ad '${data.adId}' for x-origin event request`);
110
+ return;
111
+ }
112
+ switch (data.action) {
113
+ case 'assetRequest':
114
+ reply(getAssetMessage(data, adObject));
115
+ break;
116
+ case 'allAssetRequest':
117
+ reply(getAllAssetsMessage(data, adObject));
118
+ break;
119
+ case 'resizeNativeHeight':
120
+ adObject.height = data.height;
121
+ adObject.width = data.width;
122
+ resizeRemoteCreative(adObject);
123
+ break;
124
+ default:
125
+ const trackerType = fireNativeTrackers(data, adObject);
126
+ if (trackerType === 'click') {
127
+ return;
76
128
  }
77
- }
129
+ auctionManager.addWinningBid(adObject);
130
+ events.emit(BID_WON, adObject);
78
131
  }
79
132
  }
80
133
 
81
- export function _sendAdToCreative(adObject, ev) {
134
+ function handleEventRequest(reply, data, adObject) {
135
+ if (adObject == null) {
136
+ logError(`Cannot find ad '${data.adId}' for x-origin event request`);
137
+ return;
138
+ }
139
+ if (adObject.status !== constants.BID_STATUS.RENDERED) {
140
+ logWarn(`Received x-origin event request without corresponding render request for ad '${data.adId}'`);
141
+ return;
142
+ }
143
+ switch (data.event) {
144
+ case constants.EVENTS.AD_RENDER_FAILED:
145
+ emitAdRenderFail({
146
+ bid: adObject,
147
+ id: data.adId,
148
+ reason: data.info.reason,
149
+ message: data.info.message
150
+ });
151
+ break;
152
+ case constants.EVENTS.AD_RENDER_SUCCEEDED:
153
+ emitAdRenderSucceeded({
154
+ doc: null,
155
+ bid: adObject,
156
+ id: data.adId
157
+ });
158
+ break;
159
+ default:
160
+ logError(`Received x-origin event request for unsupported event: '${data.event}' (adId: '${data.adId}')`)
161
+ }
162
+ }
163
+
164
+ export function _sendAdToCreative(adObject, reply) {
82
165
  const { adId, ad, adUrl, width, height, renderer, cpm } = adObject;
83
166
  // rendering for outstream safeframe
84
167
  if (isRendererRequired(renderer)) {
85
168
  executeRenderer(renderer, adObject);
86
169
  } else if (adId) {
87
170
  resizeRemoteCreative(adObject);
88
- ev.source.postMessage(JSON.stringify({
171
+ reply({
89
172
  message: 'Prebid Response',
90
173
  ad: replaceAuctionPrice(ad, cpm),
91
174
  adUrl: replaceAuctionPrice(adUrl, cpm),
92
175
  adId,
93
176
  width,
94
177
  height
95
- }), ev.origin);
178
+ });
96
179
  }
97
180
  }
98
181
 
package/src/targeting.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp,
3
- deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr, isAllowZeroCpmBidsEnabled
3
+ deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr,
4
4
  } from './utils.js';
5
5
  import { config } from './config.js';
6
6
  import { NATIVE_TARGETING_KEYS } from './native.js';
@@ -8,6 +8,7 @@ import { auctionManager } from './auctionManager.js';
8
8
  import { sizeSupported } from './sizeMapping.js';
9
9
  import { ADPOD } from './mediaTypes.js';
10
10
  import { hook } from './hook.js';
11
+ import { bidderSettings } from './bidderSettings.js';
11
12
  import includes from 'core-js-pure/features/array/includes.js';
12
13
  import find from 'core-js-pure/features/array/find.js';
13
14
 
@@ -437,7 +438,15 @@ export function newTargeting(auctionManager) {
437
438
  let bidsReceived = auctionManager.getBidsReceived();
438
439
 
439
440
  if (!config.getConfig('useBidCache')) {
441
+ // don't use bid cache (i.e. filter out bids not in the latest auction)
440
442
  bidsReceived = bidsReceived.filter(bid => latestAuctionForAdUnit[bid.adUnitCode] === bid.auctionId)
443
+ } else {
444
+ // if custom bid cache filter function exists, run for each bid from
445
+ // previous auctions. If it returns true, include bid in bid pool
446
+ const filterFunction = config.getConfig('bidCacheFilterFunction');
447
+ if (typeof filterFunction === 'function') {
448
+ bidsReceived = bidsReceived.filter(bid => latestAuctionForAdUnit[bid.adUnitCode] === bid.auctionId || !!filterFunction(bid))
449
+ }
441
450
  }
442
451
 
443
452
  bidsReceived = bidsReceived
@@ -459,7 +468,7 @@ export function newTargeting(auctionManager) {
459
468
  const adUnitCodes = getAdUnitCodes(adUnitCode);
460
469
  return bidsReceived
461
470
  .filter(bid => includes(adUnitCodes, bid.adUnitCode))
462
- .filter(bid => (isAllowZeroCpmBidsEnabled(bid.bidderCode)) ? bid.cpm >= 0 : bid.cpm > 0)
471
+ .filter(bid => (bidderSettings.get(bid.bidderCode, 'allowZeroCpmBids') === true) ? bid.cpm >= 0 : bid.cpm > 0)
463
472
  .map(bid => bid.adUnitCode)
464
473
  .filter(uniques)
465
474
  .map(adUnitCode => bidsReceived
package/src/utils.js CHANGED
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable no-console */
2
2
  import { config } from './config.js';
3
- import { getGlobal } from './prebidGlobal.js';
4
3
  import clone from 'just-clone';
5
4
  import find from 'core-js-pure/features/array/find.js';
6
5
  import includes from 'core-js-pure/features/array/includes.js';
@@ -22,7 +21,17 @@ let consoleLogExists = Boolean(consoleExists && window.console.log);
22
21
  let consoleInfoExists = Boolean(consoleExists && window.console.info);
23
22
  let consoleWarnExists = Boolean(consoleExists && window.console.warn);
24
23
  let consoleErrorExists = Boolean(consoleExists && window.console.error);
25
- var events = require('./events.js');
24
+
25
+ const emitEvent = (function () {
26
+ // lazy load events to avoid circular import
27
+ let ev;
28
+ return function() {
29
+ if (ev == null) {
30
+ ev = require('./events.js');
31
+ }
32
+ return ev.emit.apply(ev, arguments);
33
+ }
34
+ })();
26
35
 
27
36
  // this allows stubbing of utility functions that are used internally by other utility functions
28
37
  export const internal = {
@@ -265,14 +274,14 @@ export function logWarn() {
265
274
  if (debugTurnedOn() && consoleWarnExists) {
266
275
  console.warn.apply(console, decorateLog(arguments, 'WARNING:'));
267
276
  }
268
- events.emit(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'WARNING', arguments: arguments});
277
+ emitEvent(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'WARNING', arguments: arguments});
269
278
  }
270
279
 
271
280
  export function logError() {
272
281
  if (debugTurnedOn() && consoleErrorExists) {
273
282
  console.error.apply(console, decorateLog(arguments, 'ERROR:'));
274
283
  }
275
- events.emit(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'ERROR', arguments: arguments});
284
+ emitEvent(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'ERROR', arguments: arguments});
276
285
  }
277
286
 
278
287
  function decorateLog(args, prefix) {
@@ -885,12 +894,6 @@ export function isValidMediaTypes(mediaTypes) {
885
894
  return true;
886
895
  }
887
896
 
888
- export function getBidderRequest(bidRequests, bidder, adUnitCode) {
889
- return find(bidRequests, request => {
890
- return request.bids
891
- .filter(bid => bid.bidder === bidder && bid.adUnitCode === adUnitCode).length > 0;
892
- }) || { start: null, auctionId: null };
893
- }
894
897
  /**
895
898
  * Returns user configured bidder params from adunit
896
899
  * @param {Object} adUnits
@@ -1270,7 +1273,7 @@ export function mergeDeep(target, ...sources) {
1270
1273
  mergeDeep(target[key], source[key]);
1271
1274
  } else if (isArray(source[key])) {
1272
1275
  if (!target[key]) {
1273
- Object.assign(target, { [key]: source[key] });
1276
+ Object.assign(target, { [key]: [...source[key]] });
1274
1277
  } else if (isArray(target[key])) {
1275
1278
  source[key].forEach(obj => {
1276
1279
  let addItFlag = 1;
@@ -1333,9 +1336,3 @@ export function cyrb53Hash(str, seed = 0) {
1333
1336
  h2 = imul(h2 ^ (h2 >>> 16), 2246822507) ^ imul(h1 ^ (h1 >>> 13), 3266489909);
1334
1337
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
1335
1338
  }
1336
-
1337
- export function isAllowZeroCpmBidsEnabled(bidderCode) {
1338
- const bidderSettings = getGlobal().bidderSettings;
1339
- return ((bidderSettings[bidderCode] && bidderSettings[bidderCode].allowZeroCpmBids === true) ||
1340
- (bidderSettings.standard && bidderSettings.standard.allowZeroCpmBids === true));
1341
- }
package/src/video.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import adapterManager from './adapterManager.js';
2
- import { getBidRequest, deepAccess, logError } from './utils.js';
2
+ import { deepAccess, logError } from './utils.js';
3
3
  import { config } from '../src/config.js';
4
4
  import includes from 'core-js-pure/features/array/includes.js';
5
5
  import { hook } from './hook.js';
6
+ import {auctionManager} from './auctionManager.js';
6
7
 
7
8
  const VIDEO_MEDIA_TYPE = 'video';
8
9
  export const OUTSTREAM = 'outstream';
@@ -28,23 +29,21 @@ export const hasNonVideoBidder = adUnit =>
28
29
  /**
29
30
  * Validate that the assets required for video context are present on the bid
30
31
  * @param {VideoBid} bid Video bid to validate
31
- * @param {BidRequest[]} bidRequests All bid requests for an auction
32
+ * @param index
32
33
  * @return {Boolean} If object is valid
33
34
  */
34
- export function isValidVideoBid(bid, bidRequests) {
35
- const bidRequest = getBidRequest(bid.requestId, bidRequests);
36
-
37
- const videoMediaType =
38
- bidRequest && deepAccess(bidRequest, 'mediaTypes.video');
35
+ export function isValidVideoBid(bid, {index = auctionManager.index} = {}) {
36
+ const videoMediaType = deepAccess(index.getMediaTypes(bid), 'video');
39
37
  const context = videoMediaType && deepAccess(videoMediaType, 'context');
38
+ const adUnit = index.getAdUnit(bid);
40
39
 
41
40
  // if context not defined assume default 'instream' for video bids
42
41
  // instream bids require a vast url or vast xml content
43
- return checkVideoBidSetup(bid, bidRequest, videoMediaType, context);
42
+ return checkVideoBidSetup(bid, adUnit, videoMediaType, context);
44
43
  }
45
44
 
46
- export const checkVideoBidSetup = hook('sync', function(bid, bidRequest, videoMediaType, context) {
47
- if (!bidRequest || (videoMediaType && context !== OUTSTREAM)) {
45
+ export const checkVideoBidSetup = hook('sync', function(bid, adUnit, videoMediaType, context) {
46
+ if (videoMediaType && context !== OUTSTREAM) {
48
47
  // xml-only video bids require a prebid cache url
49
48
  if (!config.getConfig('cache.url') && bid.vastXml && !bid.vastUrl) {
50
49
  logError(`
@@ -59,7 +58,7 @@ export const checkVideoBidSetup = hook('sync', function(bid, bidRequest, videoMe
59
58
 
60
59
  // outstream bids require a renderer on the bid or pub-defined on adunit
61
60
  if (context === OUTSTREAM) {
62
- return !!(bid.renderer || bidRequest.renderer || videoMediaType.renderer);
61
+ return !!(bid.renderer || (adUnit && adUnit.renderer) || videoMediaType.renderer);
63
62
  }
64
63
 
65
64
  return true;
package/src/videoCache.js CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { ajax } from './ajax.js';
13
13
  import { config } from './config.js';
14
- import { isPlainObject } from './utils.js';
14
+ import {auctionManager} from './auctionManager.js';
15
15
 
16
16
  /**
17
17
  * @typedef {object} CacheableUrlBid
@@ -58,9 +58,11 @@ function wrapURI(uri, impUrl) {
58
58
  * the bid can't be converted cleanly.
59
59
  *
60
60
  * @param {CacheableBid} bid
61
+ * @param index
61
62
  */
62
- function toStorageRequest(bid) {
63
+ function toStorageRequest(bid, {index = auctionManager.index} = {}) {
63
64
  const vastValue = bid.vastXml ? bid.vastXml : wrapURI(bid.vastUrl, bid.vastImpUrl);
65
+ const auction = index.getAuction(bid);
64
66
 
65
67
  let payload = {
66
68
  type: 'xml',
@@ -72,10 +74,10 @@ function toStorageRequest(bid) {
72
74
  payload.bidder = bid.bidder;
73
75
  payload.bidid = bid.requestId;
74
76
  payload.aid = bid.auctionId;
75
- // function has a thisArg set to bidderRequest for accessing the auctionStart
76
- if (isPlainObject(this) && this.hasOwnProperty('auctionStart')) {
77
- payload.timestamp = this.auctionStart;
78
- }
77
+ }
78
+
79
+ if (auction != null) {
80
+ payload.timestamp = auction.getAuctionStart();
79
81
  }
80
82
 
81
83
  if (typeof bid.customCacheKey === 'string' && bid.customCacheKey !== '') {
@@ -132,12 +134,11 @@ function shimStorageCallback(done) {
132
134
  *
133
135
  * @param {CacheableBid[]} bids A list of bid objects which should be cached.
134
136
  * @param {videoCacheStoreCallback} [done] An optional callback which should be executed after
135
- * @param {BidderRequest} [bidderRequest]
136
137
  * the data has been stored in the cache.
137
138
  */
138
- export function store(bids, done, bidderRequest) {
139
+ export function store(bids, done) {
139
140
  const requestData = {
140
- puts: bids.map(toStorageRequest, bidderRequest)
141
+ puts: bids.map(toStorageRequest)
141
142
  };
142
143
 
143
144
  ajax(config.getConfig('cache.url'), shimStorageCallback(done), JSON.stringify(requestData), {
@@ -1231,7 +1231,7 @@ export function getCurrencyRates() {
1231
1231
  };
1232
1232
  }
1233
1233
 
1234
- export function createBidReceived({bidder, cpm, auctionId, responseTimestamp, adUnitCode, adId, status, ttl, requestId}) {
1234
+ export function createBidReceived({bidder, cpm, auctionId, responseTimestamp, adUnitCode, adId, status, ttl, requestId, mediaType}) {
1235
1235
  let bid = {
1236
1236
  'bidderCode': bidder,
1237
1237
  'width': '300',
@@ -1259,6 +1259,7 @@ export function createBidReceived({bidder, cpm, auctionId, responseTimestamp, ad
1259
1259
  'hb_pb': cpm,
1260
1260
  'foobar': '300x250'
1261
1261
  }),
1262
+ 'mediaType': mediaType,
1262
1263
  'netRevenue': true,
1263
1264
  'currency': 'USD',
1264
1265
  'ttl': (!ttl) ? 300 : ttl