prebid.js 7.18.0 → 7.19.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 (197) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adfBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryIdSystem.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/axonixBidAdapter.js +1 -1
  17. package/dist/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bridgewellBidAdapter.js +1 -1
  21. package/dist/brightMountainMediaBidAdapter.js +1 -1
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/cleanioRtdProvider.js +1 -1
  24. package/dist/colossussspBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectadBidAdapter.js +1 -1
  27. package/dist/consumableBidAdapter.js +1 -1
  28. package/dist/conversantAnalyticsAdapter.js +1 -0
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/debugging-standalone.js +1 -1
  33. package/dist/debugging.js +1 -1
  34. package/dist/dependencies.json +6 -0
  35. package/dist/dgkeywordRtdProvider.js +1 -1
  36. package/dist/dianomiBidAdapter.js +1 -1
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/enrichmentFpdModule.js +1 -1
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/finativeBidAdapter.js +1 -1
  41. package/dist/fpd.js +1 -0
  42. package/dist/glimpseBidAdapter.js +1 -1
  43. package/dist/gmosspBidAdapter.js +1 -1
  44. package/dist/goldbachBidAdapter.js +1 -1
  45. package/dist/gridBidAdapter.js +1 -1
  46. package/dist/gridNMBidAdapter.js +1 -1
  47. package/dist/gumgumBidAdapter.js +1 -1
  48. package/dist/h12mediaBidAdapter.js +1 -1
  49. package/dist/id5IdSystem.js +1 -1
  50. package/dist/improvedigitalBidAdapter.js +1 -1
  51. package/dist/inmarBidAdapter.js +1 -1
  52. package/dist/insticatorBidAdapter.js +1 -1
  53. package/dist/ixBidAdapter.js +1 -1
  54. package/dist/justpremiumBidAdapter.js +1 -1
  55. package/dist/konduitAnalyticsAdapter.js +1 -1
  56. package/dist/kueezBidAdapter.js +1 -1
  57. package/dist/lassoBidAdapter.js +1 -1
  58. package/dist/lifestreetBidAdapter.js +1 -1
  59. package/dist/liveIntentIdSystem.js +1 -1
  60. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  61. package/dist/logicadBidAdapter.js +1 -1
  62. package/dist/loglyliftBidAdapter.js +1 -1
  63. package/dist/malltvAnalyticsAdapter.js +1 -1
  64. package/dist/marsmediaBidAdapter.js +1 -1
  65. package/dist/mediafuseBidAdapter.js +1 -1
  66. package/dist/mediakeysBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/nativoBidAdapter.js +1 -1
  71. package/dist/not-for-prod/prebid.js +123 -121
  72. package/dist/oguryBidAdapter.js +1 -1
  73. package/dist/onetagBidAdapter.js +1 -1
  74. package/dist/ooloAnalyticsAdapter.js +1 -1
  75. package/dist/outbrainBidAdapter.js +1 -1
  76. package/dist/parrableIdSystem.js +1 -1
  77. package/dist/pixfutureBidAdapter.js +1 -1
  78. package/dist/prebid-core.js +1 -1
  79. package/dist/prebidServerBidAdapter.js +1 -1
  80. package/dist/publinkIdSystem.js +1 -1
  81. package/dist/pubmaticBidAdapter.js +1 -1
  82. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  83. package/dist/pxyzBidAdapter.js +1 -1
  84. package/dist/quantcastBidAdapter.js +1 -1
  85. package/dist/readpeakBidAdapter.js +1 -1
  86. package/dist/relaidoBidAdapter.js +1 -1
  87. package/dist/rhythmoneBidAdapter.js +1 -1
  88. package/dist/riseBidAdapter.js +1 -1
  89. package/dist/rubiconAnalyticsAdapter.js +1 -1
  90. package/dist/rubiconBidAdapter.js +1 -1
  91. package/dist/seedingAllianceBidAdapter.js +1 -1
  92. package/dist/seedtagBidAdapter.js +1 -1
  93. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  94. package/dist/sharethroughBidAdapter.js +1 -1
  95. package/dist/shinezBidAdapter.js +1 -1
  96. package/dist/smaatoBidAdapter.js +1 -1
  97. package/dist/smartadserverBidAdapter.js +1 -1
  98. package/dist/smartxBidAdapter.js +1 -1
  99. package/dist/smilewantedBidAdapter.js +1 -1
  100. package/dist/sonobiBidAdapter.js +1 -1
  101. package/dist/sovrnAnalyticsAdapter.js +1 -1
  102. package/dist/sovrnBidAdapter.js +1 -1
  103. package/dist/sspBCBidAdapter.js +1 -1
  104. package/dist/sublimeBidAdapter.js +1 -1
  105. package/dist/synacormediaBidAdapter.js +1 -1
  106. package/dist/taboolaBidAdapter.js +1 -1
  107. package/dist/targetVideoBidAdapter.js +1 -1
  108. package/dist/teadsBidAdapter.js +1 -1
  109. package/dist/trionBidAdapter.js +1 -1
  110. package/dist/tripleliftBidAdapter.js +1 -1
  111. package/dist/ttdBidAdapter.js +1 -1
  112. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  113. package/dist/underdogmediaBidAdapter.js +1 -1
  114. package/dist/undertoneBidAdapter.js +1 -1
  115. package/dist/vidazooBidAdapter.js +1 -1
  116. package/dist/videobyteBidAdapter.js +1 -1
  117. package/dist/visxBidAdapter.js +1 -1
  118. package/dist/vuukleBidAdapter.js +1 -1
  119. package/dist/widespaceBidAdapter.js +1 -1
  120. package/dist/winrBidAdapter.js +1 -1
  121. package/dist/yahoosspBidAdapter.js +1 -1
  122. package/dist/yandexBidAdapter.js +1 -1
  123. package/dist/yieldmoBidAdapter.js +1 -1
  124. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  125. package/libraries/fpd/sua.js +98 -0
  126. package/modules/adfBidAdapter.js +1 -1
  127. package/modules/adkernelAdnBidAdapter.js +1 -0
  128. package/modules/adqueryIdSystem.js +8 -8
  129. package/modules/adxcgBidAdapter.js +1 -1
  130. package/modules/amxBidAdapter.js +1 -1
  131. package/modules/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +0 -0
  132. package/modules/{andBeyondMediaBidAdapter.md → beyondmediaBidAdapter.md} +1 -1
  133. package/modules/cleanioRtdProvider.js +3 -4
  134. package/modules/colossussspBidAdapter.js +2 -1
  135. package/modules/conversantAnalyticsAdapter.js +560 -0
  136. package/modules/conversantAnalyticsAdapter.md +47 -0
  137. package/modules/criteoBidAdapter.js +1 -1
  138. package/modules/debugging/bidInterceptor.js +2 -2
  139. package/modules/debugging/debugging.js +10 -2
  140. package/modules/dgkeywordRtdProvider.js +21 -3
  141. package/modules/dianomiBidAdapter.js +1 -1
  142. package/modules/enrichmentFpdModule.js +33 -14
  143. package/modules/finativeBidAdapter.js +1 -1
  144. package/modules/gridBidAdapter.js +187 -117
  145. package/modules/improvedigitalBidAdapter.js +2 -2
  146. package/modules/ixBidAdapter.js +94 -23
  147. package/modules/liveIntentIdSystem.js +39 -5
  148. package/modules/mediakeysBidAdapter.js +6 -1
  149. package/modules/mediakeysBidAdapter.md +50 -40
  150. package/modules/nativoBidAdapter.js +1 -1
  151. package/modules/prebidServerBidAdapter/index.js +44 -13
  152. package/modules/readpeakBidAdapter.js +1 -1
  153. package/modules/rubiconBidAdapter.js +2 -3
  154. package/modules/seedingAllianceBidAdapter.js +1 -1
  155. package/modules/sharethroughBidAdapter.js +1 -1
  156. package/modules/taboolaBidAdapter.js +1 -1
  157. package/modules/talkadsBidAdapter.js +1 -0
  158. package/modules/truereachBidAdapter.js +1 -0
  159. package/modules/ttdBidAdapter.js +1 -1
  160. package/modules/vuukleBidAdapter.js +34 -3
  161. package/modules/yahoosspBidAdapter.js +3 -1
  162. package/modules/yandexBidAdapter.js +31 -8
  163. package/package.json +2 -2
  164. package/src/adapterManager.js +2 -4
  165. package/src/cpmBucketManager.js +22 -3
  166. package/src/native.js +1 -5
  167. package/src/prebid.js +3 -3
  168. package/test/spec/cpmBucketManager_spec.js +239 -177
  169. package/test/spec/fpd/sua_spec.js +244 -0
  170. package/test/spec/modules/adfBidAdapter_spec.js +2 -3
  171. package/test/spec/modules/adqueryIdSystem_spec.js +0 -2
  172. package/test/spec/modules/adxcgBidAdapter_spec.js +2 -3
  173. package/test/spec/modules/amxBidAdapter_spec.js +3 -2
  174. package/test/spec/modules/{andBeyondMediaBidAdapter_spec.js → beyondmediaBidAdapter_spec.js} +1 -1
  175. package/test/spec/modules/colossussspBidAdapter_spec.js +4 -2
  176. package/test/spec/modules/conversantAnalyticsAdapter_spec.js +963 -0
  177. package/test/spec/modules/debugging_mod_spec.js +9 -0
  178. package/test/spec/modules/dgkeywordRtdProvider_spec.js +83 -1
  179. package/test/spec/modules/dianomiBidAdapter_spec.js +2 -3
  180. package/test/spec/modules/enrichmentFpdModule_spec.js +50 -7
  181. package/test/spec/modules/fpdModule_spec.js +9 -0
  182. package/test/spec/modules/gridBidAdapter_spec.js +87 -31
  183. package/test/spec/modules/ixBidAdapter_spec.js +221 -2
  184. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +62 -8
  185. package/test/spec/modules/liveIntentIdSystem_spec.js +62 -8
  186. package/test/spec/modules/mediakeysBidAdapter_spec.js +20 -3
  187. package/test/spec/modules/nativoBidAdapter_spec.js +13 -2
  188. package/test/spec/modules/prebidServerBidAdapter_spec.js +159 -4
  189. package/test/spec/modules/seedtagBidAdapter_spec.js +15 -18
  190. package/test/spec/modules/sharethroughBidAdapter_spec.js +2 -1
  191. package/test/spec/modules/taboolaBidAdapter_spec.js +2 -2
  192. package/test/spec/modules/ttdBidAdapter_spec.js +3 -3
  193. package/test/spec/modules/vuukleBidAdapter_spec.js +87 -0
  194. package/test/spec/modules/yahoosspBidAdapter_spec.js +3 -1
  195. package/test/spec/modules/yandexBidAdapter_spec.js +8 -5
  196. package/test/spec/native_spec.js +5 -0
  197. package/test/spec/unit/pbjs_api_spec.js +44 -0
@@ -13,7 +13,8 @@ import {
13
13
  logError,
14
14
  logWarn,
15
15
  mergeDeep,
16
- parseQueryStringParameters
16
+ parseQueryStringParameters,
17
+ safeJSONParse
17
18
  } from '../src/utils.js';
18
19
  import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js';
19
20
  import {config} from '../src/config.js';
@@ -99,8 +100,46 @@ const VIDEO_PARAMS_ALLOW_LIST = [
99
100
  'playerSize', 'w', 'h'
100
101
  ];
101
102
  const LOCAL_STORAGE_KEY = 'ixdiag';
103
+ export const LOCAL_STORAGE_FEATURE_TOGGLES_KEY = `${BIDDER_CODE}_features`;
102
104
  let hasRegisteredHandler = false;
103
105
  export const storage = getStorageManager({gvlid: GLOBAL_VENDOR_ID, bidderCode: BIDDER_CODE});
106
+ export const FEATURE_TOGGLES = {
107
+ featureToggles: {},
108
+ isFeatureEnabled: function(ft) {
109
+ return deepAccess(this.featureToggles, `features.${ft}.activated`)
110
+ },
111
+ getFeatureToggles: function() {
112
+ if (storage.localStorageIsEnabled()) {
113
+ const parsedToggles = safeJSONParse(storage.getDataFromLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY));
114
+ if (deepAccess(parsedToggles, 'expiry') && parsedToggles.expiry >= new Date().getTime()) {
115
+ this.featureToggles = parsedToggles
116
+ } else {
117
+ this.clearFeatureToggles();
118
+ }
119
+ }
120
+ },
121
+ setFeatureToggles: function(serverResponse) {
122
+ const responseBody = serverResponse.body;
123
+ const expiryTime = new Date();
124
+ const toggles = deepAccess(responseBody, 'ext.features');
125
+
126
+ if (toggles) {
127
+ this.featureToggles = {
128
+ expiry: expiryTime.setHours(expiryTime.getHours() + 1),
129
+ features: toggles
130
+ }
131
+ if (storage.localStorageIsEnabled()) {
132
+ storage.setDataInLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY, JSON.stringify(this.featureToggles));
133
+ }
134
+ }
135
+ },
136
+ clearFeatureToggles: function() {
137
+ this.featureToggles = {};
138
+ if (storage.localStorageIsEnabled()) {
139
+ storage.removeDataFromLocalStorage(LOCAL_STORAGE_FEATURE_TOGGLES_KEY);
140
+ }
141
+ }
142
+ };
104
143
  let siteID = 0;
105
144
  let gdprConsent = '';
106
145
  let usPrivacy = '';
@@ -578,6 +617,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
578
617
  r.ext = {};
579
618
  r.ext.source = 'prebid';
580
619
  r.ext.ixdiag = {};
620
+ r.ext.ixdiag.ls = storage.localStorageIsEnabled();
581
621
  r.imp = [];
582
622
  r.at = 1;
583
623
 
@@ -602,13 +642,15 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
602
642
  r.ext.ixdiag.err = cachedErrors;
603
643
  }
604
644
 
645
+ // set source.tid to auctionId for outgoing request to Exchange.
646
+ r.source = {
647
+ tid: validBidRequests[0].auctionId,
648
+ }
649
+
605
650
  // if an schain is provided, send it along
606
651
  if (validBidRequests[0].schain) {
607
- r.source = {
608
- ext: {
609
- schain: validBidRequests[0].schain
610
- }
611
- };
652
+ r.source.ext = {};
653
+ r.source.ext.schain = validBidRequests[0].schain;
612
654
  }
613
655
 
614
656
  if (userEids.length > 0) {
@@ -665,14 +707,17 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
665
707
  // Use the siteId in the first bid request as the main siteId.
666
708
  siteID = validBidRequests[0].params.siteId;
667
709
  payload.s = siteID;
668
- if (version) {
669
- payload.v = version;
670
- }
671
- payload.ac = 'j';
672
- payload.sd = 1;
673
710
 
674
- if (version === VIDEO_ENDPOINT_VERSION) {
675
- payload.nf = 1;
711
+ if (!FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
712
+ if (version) {
713
+ payload.v = version;
714
+ }
715
+ payload.ac = 'j';
716
+ payload.sd = 1;
717
+
718
+ if (version === VIDEO_ENDPOINT_VERSION) {
719
+ payload.nf = 1;
720
+ }
676
721
  }
677
722
 
678
723
  // Parse additional runtime configs.
@@ -718,9 +763,11 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
718
763
  }
719
764
  }
720
765
 
721
- // Create t in payload if timeout is configured.
722
- if (typeof otherIxConfig.timeout === 'number') {
723
- payload.t = otherIxConfig.timeout;
766
+ if (!FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
767
+ // Create t in payload if timeout is configured.
768
+ if (typeof otherIxConfig.timeout === 'number') {
769
+ payload.t = otherIxConfig.timeout;
770
+ }
724
771
  }
725
772
  }
726
773
 
@@ -866,12 +913,27 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
866
913
  requestSequenceNumber++;
867
914
  clonedPayload.r = JSON.stringify(r);
868
915
 
869
- requests.push({
870
- method: 'GET',
871
- url: baseUrl,
872
- data: clonedPayload,
873
- validBidRequests
874
- });
916
+ let requestData;
917
+
918
+ if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
919
+ requestData = {
920
+ method: 'POST',
921
+ url: baseUrl + '?s=' + payload.s,
922
+ data: deepClone(r),
923
+ option: {
924
+ contentType: 'text/plain',
925
+ },
926
+ validBidRequests
927
+ }
928
+ } else {
929
+ requestData = {
930
+ method: 'GET',
931
+ url: baseUrl,
932
+ data: clonedPayload,
933
+ validBidRequests
934
+ }
935
+ }
936
+ requests.push(requestData);
875
937
 
876
938
  currentRequestSize = baseRequestSize;
877
939
  r.imp = [];
@@ -1381,6 +1443,7 @@ export const spec = {
1381
1443
  const videoImps = {}; // Stores created video impressions
1382
1444
  const nativeImps = {}; // Stores created native impressions
1383
1445
  const missingBannerSizes = {}; // To capture the missing sizes i.e not configured for ix
1446
+ FEATURE_TOGGLES.getFeatureToggles();
1384
1447
 
1385
1448
  // Step 1: Create impresssions from IX params
1386
1449
  validBidRequests.forEach((validBidRequest) => {
@@ -1451,6 +1514,7 @@ export const spec = {
1451
1514
  let bid = null;
1452
1515
 
1453
1516
  if (!serverResponse.hasOwnProperty('body') || !serverResponse.body.hasOwnProperty('seatbid')) {
1517
+ FEATURE_TOGGLES.setFeatureToggles(serverResponse);
1454
1518
  return bids;
1455
1519
  }
1456
1520
 
@@ -1463,7 +1527,13 @@ export const spec = {
1463
1527
 
1464
1528
  // Transform rawBid in bid response to the format that will be accepted by prebid.
1465
1529
  const innerBids = seatbid[i].bid;
1466
- let requestBid = JSON.parse(bidderRequest.data.r);
1530
+ let requestBid;
1531
+
1532
+ if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_enable_post')) {
1533
+ requestBid = bidderRequest.data;
1534
+ } else {
1535
+ requestBid = safeJSONParse(bidderRequest.data.r);
1536
+ }
1467
1537
 
1468
1538
  for (let j = 0; j < innerBids.length; j++) {
1469
1539
  const bidRequest = getBidRequest(innerBids[j].impid, requestBid.imp, bidderRequest.validBidRequests);
@@ -1491,6 +1561,7 @@ export const spec = {
1491
1561
  }
1492
1562
  }
1493
1563
 
1564
+ FEATURE_TOGGLES.setFeatureToggles(serverResponse);
1494
1565
  return bids;
1495
1566
  },
1496
1567
 
@@ -14,6 +14,7 @@ import { MinimalLiveConnect } from 'live-connect-js/esm/minimal-live-connect.js'
14
14
 
15
15
  const MODULE_NAME = 'liveIntentId';
16
16
  export const storage = getStorageManager({gvlid: null, moduleName: MODULE_NAME});
17
+ const defaultRequestedAttributes = {'nonId': true}
17
18
  const calls = {
18
19
  ajaxGet: (url, onSuccess, onError, timeout) => {
19
20
  ajaxBuilder(timeout)(
@@ -57,6 +58,23 @@ function parseLiveIntentCollectorConfig(collectConfig) {
57
58
  return config;
58
59
  }
59
60
 
61
+ /**
62
+ * Create requestedAttributes array to pass to liveconnect
63
+ * @function
64
+ * @param {Object} overrides - object with boolean values that will override defaults { 'foo': true, 'bar': false }
65
+ * @returns {Array}
66
+ */
67
+ function parseRequestedAttributes(overrides) {
68
+ function createParameterArray(config) {
69
+ return Object.entries(config).flatMap(([k, v]) => (typeof v === 'boolean' && v) ? [k] : []);
70
+ }
71
+ if (typeof overrides === 'object') {
72
+ return createParameterArray({...defaultRequestedAttributes, ...overrides})
73
+ } else {
74
+ return createParameterArray(defaultRequestedAttributes);
75
+ }
76
+ }
77
+
60
78
  function initializeLiveConnect(configParams) {
61
79
  configParams = configParams || {};
62
80
  if (liveConnect) {
@@ -66,7 +84,8 @@ function initializeLiveConnect(configParams) {
66
84
  const publisherId = configParams.publisherId || 'any';
67
85
  const identityResolutionConfig = {
68
86
  source: 'prebid',
69
- publisherId: publisherId
87
+ publisherId: publisherId,
88
+ requestedAttributes: parseRequestedAttributes(configParams.requestedAttributesOverrides)
70
89
  };
71
90
  if (configParams.url) {
72
91
  identityResolutionConfig.url = configParams.url
@@ -136,9 +155,24 @@ export const liveIntentIdSubmodule = {
136
155
  decode(value, config) {
137
156
  const configParams = (config && config.params) || {};
138
157
  function composeIdObject(value) {
139
- const base = { 'lipbid': value.unifiedId };
140
- delete value.unifiedId;
141
- return { 'lipb': { ...base, ...value } };
158
+ const result = {};
159
+
160
+ // old versions stored lipbid in unifiedId. Ensure that we can still read the data.
161
+ const lipbid = value.nonId || value.unifiedId
162
+ if (lipbid) {
163
+ value.lipbid = lipbid
164
+ delete value.unifiedId
165
+ result.lipb = value
166
+ }
167
+
168
+ // Lift usage of uid2 by exposing uid2 if we were asked to resolve it.
169
+ // As adapters are applied in lexicographical order, we will always
170
+ // be overwritten by the 'proper' uid2 module if it is present.
171
+ if (value.uid2) {
172
+ result.uid2 = { 'id': value.uid2 }
173
+ }
174
+
175
+ return result
142
176
  }
143
177
 
144
178
  if (!liveConnect) {
@@ -146,7 +180,7 @@ export const liveIntentIdSubmodule = {
146
180
  }
147
181
  tryFireEvent();
148
182
 
149
- return (value && typeof value['unifiedId'] === 'string') ? composeIdObject(value) : undefined;
183
+ return composeIdObject(value);
150
184
  },
151
185
 
152
186
  /**
@@ -572,7 +572,12 @@ function nativeBidResponseHandler(bid) {
572
572
  native.impressionTrackers.push(tracker.url);
573
573
  break;
574
574
  case 2:
575
- native.javascriptTrackers = `<script src=\"${tracker.url}\"></script>`;
575
+ const script = `<script async src=\"${tracker.url}\"></script>`;
576
+ if (!native.javascriptTrackers) {
577
+ native.javascriptTrackers = script;
578
+ } else {
579
+ native.javascriptTrackers += `\n${script}`;
580
+ }
576
581
  break;
577
582
  }
578
583
  });
@@ -14,9 +14,10 @@ Connects to Mediakeys demand source to fetch bids.
14
14
 
15
15
  ## Banner only Ad Unit
16
16
 
17
- ```
18
- var adUnits = [
19
- {
17
+ The Mediakeys adapter accepts any valid OpenRTB Spec 2.5 property.
18
+
19
+ ```javascript
20
+ var adUnits = [{
20
21
  code: 'test',
21
22
  mediaTypes: {
22
23
  banner: {
@@ -27,20 +28,26 @@ var adUnits = [
27
28
  bidder: 'mediakeys',
28
29
  params: {} // no params required.
29
30
  }]
30
- },
31
+ }]
31
32
  ```
32
33
 
33
34
  ## Native only Ad Unit
34
35
 
35
36
  The Mediakeys adapter accepts two optional params for native requests. Please see the [OpenRTB Native Ads Specification](https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf) for valid values.
36
37
 
37
- ```
38
- var adUnits = [
39
- {
38
+ ```javascript
39
+ var adUnits = [{
40
40
  code: 'test',
41
41
  mediaTypes: {
42
42
  native: {
43
- type: 'image',
43
+ title: {
44
+ required: true,
45
+ len: 120
46
+ },
47
+ image: {
48
+ required: true,
49
+ sizes: [300, 250]
50
+ }
44
51
  }
45
52
  },
46
53
  bids: [{
@@ -52,7 +59,7 @@ var adUnits = [
52
59
  }
53
60
  }
54
61
  }]
55
- },
62
+ }]
56
63
  ```
57
64
 
58
65
  ## Video only Ad Unit
@@ -61,63 +68,65 @@ The Mediakeys adapter accepts any valid openRTB 2.5 video property. Properties c
61
68
 
62
69
  ### Outstream context
63
70
 
64
- ```
65
- var adUnits = [
66
- {
71
+ ```javascript
72
+ var adUnits = [{
67
73
  code: 'test',
68
74
  mediaTypes: {
69
75
  video: {
70
76
  context: 'outstream',
71
- playerSize: [300, 250],
77
+ playerSize: [1280, 720],
72
78
  // additional OpenRTB video params
73
79
  // placement: 2,
74
80
  // api: [1],
75
81
  // …
82
+ mimes: ['video/mp4'],
83
+ protocols: [2, 3],
84
+ skip: 0
76
85
  }
77
86
  },
78
87
  renderer: {
79
88
  url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
89
+ // the render method must fetch the vast xml document before displaying video
80
90
  render: function (bid) {
81
- var bidReqConfig = pbjs.adUnits.find(bidReq => bidReq.bidId === bid.impid);
82
-
83
- if (bidReqConfig && bidReqConfig.mediaTypes && bidReqConfig.mediaTypes.video && bidReqConfig.mediaTypes.video.context === 'outstream') {
84
- var adResponse = fetch(bid.vastUrl).then(resp => resp.text()).then(text => ({
85
- ad: {
86
- video: {
87
- content: text,
88
- player_width: bid.width || bidReqConfig.mediaTypes.video.playerSize[0],
89
- player_height: bid.height || bidReqConfig.mediaTypes.video.playerSize[1],
90
- }
91
+ var adResponse = fetch(bid.vastUrl).then(resp => resp.text()).then(text => ({
92
+ ad: {
93
+ video: {
94
+ content: text,
95
+ player_height: bid.playerHeight,
96
+ player_width: bid.playerWidth
91
97
  }
92
- }))
93
-
94
- adResponse.then((ad) => {
95
- bid.renderer.push(() => {
96
- ANOutstreamVideo.renderAd({
97
- targetId: bid.adUnitCode,
98
- adResponse: ad
99
- });
98
+ }
99
+ }))
100
+
101
+ adResponse.then((content) => {
102
+ bid.renderer.push(() => {
103
+ ANOutstreamVideo.renderAd({
104
+ targetId: bid.adUnitCode,
105
+ adResponse: content
100
106
  });
101
- })
102
- }
107
+ });
108
+ })
103
109
  }
104
110
  },
105
111
  bids: [{
106
112
  bidder: 'mediakeys',
107
113
  params: {
108
114
  video: {
109
- // additional OpenRTB video params. Will be merged with params defined at mediaTypes level
115
+ // additional OpenRTB video params.
116
+ // will be merged with params defined at mediaTypes level
117
+ api: [1]
110
118
  }
111
119
  }
112
120
  }]
113
- },
121
+ }]
114
122
  ```
115
123
 
116
124
  ### Instream context
117
125
 
118
- ```
119
- var adUnits = [
120
- {
126
+ For Instream Video, you have to enable the Instream Tracking Module to have Prebid emit the onBidWon required event.
127
+
128
+ ```javascript
129
+ var adUnits = [{
121
130
  code: 'test',
122
131
  mediaTypes: {
123
132
  video: {
@@ -132,8 +141,9 @@ var adUnits = [
132
141
  bids: [{
133
142
  bidder: 'mediakeys',
134
143
  params: {
135
- // additional OpenRTB video params. Will be merged with params defined at mediaTypes level
144
+ // additional OpenRTB video params.
145
+ // will be merged with params defined at mediaTypes level
136
146
  }
137
147
  }]
138
- },
148
+ }]
139
149
  ```
@@ -145,7 +145,7 @@ export const spec = {
145
145
  'params.url',
146
146
  )
147
147
  if (pageUrl == undefined || pageUrl === '') {
148
- pageUrl = bidderRequest.refererInfo.page
148
+ pageUrl = bidderRequest.refererInfo.location
149
149
  }
150
150
 
151
151
  placementId = deepAccess(bidRequest, 'params.placementId')
@@ -522,6 +522,8 @@ Object.assign(ORTB2.prototype, {
522
522
  let imps = [];
523
523
  let aliases = {};
524
524
  const firstBidRequest = bidRequests[0];
525
+ let floorMin = null;
526
+ let floorMinCur = null;
525
527
 
526
528
  // transform ad unit into array of OpenRTB impression objects
527
529
  let impIds = new Set();
@@ -671,21 +673,21 @@ Object.assign(ORTB2.prototype, {
671
673
 
672
674
  mergeDeep(imp, mediaTypes);
673
675
 
676
+ const convertCurrency = typeof getGlobal().convertCurrency !== 'function'
677
+ ? (amount) => amount
678
+ : (amount, from, to) => {
679
+ if (from === to) return amount;
680
+ let result = null;
681
+ try {
682
+ result = getGlobal().convertCurrency(amount, from, to);
683
+ } catch (e) {
684
+ }
685
+ return result;
686
+ }
687
+
674
688
  const floor = (() => {
675
689
  // we have to pick a floor for the imp - here we attempt to find the minimum floor
676
690
  // across all bids for this adUnit
677
-
678
- const convertCurrency = typeof getGlobal().convertCurrency !== 'function'
679
- ? (amount) => amount
680
- : (amount, from, to) => {
681
- if (from === to) return amount;
682
- let result = null;
683
- try {
684
- result = getGlobal().convertCurrency(amount, from, to);
685
- } catch (e) {
686
- }
687
- return result;
688
- }
689
691
  const s2sCurrency = config.getConfig('currency.adServerCurrency') || DEFAULT_S2S_CURRENCY;
690
692
 
691
693
  return adUnit.bids
@@ -696,6 +698,7 @@ Object.assign(ORTB2.prototype, {
696
698
  const {currency, floor} = bid.getFloor({
697
699
  currency: s2sCurrency
698
700
  });
701
+
699
702
  return {
700
703
  currency,
701
704
  floor: parseFloat(floor)
@@ -717,11 +720,13 @@ Object.assign(ORTB2.prototype, {
717
720
  min.ref = min.min = floor;
718
721
  } else {
719
722
  const value = convertCurrency(floor.floor, floor.currency, min.ref.currency);
723
+
720
724
  if (value != null && value < min.ref.floor) {
721
725
  min.ref.floor = value;
722
726
  min.min = floor;
723
727
  }
724
728
  }
729
+
725
730
  return min;
726
731
  }, {}).min
727
732
  })();
@@ -729,6 +734,26 @@ Object.assign(ORTB2.prototype, {
729
734
  if (floor) {
730
735
  imp.bidfloor = floor.floor;
731
736
  imp.bidfloorcur = floor.currency;
737
+
738
+ // logic below relates to https://github.com/prebid/Prebid.js/issues/8749 and does the following:
739
+ // 1. check client-side floors (ref bidfloor/bidfloorcur & ortb2Imp floorMin/floorMinCur (if present))
740
+ // 2. set pbs req wide floorMinCur to the first floor currency found when iterating over imp's
741
+ // (if currency conversion logic present, convert all imp floor values to this currency)
742
+ // 3. compare/store ref to lowest floorMin value as each imp is iterated over
743
+ // 4. set req wide floorMin and floorMinCur values for pbs after iterations are done
744
+ if (floorMinCur == null) { floorMinCur = floor.currency }
745
+ const ortb2ImpFloorMin = imp.ext?.prebid?.floors?.floorMin || imp.ext?.prebid?.floorMin;
746
+ const ortb2ImpFloorCur = imp.ext?.prebid?.floors?.floorMinCur || imp.ext?.prebid?.floorMinCur || floorMinCur;
747
+
748
+ const convertedFloorMinValue = convertCurrency(floor.floor, floor.currency, floorMinCur);
749
+ const convertedOrtb2ImpFloorMinValue = ortb2ImpFloorMin && ortb2ImpFloorCur ? convertCurrency(ortb2ImpFloorMin, ortb2ImpFloorCur, floorMinCur) : false;
750
+
751
+ const lowestImpFloorMin = convertedOrtb2ImpFloorMinValue && convertedOrtb2ImpFloorMinValue < convertedFloorMinValue
752
+ ? convertedOrtb2ImpFloorMinValue
753
+ : convertedFloorMinValue;
754
+
755
+ deepSetValue(imp, 'ext.prebid.floors.floorMin', lowestImpFloorMin);
756
+ if (floorMin == null || floorMin > lowestImpFloorMin) { floorMin = lowestImpFloorMin }
732
757
  }
733
758
 
734
759
  if (imp.banner || imp.video || imp.native) {
@@ -742,7 +767,7 @@ Object.assign(ORTB2.prototype, {
742
767
  }
743
768
  const request = {
744
769
  id: firstBidRequest.auctionId,
745
- source: {tid: s2sBidRequest.tid},
770
+ source: {tid: firstBidRequest.auctionId},
746
771
  tmax: s2sConfig.timeout,
747
772
  imp: imps,
748
773
  // to do: add setconfig option to pass test = 1
@@ -903,6 +928,12 @@ Object.assign(ORTB2.prototype, {
903
928
  addBidderFirstPartyDataToRequest(request, s2sBidRequest.ortb2Fragments?.bidder || {});
904
929
 
905
930
  request.imp.forEach((imp) => this.impRequested[imp.id] = imp);
931
+
932
+ if (request.ext?.prebid?.floors?.enabled) {
933
+ request.ext.prebid.floors.floorMin = floorMin;
934
+ request.ext.prebid.floors.floorMinCur = floorMinCur;
935
+ }
936
+
906
937
  return request;
907
938
  },
908
939
 
@@ -41,7 +41,7 @@ export const spec = {
41
41
  cur: [currency],
42
42
  source: {
43
43
  fd: 1,
44
- tid: bidRequests[0].transactionId,
44
+ tid: bidderRequest.auctionId,
45
45
  ext: {
46
46
  prebid: '$prebid.version$'
47
47
  }
@@ -333,7 +333,7 @@ export const spec = {
333
333
  }
334
334
  });
335
335
 
336
- if (rubiConf.singleRequest !== true) {
336
+ if (config.getConfig('rubicon.singleRequest') !== true) {
337
337
  // bids are not grouped if single request mode is not enabled
338
338
  requests = videoRequests.concat(bidRequests.filter(bidRequest => bidType(bidRequest) === 'banner').map(bidRequest => {
339
339
  const bidParams = spec.createSlotParams(bidRequest, bidderRequest);
@@ -1279,8 +1279,7 @@ export function hasValidSupplyChainParams(schain) {
1279
1279
  }
1280
1280
 
1281
1281
  /**
1282
- * Creates a URL key value param, encoding the
1283
- * param unless the key is schain
1282
+ * Creates a URL key value param, encoding the param unless the key is schain
1284
1283
  * @param {String} key
1285
1284
  * @param {String} param
1286
1285
  * @returns {String}
@@ -67,7 +67,7 @@ export const spec = {
67
67
  validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
68
68
 
69
69
  const pt = setOnAny(validBidRequests, 'params.pt') || setOnAny(validBidRequests, 'params.priceType') || 'net';
70
- const tid = validBidRequests[0].transactionId;
70
+ const tid = bidderRequest.auctionId;
71
71
  const cur = [config.getConfig('currency.adServerCurrency') || DEFAULT_CUR];
72
72
  let url = bidderRequest.refererInfo.page;
73
73
 
@@ -52,7 +52,7 @@ export const sharethroughAdapterSpec = {
52
52
  ext: {},
53
53
  },
54
54
  source: {
55
- tid: bidRequests[0].transactionId,
55
+ tid: bidderRequest.auctionId,
56
56
  ext: {
57
57
  version: '$prebid.version$',
58
58
  str: VERSION,
@@ -237,7 +237,7 @@ function getBid(requestId, currency, bidResponse) {
237
237
  width,
238
238
  height,
239
239
  meta,
240
- netRevenue: false
240
+ netRevenue: true
241
241
  };
242
242
  }
243
243
 
@@ -63,6 +63,7 @@ export const spec = {
63
63
  cur: CURRENCY,
64
64
  timeout: poBidderRequest.timeout,
65
65
  auction_id: paValidBidRequests[0].auctionId,
66
+ // TODO: should this use auctionId? see #8573
66
67
  transaction_id: paValidBidRequests[0].transactionId,
67
68
  bids: laBids,
68
69
  gdpr: { applies: false, consent: false },
@@ -25,6 +25,7 @@ export const spec = {
25
25
 
26
26
  let siteId = deepAccess(validBidRequests[0], 'params.site_id');
27
27
 
28
+ // TODO: should this use auctionId? see #8573
28
29
  let url = BIDDER_URL + siteId + '?hb=1&transactionId=' + validBidRequests[0].transactionId;
29
30
 
30
31
  return {
@@ -59,7 +59,7 @@ function getBidFloor(bid) {
59
59
 
60
60
  function getSource(validBidRequests) {
61
61
  let source = {
62
- tid: validBidRequests[0].transactionId
62
+ tid: validBidRequests[0].auctionId
63
63
  };
64
64
  if (validBidRequests[0].schain) {
65
65
  utils.deepSetValue(source, 'ext.schain', validBidRequests[0].schain);