prebid.js 7.2.0 → 7.3.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 (173) hide show
  1. package/.github/dependabot.yml +6 -0
  2. package/.github/workflows/issue_tracker.yml +5 -0
  3. package/.github/workflows/release-drafter.yml +6 -0
  4. package/README.md +35 -0
  5. package/dist/33acrossBidAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adbookpspBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adkernelBidAdapter.js +1 -1
  10. package/dist/adqueryBidAdapter.js +1 -1
  11. package/dist/adrelevantisBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/adyoulikeBidAdapter.js +1 -1
  14. package/dist/ajaBidAdapter.js +1 -1
  15. package/dist/amxBidAdapter.js +1 -1
  16. package/dist/amxIdSystem.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/audiencerunBidAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bluebillywigBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/concertBidAdapter.js +1 -1
  28. package/dist/connectadBidAdapter.js +1 -1
  29. package/dist/consumableBidAdapter.js +1 -1
  30. package/dist/conversantBidAdapter.js +1 -1
  31. package/dist/cpexIdSystem.js +1 -1
  32. package/dist/craftBidAdapter.js +1 -1
  33. package/dist/criteoBidAdapter.js +1 -1
  34. package/dist/dianomiBidAdapter.js +1 -0
  35. package/dist/dspxBidAdapter.js +1 -1
  36. package/dist/eplanningBidAdapter.js +1 -1
  37. package/dist/finativeBidAdapter.js +1 -0
  38. package/dist/fpdModule.js +1 -1
  39. package/dist/glimpseBidAdapter.js +1 -1
  40. package/dist/gmosspBidAdapter.js +1 -1
  41. package/dist/goldbachBidAdapter.js +1 -1
  42. package/dist/gridBidAdapter.js +1 -1
  43. package/dist/gridNMBidAdapter.js +1 -1
  44. package/dist/gumgumBidAdapter.js +1 -1
  45. package/dist/h12mediaBidAdapter.js +1 -1
  46. package/dist/id5IdSystem.js +1 -1
  47. package/dist/impactifyBidAdapter.js +1 -1
  48. package/dist/improvedigitalBidAdapter.js +1 -1
  49. package/dist/inmarBidAdapter.js +1 -1
  50. package/dist/insticatorBidAdapter.js +1 -1
  51. package/dist/ixBidAdapter.js +1 -1
  52. package/dist/jixieBidAdapter.js +1 -1
  53. package/dist/justpremiumBidAdapter.js +1 -1
  54. package/dist/konduitAnalyticsAdapter.js +1 -1
  55. package/dist/kueezBidAdapter.js +1 -1
  56. package/dist/lassoBidAdapter.js +1 -0
  57. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  58. package/dist/logicadBidAdapter.js +1 -1
  59. package/dist/loglyliftBidAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediakeysBidAdapter.js +1 -1
  64. package/dist/medianetBidAdapter.js +1 -1
  65. package/dist/mediasquareBidAdapter.js +1 -1
  66. package/dist/mgidBidAdapter.js +1 -1
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/nativoBidAdapter.js +1 -1
  69. package/dist/not-for-prod/prebid.js +119 -115
  70. package/dist/oguryBidAdapter.js +1 -1
  71. package/dist/onetagBidAdapter.js +1 -1
  72. package/dist/ooloAnalyticsAdapter.js +1 -1
  73. package/dist/outbrainBidAdapter.js +1 -1
  74. package/dist/parrableIdSystem.js +1 -1
  75. package/dist/pixfutureBidAdapter.js +1 -1
  76. package/dist/prebid-core.js +1 -1
  77. package/dist/publinkIdSystem.js +1 -1
  78. package/dist/pubmaticBidAdapter.js +1 -1
  79. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  80. package/dist/pxyzBidAdapter.js +1 -1
  81. package/dist/quantcastBidAdapter.js +1 -1
  82. package/dist/readpeakBidAdapter.js +1 -1
  83. package/dist/relaidoBidAdapter.js +1 -1
  84. package/dist/rhythmoneBidAdapter.js +1 -1
  85. package/dist/riseBidAdapter.js +1 -1
  86. package/dist/rubiconAnalyticsAdapter.js +1 -1
  87. package/dist/rubiconBidAdapter.js +1 -1
  88. package/dist/seedingAllianceBidAdapter.js +1 -1
  89. package/dist/seedtagBidAdapter.js +1 -1
  90. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  91. package/dist/sharethroughBidAdapter.js +1 -1
  92. package/dist/smaatoBidAdapter.js +1 -1
  93. package/dist/smartadserverBidAdapter.js +1 -1
  94. package/dist/smartxBidAdapter.js +1 -1
  95. package/dist/smilewantedBidAdapter.js +1 -1
  96. package/dist/sonobiBidAdapter.js +1 -1
  97. package/dist/sovrnAnalyticsAdapter.js +1 -1
  98. package/dist/sovrnBidAdapter.js +1 -1
  99. package/dist/sspBCBidAdapter.js +1 -1
  100. package/dist/sublimeBidAdapter.js +1 -1
  101. package/dist/synacormediaBidAdapter.js +1 -1
  102. package/dist/targetVideoBidAdapter.js +1 -1
  103. package/dist/teadsBidAdapter.js +1 -1
  104. package/dist/tncIdSystem.js +1 -0
  105. package/dist/trionBidAdapter.js +1 -1
  106. package/dist/tripleliftBidAdapter.js +1 -1
  107. package/dist/ttdBidAdapter.js +1 -1
  108. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  109. package/dist/underdogmediaBidAdapter.js +1 -1
  110. package/dist/undertoneBidAdapter.js +1 -1
  111. package/dist/userId.js +1 -1
  112. package/dist/vidazooBidAdapter.js +1 -1
  113. package/dist/videobyteBidAdapter.js +1 -1
  114. package/dist/visxBidAdapter.js +1 -1
  115. package/dist/vuukleBidAdapter.js +1 -1
  116. package/dist/widespaceBidAdapter.js +1 -1
  117. package/dist/winrBidAdapter.js +1 -1
  118. package/dist/yahoosspBidAdapter.js +1 -1
  119. package/dist/yieldlabBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/dist/yieldoneBidAdapter.js +1 -1
  123. package/governance.md +5 -11
  124. package/gulpHelpers.js +1 -1
  125. package/modules/.submodules.json +1 -0
  126. package/modules/33acrossBidAdapter.js +5 -1
  127. package/modules/adkernelBidAdapter.js +2 -1
  128. package/modules/adqueryBidAdapter.js +5 -1
  129. package/modules/cpexIdSystem.js +7 -8
  130. package/modules/dianomiBidAdapter.js +369 -0
  131. package/modules/dianomiBidAdapter.md +73 -0
  132. package/modules/finativeBidAdapter.js +235 -0
  133. package/modules/finativeBidAdapter.md +45 -0
  134. package/modules/fpdModule/index.js +6 -5
  135. package/modules/gumgumBidAdapter.js +2 -0
  136. package/modules/gumgumBidAdapter.md +19 -1
  137. package/modules/lassoBidAdapter.js +133 -0
  138. package/modules/lassoBidAdapter.md +29 -0
  139. package/modules/medianetBidAdapter.js +9 -5
  140. package/modules/nativoBidAdapter.js +19 -7
  141. package/modules/riseBidAdapter.js +1 -0
  142. package/modules/sonobiBidAdapter.js +28 -9
  143. package/modules/sovrnBidAdapter.js +16 -10
  144. package/modules/tncIdSystem.js +63 -0
  145. package/modules/tncIdSystem.md +33 -0
  146. package/modules/userId/eids.js +12 -0
  147. package/modules/userId/eids.md +7 -0
  148. package/modules/userId/userId.md +17 -0
  149. package/modules/yieldlabBidAdapter.js +4 -0
  150. package/modules/yieldmoBidAdapter.js +20 -2
  151. package/modules/yieldoneBidAdapter.js +12 -1
  152. package/package.json +1 -1
  153. package/src/adloader.js +1 -0
  154. package/src/prebid.js +4 -1
  155. package/test/spec/modules/33acrossBidAdapter_spec.js +39 -0
  156. package/test/spec/modules/cpexIdSystem_spec.js +5 -5
  157. package/test/spec/modules/dianomiBidAdapter_spec.js +1223 -0
  158. package/test/spec/modules/eids_spec.js +26 -1
  159. package/test/spec/modules/finativeBidAdapter_spec.js +186 -0
  160. package/test/spec/modules/fpdModule_spec.js +28 -1
  161. package/test/spec/modules/gumgumBidAdapter_spec.js +5 -0
  162. package/test/spec/modules/lassoBidAdapter_spec.js +177 -0
  163. package/test/spec/modules/medianetBidAdapter_spec.js +24 -1
  164. package/test/spec/modules/nativoBidAdapter_spec.js +67 -17
  165. package/test/spec/modules/riseBidAdapter_spec.js +3 -0
  166. package/test/spec/modules/sonobiBidAdapter_spec.js +38 -23
  167. package/test/spec/modules/sovrnBidAdapter_spec.js +39 -5
  168. package/test/spec/modules/tncIdSystem_spec.js +109 -0
  169. package/test/spec/modules/userId_spec.js +6 -3
  170. package/test/spec/modules/yieldlabBidAdapter_spec.js +4 -0
  171. package/test/spec/modules/yieldmoBidAdapter_spec.js +15 -2
  172. package/test/spec/modules/yieldoneBidAdapter_spec.js +43 -2
  173. package/test/spec/unit/pbjs_api_spec.js +23 -0
@@ -7,13 +7,14 @@ import { module, getHook } from '../../src/hook.js';
7
7
 
8
8
  let submodules = [];
9
9
 
10
- /**
11
- * enable submodule in User ID
12
- */
13
10
  export function registerSubmodules(submodule) {
14
11
  submodules.push(submodule);
15
12
  }
16
13
 
14
+ export function reset() {
15
+ submodules.length = 0;
16
+ }
17
+
17
18
  export function processFpd({global = {}, bidder = {}} = {}) {
18
19
  let modConf = config.getConfig('firstPartyData') || {};
19
20
 
@@ -26,8 +27,8 @@ export function processFpd({global = {}, bidder = {}} = {}) {
26
27
  return {global, bidder};
27
28
  }
28
29
 
29
- function startAuctionHook(fn, req) {
30
- Object.assign(req, processFpd({global: req.ortb2, bidder: req.bidderOrtb2}));
30
+ export function startAuctionHook(fn, req) {
31
+ Object.assign(req.ortb2Fragments, processFpd(req.ortb2Fragments));
31
32
  fn.call(this, req);
32
33
  }
33
34
 
@@ -370,6 +370,8 @@ function buildRequests(validBidRequests, bidderRequest) {
370
370
  data.pi = 5;
371
371
  } else if (mediaTypes.video) {
372
372
  data.pi = mediaTypes.video.linearity === 2 ? 6 : 7; // invideo : video
373
+ } else if (params.product && params.product.toLowerCase() === 'skin') {
374
+ data.pi = 8;
373
375
  }
374
376
  } else { // legacy params
375
377
  data = { ...data, ...handleLegacyParams(params, sizes) }
@@ -10,7 +10,7 @@ Maintainer: engineering@gumgum.com
10
10
 
11
11
  GumGum adapter for Prebid.js
12
12
  Please note that both video and in-video products require a mediaType of video.
13
- In-screen and slot products should have a mediaType of banner.
13
+ In-screen, slot, and skin products should have a mediaType of banner.
14
14
 
15
15
  # Test Parameters
16
16
  ```
@@ -50,6 +50,24 @@ var adUnits = [
50
50
  }
51
51
  }
52
52
  ]
53
+ },{
54
+ code: 'skin-placement',
55
+ sizes: [[300, 50]],
56
+ mediaTypes: {
57
+ banner: {
58
+ sizes: [[1, 1]],
59
+ }
60
+ },
61
+ bids: [
62
+ {
63
+ bidder: 'gumgum',
64
+ params: {
65
+ zone: 'dc9d6be1', // GumGum Zone ID given to the client
66
+ product: 'skin',
67
+ bidfloor: 0.03 // CPM bid floor
68
+ }
69
+ }
70
+ ]
53
71
  },{
54
72
  code: 'video-placement',
55
73
  sizes: [[300, 50]],
@@ -0,0 +1,133 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { BANNER } from '../src/mediaTypes.js';
3
+ import { getStorageManager } from '../src/storageManager.js';
4
+ import { ajax } from '../src/ajax.js';
5
+ import { config } from '../src/config.js';
6
+
7
+ const BIDDER_CODE = 'lasso';
8
+ const ENDPOINT_URL = 'https://trc.lhmos.com/prebid';
9
+ const GET_IUD_URL = 'https://secure.adnxs.com/getuid?';
10
+ const COOKIE_NAME = 'aim-xr';
11
+ const storage = getStorageManager({bidderCode: BIDDER_CODE});
12
+
13
+ export const spec = {
14
+ code: BIDDER_CODE,
15
+ isBidRequestValid: function(bid) {
16
+ return !!(bid.params && bid.params.adUnitId);
17
+ },
18
+
19
+ buildRequests: function(validBidRequests, bidderRequest) {
20
+ if (validBidRequests.length === 0) {
21
+ return [];
22
+ }
23
+
24
+ let aimXR = '';
25
+ if (storage.cookiesAreEnabled) {
26
+ aimXR = storage.getCookie(COOKIE_NAME, undefined);
27
+ }
28
+
29
+ return validBidRequests.map(bidRequest => {
30
+ let sizes = []
31
+ if (bidRequest.mediaTypes && bidRequest.mediaTypes[BANNER] && bidRequest.mediaTypes[BANNER].sizes) {
32
+ sizes = bidRequest.mediaTypes[BANNER].sizes;
33
+ }
34
+
35
+ const payload = {
36
+ auctionStart: bidderRequest.auctionStart,
37
+ url: encodeURIComponent(window.location.href),
38
+ bidderRequestId: bidRequest.bidderRequestId,
39
+ adUnitCode: bidRequest.adUnitCode,
40
+ auctionId: bidRequest.auctionId,
41
+ bidId: bidRequest.bidId,
42
+ transactionId: bidRequest.transactionId,
43
+ device: JSON.stringify(getDeviceData()),
44
+ sizes,
45
+ aimXR,
46
+ uid: '$UID',
47
+ params: JSON.stringify(bidRequest.params),
48
+ crumbs: JSON.stringify(bidRequest.crumbs),
49
+ prebidVersion: '$prebid.version$',
50
+ version: 1,
51
+ coppa: config.getConfig('coppa') == true ? 1 : 0,
52
+ ccpa: bidderRequest.uspConsent || undefined
53
+ }
54
+
55
+ return {
56
+ method: 'GET',
57
+ url: getBidRequestUrl(aimXR),
58
+ data: payload,
59
+ options: {
60
+ withCredentials: false
61
+ },
62
+ };
63
+ });
64
+ },
65
+
66
+ interpretResponse: function(serverResponse) {
67
+ const response = serverResponse && serverResponse.body;
68
+ const bidResponses = [];
69
+
70
+ if (!response) {
71
+ return bidResponses;
72
+ }
73
+
74
+ const bidResponse = {
75
+ requestId: response.bidid,
76
+ cpm: response.bid.price,
77
+ currency: response.cur,
78
+ width: response.bid.w,
79
+ height: response.bid.h,
80
+ creativeId: response.bid.crid,
81
+ netRevenue: response.netRevenue,
82
+ ttl: response.ttl,
83
+ ad: response.bid.ad,
84
+ mediaType: response.bid.mediaType,
85
+ meta: {
86
+ secondaryCatIds: response.bid.cat,
87
+ advertiserDomains: response.bid.advertiserDomains,
88
+ advertiserName: response.meta.advertiserName,
89
+ mediaType: response.bid.mediaType
90
+ }
91
+ };
92
+ bidResponses.push(bidResponse);
93
+ return bidResponses;
94
+ },
95
+
96
+ onTimeout: function(timeoutData) {
97
+ if (timeoutData === null) {
98
+ return;
99
+ }
100
+ ajax(ENDPOINT_URL + '/timeout', null, JSON.stringify(timeoutData), {
101
+ method: 'POST',
102
+ withCredentials: false
103
+ });
104
+ },
105
+
106
+ onBidWon: function(bid) {
107
+ ajax(ENDPOINT_URL + '/won', null, JSON.stringify(bid), {
108
+ method: 'POST',
109
+ withCredentials: false
110
+ });
111
+ },
112
+
113
+ supportedMediaTypes: [BANNER]
114
+ }
115
+
116
+ function getBidRequestUrl(aimXR) {
117
+ if (!aimXR) {
118
+ return GET_IUD_URL + ENDPOINT_URL + '/request';
119
+ }
120
+ return ENDPOINT_URL + '/request'
121
+ }
122
+
123
+ function getDeviceData() {
124
+ const win = window.top;
125
+ return {
126
+ ua: navigator.userAgent,
127
+ width: win.innerWidth || win.document.documentElement.clientWidth || win.document.body.clientWidth,
128
+ height: win.innerHeight || win.document.documentElement.clientHeight || win.document.body.clientHeight,
129
+ browserLanguage: navigator.language,
130
+ }
131
+ }
132
+
133
+ registerBidder(spec);
@@ -0,0 +1,29 @@
1
+ # Overview
2
+
3
+ **Module Name**: Lasso Bidder Adapter
4
+ **Module Type**: Bidder Adapter
5
+ **Maintainer**: headerbidding@lassomarketing.io
6
+
7
+ # Description
8
+
9
+ Connects to Lasso demand source to fetch bids.
10
+ Only banner format supported.
11
+
12
+ # Test Parameters
13
+
14
+ ```
15
+ var adUnits = [{
16
+ code: 'banner-ad-unit',
17
+ mediaTypes: {
18
+ banner: {
19
+ sizes: [[300, 250]],
20
+ }
21
+ },
22
+ bids: [{
23
+ bidder: 'lasso',
24
+ params: {
25
+ adUnitId: '0'
26
+ }
27
+ }]
28
+ }];
29
+ ```
@@ -56,13 +56,15 @@ function getTopWindowReferrer() {
56
56
  }
57
57
  }
58
58
 
59
- function siteDetails(site) {
59
+ function siteDetails(site, bidderRequest) {
60
+ const urlData = bidderRequest.refererInfo;
60
61
  site = site || {};
61
62
  let siteData = {
62
- domain: site.domain || mnData.urlData.domain,
63
- page: site.page || mnData.urlData.page,
63
+ domain: site.domain || urlData.domain,
64
+ page: site.page || urlData.page,
64
65
  ref: site.ref || getTopWindowReferrer(),
65
- isTop: site.isTop || mnData.urlData.isTop
66
+ topMostLocation: urlData.topmostLocation,
67
+ isTop: site.isTop || urlData.reachedTop
66
68
  };
67
69
 
68
70
  return Object.assign(siteData, getPageMeta());
@@ -187,6 +189,7 @@ function slotParams(bidRequest) {
187
189
  // check with Media.net Account manager for bid floor and crid parameters
188
190
  let params = {
189
191
  id: bidRequest.bidId,
192
+ transactionId: bidRequest.transactionId,
190
193
  ext: {
191
194
  dfp_id: bidRequest.adUnitCode,
192
195
  display_count: bidRequest.bidRequestsCount
@@ -320,10 +323,11 @@ function getBidderURL(cid) {
320
323
 
321
324
  function generatePayload(bidRequests, bidderRequests) {
322
325
  return {
323
- site: siteDetails(bidRequests[0].params.site),
326
+ site: siteDetails(bidRequests[0].params.site, bidderRequests),
324
327
  ext: extParams(bidRequests[0], bidderRequests),
325
328
  id: bidRequests[0].auctionId,
326
329
  imp: bidRequests.map(request => slotParams(request)),
330
+ ortb2: bidderRequests.ortb2,
327
331
  tmax: bidderRequests.timeout || config.getConfig('bidderTimeout')
328
332
  }
329
333
  }
@@ -16,7 +16,7 @@ const SUPPORTED_AD_TYPES = [BANNER]
16
16
  * Keep track of bid data by keys
17
17
  * @returns {Object} - Map of bid data that can be referenced by multiple keys
18
18
  */
19
- const BidDataMap = () => {
19
+ export const BidDataMap = () => {
20
20
  const referenceMap = {}
21
21
  const bids = []
22
22
 
@@ -25,7 +25,7 @@ const BidDataMap = () => {
25
25
  * @param {String} key - The key to store the index reference
26
26
  * @param {Integer} index - The index value of the bidData
27
27
  */
28
- function adKeyReference(key, index) {
28
+ function addKeyReference(key, index) {
29
29
  if (!referenceMap.hasOwnProperty(key)) {
30
30
  referenceMap[key] = index
31
31
  }
@@ -42,12 +42,12 @@ const BidDataMap = () => {
42
42
 
43
43
  if (Array.isArray(keys)) {
44
44
  keys.forEach((key) => {
45
- adKeyReference(String(key), index)
45
+ addKeyReference(String(key), index)
46
46
  })
47
47
  return
48
48
  }
49
49
 
50
- adKeyReference(String(keys), index)
50
+ addKeyReference(String(keys), index)
51
51
  }
52
52
 
53
53
  /**
@@ -132,8 +132,9 @@ export const spec = {
132
132
  */
133
133
  buildRequests: function (validBidRequests, bidderRequest) {
134
134
  const placementIds = new Set()
135
- let placementId, pageUrl
136
135
  const bidDataMap = BidDataMap()
136
+ const placementSizes = { length: 0 }
137
+ let placementId, pageUrl
137
138
  validBidRequests.forEach((request) => {
138
139
  pageUrl = deepAccess(
139
140
  request,
@@ -142,15 +143,21 @@ export const spec = {
142
143
  )
143
144
  placementId = deepAccess(request, 'params.placementId')
144
145
 
145
- if (placementId) {
146
+ const bidDataKeys = [request.adUnitCode]
147
+
148
+ if (placementId && !placementIds.has(placementId)) {
146
149
  placementIds.add(placementId)
150
+ bidDataKeys.push(placementId)
151
+
152
+ placementSizes[placementId] = request.sizes
153
+ placementSizes.length++
147
154
  }
148
155
 
149
156
  const bidData = {
150
157
  bidId: request.bidId,
151
158
  size: getLargestSize(request.sizes),
152
159
  }
153
- bidDataMap.addBidData(bidData, [placementId, request.adUnitCode])
160
+ bidDataMap.addBidData(bidData, bidDataKeys)
154
161
  })
155
162
  bidRequestMap[bidderRequest.bidderRequestId] = bidDataMap
156
163
 
@@ -199,6 +206,11 @@ export const spec = {
199
206
  params.unshift({ key: 'ntv_ctf', value: Array.from(campaignsToFilter).join(',') })
200
207
  }
201
208
 
209
+ // Placement Sizes
210
+ if (placementSizes.length) {
211
+ params.unshift({ key: 'ntv_pas', value: btoa(JSON.stringify(placementSizes)) })
212
+ }
213
+
202
214
  // Add placement IDs
203
215
  if (placementIds.size > 0) {
204
216
  // Convert Set to Array (IE 11 Safe)
@@ -287,6 +287,7 @@ function generateBidParameters(bid, bidderRequest) {
287
287
  floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice),
288
288
  bidId: getBidIdParameter('bidId', bid),
289
289
  bidderRequestId: getBidIdParameter('bidderRequestId', bid),
290
+ loop: getBidIdParameter('bidderRequestsCount', bid),
290
291
  transactionId: getBidIdParameter('transactionId', bid),
291
292
  };
292
293
 
@@ -56,15 +56,23 @@ export const spec = {
56
56
  */
57
57
  buildRequests: (validBidRequests, bidderRequest) => {
58
58
  const bids = validBidRequests.map(bid => {
59
+ let mediaType;
60
+
61
+ if (deepAccess(bid, 'mediaTypes.video')) {
62
+ mediaType = 'video';
63
+ } else if (deepAccess(bid, 'mediaTypes.banner')) {
64
+ mediaType = 'display';
65
+ }
66
+
59
67
  let slotIdentifier = _validateSlot(bid);
60
68
  if (/^[\/]?[\d]+[[\/].+[\/]?]?$/.test(slotIdentifier)) {
61
69
  slotIdentifier = slotIdentifier.charAt(0) === '/' ? slotIdentifier : '/' + slotIdentifier;
62
70
  return {
63
- [`${slotIdentifier}|${bid.bidId}`]: `${_validateSize(bid)}${_validateFloor(bid)}${_validateGPID(bid)}`
71
+ [`${slotIdentifier}|${bid.bidId}`]: `${_validateSize(bid)}|${_validateFloor(bid)}${_validateGPID(bid)}${_validateMediaType(mediaType)}`
64
72
  }
65
73
  } else if (/^[0-9a-fA-F]{20}$/.test(slotIdentifier) && slotIdentifier.length === 20) {
66
74
  return {
67
- [bid.bidId]: `${slotIdentifier}|${_validateSize(bid)}${_validateFloor(bid)}${_validateGPID(bid)}`
75
+ [bid.bidId]: `${slotIdentifier}|${_validateSize(bid)}|${_validateFloor(bid)}${_validateGPID(bid)}${_validateMediaType(mediaType)}`
68
76
  }
69
77
  } else {
70
78
  logError(`The ad unit code or Sonobi Placement id for slot ${bid.bidId} is invalid`);
@@ -273,7 +281,7 @@ export const spec = {
273
281
  });
274
282
  });
275
283
  }
276
- } catch (e) {}
284
+ } catch (e) { }
277
285
  return syncs;
278
286
  }
279
287
  };
@@ -286,7 +294,7 @@ function _findBidderRequest(bidderRequests, bidId) {
286
294
  }
287
295
  }
288
296
 
289
- function _validateSize (bid) {
297
+ function _validateSize(bid) {
290
298
  if (deepAccess(bid, 'mediaTypes.video')) {
291
299
  return ''; // Video bids arent allowed to override sizes via the trinity request
292
300
  }
@@ -304,18 +312,18 @@ function _validateSize (bid) {
304
312
  }
305
313
  }
306
314
 
307
- function _validateSlot (bid) {
315
+ function _validateSlot(bid) {
308
316
  if (bid.params.ad_unit) {
309
317
  return bid.params.ad_unit;
310
318
  }
311
319
  return bid.params.placement_id;
312
320
  }
313
321
 
314
- function _validateFloor (bid) {
322
+ function _validateFloor(bid) {
315
323
  const floor = getBidFloor(bid);
316
324
 
317
325
  if (floor) {
318
- return `|f=${floor}`;
326
+ return `f=${floor},`;
319
327
  }
320
328
  return '';
321
329
  }
@@ -324,11 +332,22 @@ function _validateGPID(bid) {
324
332
  const gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot') || deepAccess(getGptSlotInfoForAdUnitCode(bid.adUnitCode), 'gptSlot') || bid.params.ad_unit;
325
333
 
326
334
  if (gpid) {
327
- return `|gpid=${gpid}`
335
+ return `gpid=${gpid},`
328
336
  }
329
337
  return ''
330
338
  }
331
339
 
340
+ function _validateMediaType(mediaType) {
341
+ let mediaTypeValidation = '';
342
+ if (mediaType === 'video') {
343
+ mediaTypeValidation = 'c=v,';
344
+ } else if (mediaType === 'display') {
345
+ mediaTypeValidation = 'c=d,';
346
+ }
347
+
348
+ return mediaTypeValidation;
349
+ }
350
+
332
351
  const _creative = (mediaType, referer) => (sbiDc, sbiAid) => {
333
352
  if (mediaType === 'video' || mediaType === 'outstream') {
334
353
  return _videoCreative(sbiDc, sbiAid, referer)
@@ -341,7 +360,7 @@ function _videoCreative(sbiDc, sbiAid, referer) {
341
360
  return `https://${sbiDc}apex.go.sonobi.com/vast.xml?vid=${sbiAid}&ref=${encodeURIComponent(referer)}`
342
361
  }
343
362
 
344
- function _getBidIdFromTrinityKey (key) {
363
+ function _getBidIdFromTrinityKey(key) {
345
364
  return key.split('|').slice(-1)[0]
346
365
  }
347
366
 
@@ -1,16 +1,20 @@
1
1
  import {
2
2
  _each,
3
- deepAccess,
4
- deepSetValue,
5
3
  getBidIdParameter,
6
- getUniqueIdentifierStr,
7
4
  isArray,
8
- isInteger,
5
+ getUniqueIdentifierStr,
6
+ deepSetValue,
9
7
  logError,
8
+ deepAccess,
9
+ isInteger,
10
10
  logWarn
11
11
  } from '../src/utils.js';
12
- import {registerBidder} from '../src/adapters/bidderFactory.js';
13
- import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js';
12
+ import { registerBidder } from '../src/adapters/bidderFactory.js'
13
+ import {
14
+ ADPOD,
15
+ BANNER,
16
+ VIDEO
17
+ } from '../src/mediaTypes.js'
14
18
  import {createEidsArray} from './userId/eids.js';
15
19
 
16
20
  const ORTB_VIDEO_PARAMS = {
@@ -83,7 +87,6 @@ export const spec = {
83
87
  let iv;
84
88
  let schain;
85
89
  let eids;
86
- let tpid = []
87
90
  let criteoId;
88
91
 
89
92
  _each(bidReqs, function (bid) {
@@ -94,7 +97,6 @@ export const spec = {
94
97
  if (id.source === 'criteo.com') {
95
98
  criteoId = id.uids[0].id
96
99
  }
97
- tpid.push({source: id.source, uid: id.uids[0].id})
98
100
  }
99
101
  })
100
102
  }
@@ -175,7 +177,6 @@ export const spec = {
175
177
 
176
178
  if (eids) {
177
179
  deepSetValue(sovrnBidReq, 'user.ext.eids', eids)
178
- deepSetValue(sovrnBidReq, 'user.ext.tpid', tpid)
179
180
  if (criteoId) {
180
181
  deepSetValue(sovrnBidReq, 'user.ext.prebid_criteoid', criteoId)
181
182
  }
@@ -276,11 +277,16 @@ export const spec = {
276
277
 
277
278
  function _buildVideoRequestObj(bid) {
278
279
  const videoObj = {}
280
+ const bidSizes = deepAccess(bid, 'sizes')
279
281
  const videoAdUnitParams = deepAccess(bid, 'mediaTypes.video', {})
280
282
  const videoBidderParams = deepAccess(bid, 'params.video', {})
281
283
  const computedParams = {}
282
284
 
283
- if (Array.isArray(videoAdUnitParams.playerSize)) {
285
+ if (bidSizes) {
286
+ const sizes = (Array.isArray(bidSizes[0])) ? bidSizes[0] : bidSizes
287
+ computedParams.w = sizes[0]
288
+ computedParams.h = sizes[1]
289
+ } else if (Array.isArray(videoAdUnitParams.playerSize)) {
284
290
  const sizes = (Array.isArray(videoAdUnitParams.playerSize[0])) ? videoAdUnitParams.playerSize[0] : videoAdUnitParams.playerSize
285
291
  computedParams.w = sizes[0]
286
292
  computedParams.h = sizes[1]
@@ -0,0 +1,63 @@
1
+ import { submodule } from '../src/hook.js';
2
+ import { logInfo } from '../src/utils.js';
3
+ import { loadExternalScript } from '../src/adloader.js';
4
+
5
+ const MODULE_NAME = 'tncId';
6
+ let url = null;
7
+
8
+ const waitTNCScript = (tncNS) => {
9
+ return new Promise((resolve, reject) => {
10
+ var tnc = window[tncNS];
11
+ if (!tnc) reject(new Error('No TNC Object'));
12
+ if (tnc.tncid) resolve(tnc.tncid);
13
+ tnc.ready(() => {
14
+ tnc = window[tncNS];
15
+ if (tnc.tncid) resolve(tnc.tncid);
16
+ else tnc.on('data-sent', () => resolve(tnc.tncid));
17
+ });
18
+ });
19
+ }
20
+
21
+ const loadRemoteScript = () => {
22
+ return new Promise((resolve) => {
23
+ loadExternalScript(url, MODULE_NAME, resolve);
24
+ })
25
+ }
26
+
27
+ const tncCallback = function (cb) {
28
+ let tncNS = '__tnc';
29
+ let promiseArray = [];
30
+ if (!window[tncNS]) {
31
+ tncNS = '__tncPbjs';
32
+ promiseArray.push(loadRemoteScript());
33
+ }
34
+
35
+ return Promise.all(promiseArray).then(() => waitTNCScript(tncNS)).then(cb).catch(() => cb());
36
+ }
37
+
38
+ export const tncidSubModule = {
39
+ name: MODULE_NAME,
40
+ decode(id) {
41
+ return {
42
+ tncid: id
43
+ };
44
+ },
45
+ gvlid: 750,
46
+ getId(config, consentData) {
47
+ const gdpr = (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) ? 1 : 0;
48
+ const consentString = gdpr ? consentData.consentString : '';
49
+
50
+ if (gdpr && !consentString) {
51
+ logInfo('Consent string is required for TNCID module');
52
+ return;
53
+ }
54
+
55
+ if (config.params && config.params.url) { url = config.params.url; }
56
+
57
+ return {
58
+ callback: function (cb) { return tncCallback(cb); }
59
+ }
60
+ }
61
+ }
62
+
63
+ submodule('userId', tncidSubModule)
@@ -0,0 +1,33 @@
1
+ # TNCID UserID Module
2
+
3
+ ### Prebid Configuration
4
+
5
+ First, make sure to add the TNCID submodule to your Prebid.js package with:
6
+
7
+ ```
8
+ gulp build --modules=tncIdSystem,userId
9
+ ```
10
+
11
+ ### TNCIDIdSystem module Configuration
12
+
13
+ You can configure this submodule in your `userSync.userIds[]` configuration:
14
+
15
+ ```javascript
16
+ pbjs.setConfig({
17
+ userSync: {
18
+ userIds: [{
19
+ name: 'tncId',
20
+ params: {
21
+ url: 'https://js.tncid.app/remote.min.js' //Optional
22
+ }
23
+ }],
24
+ syncDelay: 5000
25
+ }
26
+ });
27
+ ```
28
+ #### Configuration Params
29
+
30
+ | Param Name | Required | Type | Description |
31
+ | --- | --- | --- | --- |
32
+ | name | Required | String | ID value for the TNCID module: `"tncId"` |
33
+ | params.url | Optional | String | Provide TNC fallback script URL, this script is loaded if there is no TNC script on page |
@@ -307,11 +307,23 @@ export const USER_IDS_CONFIG = {
307
307
  }
308
308
  },
309
309
 
310
+ // tncId
311
+ 'tncid': {
312
+ source: 'thenewco.it',
313
+ atype: 3
314
+ },
315
+
310
316
  // Gravito MP ID
311
317
  'gravitompId': {
312
318
  source: 'gravito.net',
313
319
  atype: 1
314
320
  },
321
+
322
+ // cpexId
323
+ 'cpexId': {
324
+ source: 'czechadid.cz',
325
+ atype: 1
326
+ }
315
327
  };
316
328
 
317
329
  // this function will create an eid object for the given UserId sub-module
@@ -232,6 +232,13 @@ userIdAsEids = [
232
232
  id: 'some-random-id-value',
233
233
  atype: 3
234
234
  }]
235
+ },
236
+ {
237
+ source: 'thenewco.it',
238
+ uids: [{
239
+ id: 'some-random-id-value',
240
+ atype: 3
241
+ }]
235
242
  }
236
243
  ]
237
244
  ```
@@ -356,3 +356,20 @@ pbjs.setConfig({
356
356
  }
357
357
  });
358
358
  ```
359
+ ```
360
+
361
+ Example showing how to configure a `params` object to pass directly to bid adapters
362
+
363
+ ```
364
+ pbjs.setConfig({
365
+ userSync: {
366
+ userIds: [{
367
+ name: 'tncId',
368
+ params: {
369
+ providerId: "c8549079-f149-4529-a34b-3fa91ef257d1"
370
+ }
371
+ }],
372
+ syncDelay: 5000
373
+ }
374
+ });
375
+ ```