prebid.js 6.2.0 → 6.6.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 (169) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/gulpfile.js +87 -82
  3. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  4. package/karma.conf.maker.js +1 -1
  5. package/modules/.submodules.json +2 -1
  6. package/modules/33acrossBidAdapter.js +189 -102
  7. package/modules/adagioBidAdapter.js +1 -1
  8. package/modules/addefendBidAdapter.js +1 -0
  9. package/modules/adkernelBidAdapter.js +148 -62
  10. package/modules/adlooxAdServerVideo.js +2 -2
  11. package/modules/adlooxAnalyticsAdapter.js +4 -4
  12. package/modules/admanBidAdapter.js +11 -4
  13. package/modules/admixerBidAdapter.js +1 -1
  14. package/modules/adnuntiusBidAdapter.js +3 -1
  15. package/modules/adomikAnalyticsAdapter.js +27 -9
  16. package/modules/adqueryIdSystem.js +103 -0
  17. package/modules/adqueryIdSystem.md +35 -0
  18. package/modules/adxcgBidAdapter.js +311 -359
  19. package/modules/adxcgBidAdapter.md +22 -21
  20. package/modules/adyoulikeBidAdapter.js +13 -9
  21. package/modules/aniviewBidAdapter.js +1 -1
  22. package/modules/appnexusBidAdapter.js +0 -1
  23. package/modules/beopBidAdapter.js +6 -4
  24. package/modules/bidViewability.js +3 -3
  25. package/modules/bidViewabilityIO.js +3 -3
  26. package/modules/bliinkBidAdapter.js +3 -2
  27. package/modules/colossussspBidAdapter.js +7 -0
  28. package/modules/compassBidAdapter.js +208 -0
  29. package/modules/compassBidAdapter.md +79 -0
  30. package/modules/consentManagement.js +7 -1
  31. package/modules/criteoBidAdapter.js +1 -1
  32. package/modules/criteoIdSystem.js +29 -7
  33. package/modules/currency.js +2 -2
  34. package/modules/cwireBidAdapter.js +3 -0
  35. package/modules/dailyhuntBidAdapter.js +435 -0
  36. package/modules/dailyhuntBidAdapter.md +4 -0
  37. package/modules/docereeBidAdapter.js +10 -1
  38. package/modules/docereeBidAdapter.md +2 -0
  39. package/modules/dspxBidAdapter.js +1 -1
  40. package/modules/engageyaBidAdapter.js +1 -1
  41. package/modules/feedadBidAdapter.js +2 -2
  42. package/modules/feedadBidAdapter.md +4 -2
  43. package/modules/futureads.md +48 -0
  44. package/modules/glimpseBidAdapter.js +82 -47
  45. package/modules/gptPreAuction.js +55 -7
  46. package/modules/gridBidAdapter.js +4 -3
  47. package/modules/gumgumBidAdapter.js +2 -2
  48. package/modules/idImportLibrary.js +45 -8
  49. package/modules/idImportLibrary.md +4 -0
  50. package/modules/improvedigitalBidAdapter.js +42 -4
  51. package/modules/instreamTracking.js +4 -4
  52. package/modules/invibesBidAdapter.js +49 -5
  53. package/modules/invibesBidAdapter.md +2 -1
  54. package/modules/ixBidAdapter.js +53 -18
  55. package/modules/kinessoIdSystem.js +1 -1
  56. package/modules/limelightDigitalBidAdapter.js +2 -1
  57. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  58. package/modules/livewrappedBidAdapter.js +8 -2
  59. package/modules/loglyliftBidAdapter.js +79 -0
  60. package/modules/loglyliftBidAdapter.md +55 -0
  61. package/modules/lotamePanoramaIdSystem.js +80 -8
  62. package/modules/mediasquareBidAdapter.js +1 -9
  63. package/modules/nextMillenniumBidAdapter.js +39 -7
  64. package/modules/oguryBidAdapter.js +9 -2
  65. package/modules/onetagBidAdapter.js +4 -2
  66. package/modules/optimeraRtdProvider.js +8 -1
  67. package/modules/ozoneBidAdapter.js +21 -64
  68. package/modules/prebidServerBidAdapter/index.js +16 -12
  69. package/modules/proxistoreBidAdapter.js +0 -2
  70. package/modules/pubgeniusBidAdapter.js +1 -1
  71. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  72. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  73. package/modules/richaudienceBidAdapter.js +4 -4
  74. package/modules/riseBidAdapter.js +1 -1
  75. package/modules/rtbhouseBidAdapter.js +14 -4
  76. package/modules/rtdModule/index.js +49 -18
  77. package/modules/rubiconBidAdapter.js +31 -19
  78. package/modules/sharedIdSystem.js +27 -1
  79. package/modules/showheroes-bsBidAdapter.js +13 -2
  80. package/modules/tappxBidAdapter.js +8 -5
  81. package/modules/targetVideoBidAdapter.js +187 -0
  82. package/modules/targetVideoBidAdapter.md +34 -0
  83. package/modules/teadsBidAdapter.js +1 -2
  84. package/modules/telariaBidAdapter.js +2 -2
  85. package/modules/trustxBidAdapter.js +8 -16
  86. package/modules/userId/eids.js +7 -1
  87. package/modules/userId/userId.md +8 -0
  88. package/modules/vidoomyBidAdapter.js +16 -10
  89. package/modules/weboramaRtdProvider.js +288 -73
  90. package/modules/weboramaRtdProvider.md +27 -10
  91. package/modules/welectBidAdapter.js +106 -0
  92. package/modules/yahoosspBidAdapter.js +5 -1
  93. package/modules/yieldmoBidAdapter.js +23 -5
  94. package/modules/zetaSspBidAdapter.md +33 -1
  95. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  96. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  97. package/modules/zeta_global_sspBidAdapter.js +22 -1
  98. package/package.json +1 -1
  99. package/plugins/pbjsGlobals.js +28 -1
  100. package/src/auction.js +2 -2
  101. package/src/config.js +27 -3
  102. package/src/hook.js +5 -1
  103. package/src/prebid.js +21 -6
  104. package/src/targeting.js +22 -1
  105. package/src/utils.js +46 -8
  106. package/test/helpers/prebidGlobal.js +1 -0
  107. package/test/spec/config_spec.js +279 -0
  108. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  109. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  110. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  111. package/test/spec/modules/adnuntiusBidAdapter_spec.js +17 -0
  112. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
  113. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  114. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  115. package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
  116. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  117. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  118. package/test/spec/modules/bidViewability_spec.js +4 -4
  119. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  120. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  121. package/test/spec/modules/compassBidAdapter_spec.js +398 -0
  122. package/test/spec/modules/consentManagement_spec.js +20 -0
  123. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  124. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  125. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  126. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  127. package/test/spec/modules/eids_spec.js +15 -0
  128. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  129. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  130. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  131. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  132. package/test/spec/modules/improvedigitalBidAdapter_spec.js +45 -1
  133. package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
  134. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  135. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
  136. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  137. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  138. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  139. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  140. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  141. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  142. package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
  143. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  144. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  145. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
  146. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  147. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  148. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  149. package/test/spec/modules/realTimeDataModule_spec.js +147 -48
  150. package/test/spec/modules/richaudienceBidAdapter_spec.js +42 -2
  151. package/test/spec/modules/riseBidAdapter_spec.js +1 -1
  152. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  153. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  154. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  155. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  156. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  157. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  158. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  159. package/test/spec/modules/userId_spec.js +68 -19
  160. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  161. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  162. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  163. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  164. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  165. package/test/spec/unit/core/targeting_spec.js +72 -0
  166. package/test/spec/unit/pbjs_api_spec.js +3 -1
  167. package/test/spec/utils_spec.js +38 -0
  168. package/test/test_deps.js +3 -0
  169. package/test/test_index.js +1 -3
@@ -0,0 +1,106 @@
1
+ import { deepAccess } from '../src/utils.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+
4
+ const BIDDER_CODE = 'welect';
5
+ const DEFAULT_DOMAIN = 'www.welect.de';
6
+
7
+ export const spec = {
8
+ code: BIDDER_CODE,
9
+ aliases: ['wlt'],
10
+ gvlid: 282,
11
+ supportedMediaTypes: ['video'],
12
+
13
+ // short code
14
+ /**
15
+ * Determines whether or not the given bid request is valid.
16
+ *
17
+ * @param {BidRequest} bid The bid params to validate.
18
+ * @return boolean True if this is a valid bid, and false otherwise.
19
+ */
20
+ isBidRequestValid: function (bid) {
21
+ return (
22
+ deepAccess(bid, 'mediaTypes.video.context') === 'instream' &&
23
+ !!bid.params.placementId
24
+ );
25
+ },
26
+ /**
27
+ * Make a server request from the list of BidRequests.
28
+ *
29
+ * @param {validBidRequests[]} - an array of bids
30
+ * @return ServerRequest Info describing the request to the server.
31
+ */
32
+ buildRequests: function (validBidRequests) {
33
+ return validBidRequests.map((bidRequest) => {
34
+ let rawSizes =
35
+ deepAccess(bidRequest, 'mediaTypes.video.playerSize') ||
36
+ bidRequest.sizes;
37
+ let size = rawSizes[0];
38
+
39
+ let domain = bidRequest.params.domain || DEFAULT_DOMAIN;
40
+
41
+ let url = `https://${domain}/api/v2/preflight/${bidRequest.params.placementId}`;
42
+
43
+ let gdprConsent = null;
44
+
45
+ if (bidRequest && bidRequest.gdprConsent) {
46
+ gdprConsent = {
47
+ gdpr_consent: {
48
+ gdprApplies: bidRequest.gdprConsent.gdprApplies,
49
+ tcString: bidRequest.gdprConsent.gdprConsent,
50
+ },
51
+ };
52
+ }
53
+
54
+ const data = {
55
+ width: size[0],
56
+ height: size[1],
57
+ bid_id: bidRequest.bidId,
58
+ ...gdprConsent,
59
+ };
60
+
61
+ return {
62
+ method: 'POST',
63
+ url: url,
64
+ data: data,
65
+ options: {
66
+ contentType: 'application/json',
67
+ withCredentials: false,
68
+ crossOrigin: true,
69
+ },
70
+ };
71
+ });
72
+ },
73
+ /**
74
+ * Unpack the response from the server into a list of bids.
75
+ *
76
+ * @param {ServerResponse} serverResponse A successful response from the server.
77
+ * @return {Bid[]} An array of bids which were nested inside the server.
78
+ */
79
+ interpretResponse: function (serverResponse, bidRequest) {
80
+ const responseBody = serverResponse.body;
81
+
82
+ if (typeof responseBody !== 'object' || responseBody.available !== true) {
83
+ return [];
84
+ }
85
+
86
+ const bidResponses = [];
87
+ const bidResponse = {
88
+ requestId: responseBody.bidResponse.requestId,
89
+ cpm: responseBody.bidResponse.cpm,
90
+ width: responseBody.bidResponse.width,
91
+ height: responseBody.bidResponse.height,
92
+ creativeId: responseBody.bidResponse.creativeId,
93
+ currency: responseBody.bidResponse.currency,
94
+ netRevenue: responseBody.bidResponse.netRevenue,
95
+ ttl: responseBody.bidResponse.ttl,
96
+ ad: responseBody.bidResponse.ad,
97
+ vastUrl: responseBody.bidResponse.vastUrl,
98
+ meta: {
99
+ advertiserDomains: responseBody.bidResponse.meta.advertiserDomains
100
+ }
101
+ };
102
+ bidResponses.push(bidResponse);
103
+ return bidResponses;
104
+ },
105
+ };
106
+ registerBidder(spec);
@@ -6,7 +6,7 @@ import { Renderer } from '../src/Renderer.js';
6
6
 
7
7
  const INTEGRATION_METHOD = 'prebid.js';
8
8
  const BIDDER_CODE = 'yahoossp';
9
- const ADAPTER_VERSION = '1.0.1';
9
+ const ADAPTER_VERSION = '1.0.2';
10
10
  const PREBID_VERSION = '$prebid.version$';
11
11
  const DEFAULT_BID_TTL = 300;
12
12
  const TEST_MODE_DCN = '8a969516017a7a396ec539d97f540011';
@@ -359,6 +359,10 @@ function appendImpObject(bid, openRtbObject) {
359
359
  impObject.ext.data = bid.ortb2Imp.ext.data;
360
360
  };
361
361
 
362
+ if (deepAccess(bid, 'ortb2Imp.instl') && isNumber(bid.ortb2Imp.instl) && (bid.ortb2Imp.instl === 1)) {
363
+ impObject.instl = bid.ortb2Imp.instl;
364
+ };
365
+
362
366
  if (getPubIdMode(bid) === false) {
363
367
  impObject.tagid = bid.params.pos;
364
368
  impObject.ext.pos = bid.params.pos;
@@ -55,13 +55,8 @@ export const spec = {
55
55
  p: [],
56
56
  page_url: bidderRequest.refererInfo.referer,
57
57
  bust: new Date().getTime().toString(),
58
- pr: (LOCAL_WINDOW.document && LOCAL_WINDOW.document.referrer) || '',
59
- scrd: LOCAL_WINDOW.devicePixelRatio || 0,
60
58
  dnt: getDNT(),
61
59
  description: getPageDescription(),
62
- title: LOCAL_WINDOW.document.title || '',
63
- w: LOCAL_WINDOW.innerWidth,
64
- h: LOCAL_WINDOW.innerHeight,
65
60
  userConsent: JSON.stringify({
66
61
  // case of undefined, stringify will remove param
67
62
  gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || '',
@@ -70,6 +65,14 @@ export const spec = {
70
65
  us_privacy: deepAccess(bidderRequest, 'uspConsent') || ''
71
66
  };
72
67
 
68
+ if (canAccessTopWindow()) {
69
+ serverRequest.pr = (LOCAL_WINDOW.document && LOCAL_WINDOW.document.referrer) || '';
70
+ serverRequest.scrd = LOCAL_WINDOW.devicePixelRatio || 0;
71
+ serverRequest.title = LOCAL_WINDOW.document.title || '';
72
+ serverRequest.w = LOCAL_WINDOW.innerWidth;
73
+ serverRequest.h = LOCAL_WINDOW.innerHeight;
74
+ }
75
+
73
76
  const mtp = window.navigator.maxTouchPoints;
74
77
  if (mtp) {
75
78
  serverRequest.mtp = mtp;
@@ -609,3 +612,18 @@ function getEids(bidRequest) {
609
612
  return createEidsArray(bidRequest.userId) || [];
610
613
  }
611
614
  };
615
+
616
+ /**
617
+ * Check if top window can be accessed
618
+ *
619
+ * @return {boolean} true if can access top window otherwise false
620
+ */
621
+ function canAccessTopWindow() {
622
+ try {
623
+ if (getWindowTop().location.href) {
624
+ return true;
625
+ }
626
+ } catch (error) {
627
+ return false;
628
+ }
629
+ }
@@ -10,7 +10,7 @@ Maintainer: miakovlev@zetaglobal.com
10
10
 
11
11
  Module that connects to Zeta's SSP
12
12
 
13
- # Test Parameters
13
+ # Banner Ad Unit: For Publishers
14
14
  ```
15
15
  var adUnits = [
16
16
  {
@@ -40,3 +40,35 @@ Module that connects to Zeta's SSP
40
40
  }
41
41
  ];
42
42
  ```
43
+
44
+ # Video Ad Unit: For Publishers
45
+ ```
46
+ var adUnits = [
47
+ {
48
+ mediaTypes: {
49
+ video: {
50
+ playerSize: [640, 480],
51
+ context: 'outstream'
52
+ }
53
+ },
54
+ bids: [
55
+ {
56
+ bidder: 'zeta_global_ssp',
57
+ bidId: 12345,
58
+ params: {
59
+ placement: 12345,
60
+ user: {
61
+ uid: 12345,
62
+ buyeruid: 12345
63
+ },
64
+ tags: {
65
+ someTag: 123,
66
+ sid: 'publisherId'
67
+ },
68
+ test: 1
69
+ }
70
+ }
71
+ ]
72
+ }
73
+ ];
74
+ ```
@@ -0,0 +1,97 @@
1
+ import { logInfo, logError } from '../src/utils.js';
2
+ import { ajax } from '../src/ajax.js';
3
+ import adapterManager from '../src/adapterManager.js';
4
+ import CONSTANTS from '../src/constants.json';
5
+
6
+ import adapter from '../src/AnalyticsAdapter.js';
7
+
8
+ const ZETA_GVL_ID = 833;
9
+ const ADAPTER_CODE = 'zeta_global_ssp';
10
+ const BASE_URL = 'https://ssp.disqus.com/prebid/event';
11
+ const LOG_PREFIX = 'ZetaGlobalSsp-Analytics: ';
12
+
13
+ /// /////////// VARIABLES ////////////////////////////////////
14
+
15
+ let publisherId; // int
16
+
17
+ /// /////////// HELPER FUNCTIONS /////////////////////////////
18
+
19
+ function sendEvent(eventType, event) {
20
+ ajax(
21
+ BASE_URL + '/' + eventType,
22
+ null,
23
+ JSON.stringify(event)
24
+ );
25
+ }
26
+
27
+ /// /////////// ADAPTER EVENT HANDLER FUNCTIONS //////////////
28
+
29
+ function adRenderSucceededHandler(args) {
30
+ let eventType = CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED
31
+ logInfo(LOG_PREFIX + 'handle ' + eventType + ' event');
32
+
33
+ sendEvent(eventType, args);
34
+ }
35
+
36
+ function auctionEndHandler(args) {
37
+ let eventType = CONSTANTS.EVENTS.AUCTION_END;
38
+ logInfo(LOG_PREFIX + 'handle ' + eventType + ' event');
39
+
40
+ sendEvent(eventType, args);
41
+ }
42
+
43
+ /// /////////// ADAPTER DEFINITION ///////////////////////////
44
+
45
+ let baseAdapter = adapter({ analyticsType: 'endpoint' });
46
+ let zetaAdapter = Object.assign({}, baseAdapter, {
47
+
48
+ enableAnalytics(config = {}) {
49
+ let error = false;
50
+
51
+ if (typeof config.options === 'object') {
52
+ if (config.options.sid) {
53
+ publisherId = Number(config.options.sid);
54
+ }
55
+ } else {
56
+ logError(LOG_PREFIX + 'Config not found');
57
+ error = true;
58
+ }
59
+
60
+ if (!publisherId) {
61
+ logError(LOG_PREFIX + 'Missing sid (publisher id)');
62
+ error = true;
63
+ }
64
+
65
+ if (error) {
66
+ logError(LOG_PREFIX + 'Analytics is disabled due to error(s)');
67
+ } else {
68
+ baseAdapter.enableAnalytics.call(this, config);
69
+ }
70
+ },
71
+
72
+ disableAnalytics() {
73
+ publisherId = undefined;
74
+ baseAdapter.disableAnalytics.apply(this, arguments);
75
+ },
76
+
77
+ track({ eventType, args }) {
78
+ switch (eventType) {
79
+ case CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED:
80
+ adRenderSucceededHandler(args);
81
+ break;
82
+ case CONSTANTS.EVENTS.AUCTION_END:
83
+ auctionEndHandler(args);
84
+ break;
85
+ }
86
+ }
87
+ });
88
+
89
+ /// /////////// ADAPTER REGISTRATION /////////////////////////
90
+
91
+ adapterManager.registerAnalyticsAdapter({
92
+ adapter: zetaAdapter,
93
+ code: ADAPTER_CODE,
94
+ gvlid: ZETA_GVL_ID
95
+ });
96
+
97
+ export default zetaAdapter;
@@ -0,0 +1,24 @@
1
+ # Zeta Global SSP Analytics Adapter
2
+
3
+ ## Overview
4
+
5
+ Module Name: Zeta Global SSP Analytics Adapter\
6
+ Module Type: Analytics Adapter\
7
+ Maintainer: abermanov@zetaglobal.com
8
+
9
+ ## Description
10
+
11
+ Analytics Adapter which sends auctionEnd and adRenderSucceeded events to Zeta Global SSP analytics endpoints
12
+
13
+ ## How to configure
14
+ ```
15
+ pbjs.enableAnalytics({
16
+ provider: 'zeta_global_ssp',
17
+ options: {
18
+ sid: 111,
19
+ tags: {
20
+ ...
21
+ }
22
+ }
23
+ });
24
+ ```
@@ -1,4 +1,4 @@
1
- import { logWarn, deepSetValue, deepAccess, isArray, isNumber, isBoolean, isStr } from '../src/utils.js';
1
+ import {deepAccess, deepSetValue, isArray, isBoolean, isNumber, isStr, logWarn} from '../src/utils.js';
2
2
  import {registerBidder} from '../src/adapters/bidderFactory.js';
3
3
  import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
4
  import {config} from '../src/config.js';
@@ -11,6 +11,8 @@ const DEFAULT_CUR = 'USD';
11
11
  const TTL = 200;
12
12
  const NET_REV = true;
13
13
 
14
+ const VIDEO_REGEX = new RegExp(/VAST\s+version/);
15
+
14
16
  const DATA_TYPES = {
15
17
  'NUMBER': 'number',
16
18
  'STRING': 'string',
@@ -161,6 +163,7 @@ export const spec = {
161
163
  advertiserDomains: zetaBid.adomain
162
164
  };
163
165
  }
166
+ provideMediaType(zetaBid, bid);
164
167
  bidResponses.push(bid);
165
168
  })
166
169
  })
@@ -284,4 +287,22 @@ function isConnectedTV() {
284
287
  return /(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i.test(navigator.userAgent);
285
288
  }
286
289
 
290
+ function provideMediaType(zetaBid, bid) {
291
+ if (zetaBid.ext && zetaBid.ext.bidtype) {
292
+ if (zetaBid.ext.bidtype === VIDEO) {
293
+ bid.mediaType = VIDEO;
294
+ bid.vastXml = bid.ad;
295
+ } else {
296
+ bid.mediaType = BANNER;
297
+ }
298
+ } else {
299
+ if (VIDEO_REGEX.test(bid.ad)) {
300
+ bid.mediaType = VIDEO;
301
+ bid.vastXml = bid.ad;
302
+ } else {
303
+ bid.mediaType = BANNER;
304
+ }
305
+ }
306
+ }
307
+
287
308
  registerBidder(spec);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "6.2.0",
3
+ "version": "6.6.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -1,11 +1,13 @@
1
1
 
2
2
  let t = require('@babel/core').types;
3
3
  let prebid = require('../package.json');
4
+ const path = require('path');
4
5
 
5
6
  module.exports = function(api, options) {
7
+ const pbGlobal = options.globalVarName || prebid.globalVarName;
6
8
  let replace = {
7
9
  '$prebid.version$': prebid.version,
8
- '$$PREBID_GLOBAL$$': options.globalVarName || prebid.globalVarName,
10
+ '$$PREBID_GLOBAL$$': pbGlobal,
9
11
  '$$REPO_AND_VERSION$$': `${prebid.repository.url.split('/')[3]}_prebid_${prebid.version}`
10
12
  };
11
13
 
@@ -13,8 +15,33 @@ module.exports = function(api, options) {
13
15
  '$$REPO_AND_VERSION$$'
14
16
  ];
15
17
 
18
+ const PREBID_ROOT = path.resolve(__dirname, '..');
19
+
20
+ function getModuleName(filename) {
21
+ const modPath = path.parse(path.relative(PREBID_ROOT, filename));
22
+ if (modPath.ext.toLowerCase() !== '.js') {
23
+ return null;
24
+ }
25
+ if (modPath.dir === 'modules') {
26
+ // modules/moduleName.js -> moduleName
27
+ return modPath.name;
28
+ }
29
+ if (modPath.name.toLowerCase() === 'index' && path.dirname(modPath.dir) === 'modules') {
30
+ // modules/moduleName/index.js -> moduleName
31
+ return path.basename(modPath.dir);
32
+ }
33
+ return null;
34
+ }
35
+
16
36
  return {
17
37
  visitor: {
38
+ Program(path, state) {
39
+ const modName = getModuleName(state.filename);
40
+ if (modName != null) {
41
+ // append "registration" of module file to $$PREBID_GLOBAL$$.installedModules
42
+ path.node.body.push(...api.parse(`window.${pbGlobal}.installedModules.push('${modName}');`).program.body);
43
+ }
44
+ },
18
45
  StringLiteral(path) {
19
46
  Object.keys(replace).forEach(name => {
20
47
  if (path.node.value.includes(name)) {
package/src/auction.js CHANGED
@@ -569,7 +569,7 @@ function setupBidTargeting(bidObject, bidderRequest) {
569
569
  let keyValues;
570
570
  const cpmCheck = (isAllowZeroCpmBidsEnabled(bidObject.bidderCode)) ? bidObject.cpm >= 0 : bidObject.cpm > 0;
571
571
  if (bidObject.bidderCode && (cpmCheck || bidObject.dealId)) {
572
- let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode);
572
+ let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode && bid.bidId === bidObject.requestId);
573
573
  keyValues = getKeyValueTargetingPairs(bidObject.bidderCode, bidObject, bidReq);
574
574
  }
575
575
 
@@ -744,7 +744,7 @@ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) {
744
744
  var value = kvPair.val;
745
745
 
746
746
  if (keyValues[key]) {
747
- logWarn('The key: ' + key + ' is getting ovewritten');
747
+ logWarn('The key: ' + key + ' is being overwritten');
748
748
  }
749
749
 
750
750
  if (isFn(value)) {
package/src/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Module for getting and setting Prebid configuration.
3
- */
3
+ */
4
4
 
5
5
  /**
6
6
  * @typedef {Object} MediaTypePriceGranularity
@@ -580,7 +580,7 @@ export function newConfig() {
580
580
  .forEach(listener => listener.callback(options));
581
581
  }
582
582
 
583
- function setBidderConfig(config) {
583
+ function setBidderConfig(config, mergeFlag = false) {
584
584
  try {
585
585
  check(config);
586
586
  config.bidders.forEach(bidder => {
@@ -592,7 +592,8 @@ export function newConfig() {
592
592
  let option = (topic === 'fpd') ? convertFpd(config.config[topic]) : config.config[topic];
593
593
 
594
594
  if (isPlainObject(option)) {
595
- bidderConfig[bidder][prop] = Object.assign({}, bidderConfig[bidder][prop] || {}, option);
595
+ const func = mergeFlag ? mergeDeep : Object.assign;
596
+ bidderConfig[bidder][prop] = func({}, bidderConfig[bidder][prop] || {}, option);
596
597
  } else {
597
598
  bidderConfig[bidder][prop] = option;
598
599
  }
@@ -601,6 +602,7 @@ export function newConfig() {
601
602
  } catch (e) {
602
603
  logError(e);
603
604
  }
605
+
604
606
  function check(obj) {
605
607
  if (!isPlainObject(obj)) {
606
608
  throw 'setBidderConfig bidder options must be an object';
@@ -614,6 +616,26 @@ export function newConfig() {
614
616
  }
615
617
  }
616
618
 
619
+ function mergeConfig(obj) {
620
+ if (!isPlainObject(obj)) {
621
+ logError('mergeConfig input must be an object');
622
+ return;
623
+ }
624
+
625
+ const mergedConfig = Object.keys(obj).reduce((accum, key) => {
626
+ const prevConf = _getConfig(key)[key] || {};
627
+ accum[key] = mergeDeep(prevConf, obj[key]);
628
+ return accum;
629
+ }, {});
630
+
631
+ setConfig({ ...mergedConfig });
632
+ return mergedConfig;
633
+ }
634
+
635
+ function mergeBidderConfig(obj) {
636
+ return setBidderConfig(obj, true);
637
+ }
638
+
617
639
  /**
618
640
  * Internal functions for core to execute some synchronous code while having an active bidder set.
619
641
  */
@@ -653,12 +675,14 @@ export function newConfig() {
653
675
  getConfig,
654
676
  readConfig,
655
677
  setConfig,
678
+ mergeConfig,
656
679
  setDefaults,
657
680
  resetConfig,
658
681
  runWithBidder,
659
682
  callbackWithBidder,
660
683
  setBidderConfig,
661
684
  getBidderConfig,
685
+ mergeBidderConfig,
662
686
  convertAdUnitFpd,
663
687
  getLegacyFpd,
664
688
  getLegacyImpFpd
package/src/hook.js CHANGED
@@ -13,14 +13,18 @@ export function setupBeforeHookFnOnce(baseFn, hookFn, priority = 15) {
13
13
  baseFn.before(hookFn, priority);
14
14
  }
15
15
  }
16
+ const submoduleInstallMap = {};
16
17
 
17
- export function module(name, install) {
18
+ export function module(name, install, {postInstallAllowed = false} = {}) {
18
19
  hook('async', function (submodules) {
19
20
  submodules.forEach(args => install(...args));
21
+ if (postInstallAllowed) submoduleInstallMap[name] = install;
20
22
  }, name)([]); // will be queued until hook.ready() called in pbjs.processQueue();
21
23
  }
22
24
 
23
25
  export function submodule(name, ...args) {
26
+ const install = submoduleInstallMap[name];
27
+ if (install) return install(...args);
24
28
  getHook(name).before((next, modules) => {
25
29
  modules.push(args);
26
30
  next(modules);
package/src/prebid.js CHANGED
@@ -47,8 +47,7 @@ $$PREBID_GLOBAL$$.libLoaded = true;
47
47
  $$PREBID_GLOBAL$$.version = 'v$prebid.version$';
48
48
  logInfo('Prebid.js v$prebid.version$ loaded');
49
49
 
50
- // modules list generated from build
51
- $$PREBID_GLOBAL$$.installedModules = ['v$prebid.modulesList$'];
50
+ $$PREBID_GLOBAL$$.installedModules = $$PREBID_GLOBAL$$.installedModules || [];
52
51
 
53
52
  // create adUnit array
54
53
  $$PREBID_GLOBAL$$.adUnits = $$PREBID_GLOBAL$$.adUnits || [];
@@ -403,10 +402,23 @@ function emitAdRenderSucceeded({ doc, bid, id }) {
403
402
  events.emit(AD_RENDER_SUCCEEDED, data);
404
403
  }
405
404
 
405
+ /**
406
+ * This function will check for presence of given node in given parent. If not present - will inject it.
407
+ * @param {Node} node node, whose existance is in question
408
+ * @param {Document} doc document element do look in
409
+ * @param {string} tagName tag name to look in
410
+ */
411
+ function reinjectNodeIfRemoved(node, doc, tagName) {
412
+ const injectionNode = doc.querySelector(tagName);
413
+ if (!node.parentNode || node.parentNode !== injectionNode) {
414
+ insertElement(node, doc, tagName);
415
+ }
416
+ }
417
+
406
418
  /**
407
419
  * This function will render the ad (based on params) in the given iframe document passed through.
408
420
  * Note that doc SHOULD NOT be the parent document page as we can't doc.write() asynchronously
409
- * @param {HTMLDocument} doc document
421
+ * @param {Document} doc document
410
422
  * @param {string} id bid id to locate the ad
411
423
  * @alias module:pbjs.renderAd
412
424
  */
@@ -450,10 +462,11 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
450
462
  const {height, width, ad, mediaType, adUrl, renderer} = bid;
451
463
 
452
464
  const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`);
465
+ insertElement(creativeComment, doc, 'html');
453
466
 
454
467
  if (isRendererRequired(renderer)) {
455
468
  executeRenderer(renderer, bid);
456
- insertElement(creativeComment, doc, 'html');
469
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
457
470
  emitAdRenderSucceeded({ doc, bid, id });
458
471
  } else if ((doc === document && !inIframe()) || mediaType === 'video') {
459
472
  const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
@@ -472,7 +485,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
472
485
  doc.write(ad);
473
486
  doc.close();
474
487
  setRenderSize(doc, width, height);
475
- insertElement(creativeComment, doc, 'html');
488
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
476
489
  callBurl(bid);
477
490
  emitAdRenderSucceeded({ doc, bid, id });
478
491
  } else if (adUrl) {
@@ -485,7 +498,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
485
498
 
486
499
  insertElement(iframe, doc, 'body');
487
500
  setRenderSize(doc, width, height);
488
- insertElement(creativeComment, doc, 'html');
501
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
489
502
  callBurl(bid);
490
503
  emitAdRenderSucceeded({ doc, bid, id });
491
504
  } else {
@@ -902,6 +915,8 @@ $$PREBID_GLOBAL$$.markWinningBidAsUsed = function (markBidRequest) {
902
915
  */
903
916
  $$PREBID_GLOBAL$$.getConfig = config.getConfig;
904
917
  $$PREBID_GLOBAL$$.readConfig = config.readConfig;
918
+ $$PREBID_GLOBAL$$.mergeConfig = config.mergeConfig;
919
+ $$PREBID_GLOBAL$$.mergeBidderConfig = config.mergeBidderConfig;
905
920
 
906
921
  /**
907
922
  * Set Prebid config options.
package/src/targeting.js CHANGED
@@ -18,6 +18,10 @@ var pbTargetingKeys = [];
18
18
  const MAX_DFP_KEYLENGTH = 20;
19
19
  const TTL_BUFFER = 1000;
20
20
 
21
+ const CFG_ALLOW_TARGETING_KEYS = `targetingControls.allowTargetingKeys`;
22
+ const CFG_ADD_TARGETING_KEYS = `targetingControls.addTargetingKeys`;
23
+ const TARGETING_KEY_CONFIGURATION_ERROR_MSG = `Only one of "${CFG_ALLOW_TARGETING_KEYS}" or "${CFG_ADD_TARGETING_KEYS}" can be set`;
24
+
21
25
  export const TARGETING_KEYS = Object.keys(CONSTANTS.TARGETING_KEYS).map(
22
26
  key => CONSTANTS.TARGETING_KEYS[key]
23
27
  );
@@ -261,7 +265,17 @@ export function newTargeting(auctionManager) {
261
265
  });
262
266
 
263
267
  const defaultKeys = Object.keys(Object.assign({}, CONSTANTS.DEFAULT_TARGETING_KEYS, CONSTANTS.NATIVE_KEYS));
264
- const allowedKeys = config.getConfig('targetingControls.allowTargetingKeys') || defaultKeys;
268
+ let allowedKeys = config.getConfig(CFG_ALLOW_TARGETING_KEYS);
269
+ const addedKeys = config.getConfig(CFG_ADD_TARGETING_KEYS);
270
+
271
+ if (addedKeys != null && allowedKeys != null) {
272
+ throw new Error(TARGETING_KEY_CONFIGURATION_ERROR_MSG);
273
+ } else if (addedKeys != null) {
274
+ allowedKeys = defaultKeys.concat(addedKeys);
275
+ } else {
276
+ allowedKeys = allowedKeys || defaultKeys;
277
+ }
278
+
265
279
  if (Array.isArray(allowedKeys) && allowedKeys.length > 0) {
266
280
  targeting = getAllowedTargetingKeyValues(targeting, allowedKeys);
267
281
  }
@@ -284,6 +298,13 @@ export function newTargeting(auctionManager) {
284
298
  return targeting;
285
299
  };
286
300
 
301
+ // warn about conflicting configuration
302
+ config.getConfig('targetingControls', function (config) {
303
+ if (deepAccess(config, CFG_ALLOW_TARGETING_KEYS) != null && deepAccess(config, CFG_ADD_TARGETING_KEYS) != null) {
304
+ logError(TARGETING_KEY_CONFIGURATION_ERROR_MSG);
305
+ }
306
+ });
307
+
287
308
  // create an encoded string variant based on the keypairs of the provided object
288
309
  // - note this will encode the characters between the keys (ie = and &)
289
310
  function convertKeysToQueryForm(keyMap) {