prebid.js 9.52.0 → 9.53.2

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 (235) hide show
  1. package/.circleci/config.yml +27 -4
  2. package/creative/crossDomain.js +4 -2
  3. package/dist/33acrossAnalyticsAdapter.js +1 -1
  4. package/dist/33acrossBidAdapter.js +1 -1
  5. package/dist/33acrossIdSystem.js +1 -1
  6. package/dist/BTBidAdapter.js +1 -1
  7. package/dist/adagioAnalyticsAdapter.js +1 -1
  8. package/dist/adagioBidAdapter.js +1 -1
  9. package/dist/adagioUtils.js +1 -1
  10. package/dist/addefendBidAdapter.js +1 -1
  11. package/dist/adgenerationBidAdapter.js +1 -1
  12. package/dist/adlooxRtdProvider.js +1 -1
  13. package/dist/adqueryBidAdapter.js +1 -1
  14. package/dist/adrelevantisBidAdapter.js +1 -1
  15. package/dist/adstirBidAdapter.js +1 -1
  16. package/dist/adtrgtmeBidAdapter.js +1 -1
  17. package/dist/adxcgAnalyticsAdapter.js +1 -1
  18. package/dist/adxcgBidAdapter.js +1 -1
  19. package/dist/adyoulikeBidAdapter.js +1 -1
  20. package/dist/agmaAnalyticsAdapter.js +1 -1
  21. package/dist/ajaBidAdapter.js +1 -1
  22. package/dist/amxBidAdapter.js +1 -1
  23. package/dist/amxIdSystem.js +1 -1
  24. package/dist/aniviewBidAdapter.js +1 -1
  25. package/dist/appierAnalyticsAdapter.js +1 -1
  26. package/dist/appnexusBidAdapter.js +1 -1
  27. package/dist/asoBidAdapter.js +1 -1
  28. package/dist/axonixBidAdapter.js +1 -1
  29. package/dist/beopBidAdapter.js +1 -1
  30. package/dist/bidglassBidAdapter.js +1 -1
  31. package/dist/big-richmediaBidAdapter.js +1 -1
  32. package/dist/bitmediaBidAdapter.js +1 -1
  33. package/dist/bridBidAdapter.js +1 -1
  34. package/dist/bridgeuppBidAdapter.js +1 -1
  35. package/dist/bridgewellBidAdapter.js +1 -1
  36. package/dist/brightMountainMediaBidAdapter.js +1 -1
  37. package/dist/carodaBidAdapter.js +1 -1
  38. package/dist/chromeAiRtdProvider.js +1 -0
  39. package/dist/chtnwBidAdapter.js +1 -1
  40. package/dist/chunk-core.js +1 -1
  41. package/dist/concertBidAdapter.js +1 -1
  42. package/dist/connectadBidAdapter.js +1 -1
  43. package/dist/consumableBidAdapter.js +1 -1
  44. package/dist/contxtfulBidAdapter.js +1 -1
  45. package/dist/conversantAnalyticsAdapter.js +1 -1
  46. package/dist/conversantBidAdapter.js +1 -1
  47. package/dist/craftBidAdapter.js +1 -1
  48. package/dist/criteoBidAdapter.js +1 -1
  49. package/dist/cwireBidAdapter.js +1 -1
  50. package/dist/dailymotionBidAdapter.js +1 -1
  51. package/dist/debugging-standalone.js +1 -1
  52. package/dist/dependencies.json +10 -2
  53. package/dist/dspxBidAdapter.js +1 -1
  54. package/dist/dxkultureBidAdapter.js +1 -1
  55. package/dist/eplanningBidAdapter.js +1 -1
  56. package/dist/equativBidAdapter.js +1 -1
  57. package/dist/eskimiBidAdapter.js +1 -1
  58. package/dist/euidIdSystem.js +1 -1
  59. package/dist/exadsBidAdapter.js +1 -1
  60. package/dist/excoBidAdapter.js +1 -1
  61. package/dist/fanAdapter.js +1 -1
  62. package/dist/feedadBidAdapter.js +1 -1
  63. package/dist/finativeBidAdapter.js +1 -1
  64. package/dist/freewheel-sspBidAdapter.js +1 -1
  65. package/dist/gmosspBidAdapter.js +1 -1
  66. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  67. package/dist/greenbidsBidAdapter.js +1 -1
  68. package/dist/greenbidsRtdProvider.js +1 -1
  69. package/dist/gridBidAdapter.js +1 -1
  70. package/dist/gumgumBidAdapter.js +1 -1
  71. package/dist/h12mediaBidAdapter.js +1 -1
  72. package/dist/hypelabBidAdapter.js +1 -1
  73. package/dist/id5AnalyticsAdapter.js +1 -1
  74. package/dist/id5IdSystem.js +1 -1
  75. package/dist/imdsBidAdapter.js +1 -1
  76. package/dist/improvedigitalBidAdapter.js +1 -1
  77. package/dist/inmobiBidAdapter.js +1 -1
  78. package/dist/insticatorBidAdapter.js +1 -1
  79. package/dist/intentIqAnalyticsAdapter.js +1 -1
  80. package/dist/ixBidAdapter.js +1 -1
  81. package/dist/jixieBidAdapter.js +1 -1
  82. package/dist/jixieIdSystem.js +1 -0
  83. package/dist/justpremiumBidAdapter.js +1 -1
  84. package/dist/kargoBidAdapter.js +1 -1
  85. package/dist/kimberliteBidAdapter.js +1 -1
  86. package/dist/konduitAnalyticsAdapter.js +1 -1
  87. package/dist/kueezBidAdapter.js +1 -1
  88. package/dist/lassoBidAdapter.js +1 -1
  89. package/dist/lifestreetBidAdapter.js +1 -1
  90. package/dist/liveIntentId.js +1 -1
  91. package/dist/logicadBidAdapter.js +1 -1
  92. package/dist/loglyliftBidAdapter.js +1 -1
  93. package/dist/luceadBidAdapter.js +1 -1
  94. package/dist/mabidderBidAdapter.js +1 -1
  95. package/dist/madsenseBidAdapter.js +1 -1
  96. package/dist/magniteAnalyticsAdapter.js +1 -1
  97. package/dist/malltvAnalyticsAdapter.js +1 -1
  98. package/dist/marsmediaBidAdapter.js +1 -1
  99. package/dist/mediafuseBidAdapter.js +1 -1
  100. package/dist/medianetBidAdapter.js +1 -1
  101. package/dist/medianetUtils.js +1 -1
  102. package/dist/mediasquareBidAdapter.js +1 -1
  103. package/dist/mgidBidAdapter.js +1 -1
  104. package/dist/missenaBidAdapter.js +1 -1
  105. package/dist/mobilefuseBidAdapter.js +1 -1
  106. package/dist/nextMillenniumBidAdapter.js +1 -1
  107. package/dist/nexx360Utils.js +1 -1
  108. package/dist/nobidAnalyticsAdapter.js +1 -1
  109. package/dist/nobidBidAdapter.js +1 -1
  110. package/dist/nodalsAiRtdProvider.js +1 -1
  111. package/dist/not-for-prod/prebid.js +175 -173
  112. package/dist/oguryBidAdapter.js +1 -1
  113. package/dist/onetagBidAdapter.js +1 -1
  114. package/dist/ooloAnalyticsAdapter.js +1 -1
  115. package/dist/openxBidAdapter.js +1 -1
  116. package/dist/optidigitalBidAdapter.js +1 -1
  117. package/dist/orbidderBidAdapter.js +1 -1
  118. package/dist/ortb2.5Translator.js +1 -1
  119. package/dist/outbrainBidAdapter.js +1 -1
  120. package/dist/ozoneBidAdapter.js +1 -1
  121. package/dist/pixfutureBidAdapter.js +1 -1
  122. package/dist/prebidServerBidAdapter.js +1 -1
  123. package/dist/publinkIdSystem.js +1 -1
  124. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  125. package/dist/pubmaticBidAdapter.js +1 -1
  126. package/dist/pubmaticRtdProvider.js +1 -1
  127. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  128. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  129. package/dist/pxyzBidAdapter.js +1 -1
  130. package/dist/quantcastBidAdapter.js +1 -1
  131. package/dist/readpeakBidAdapter.js +1 -1
  132. package/dist/relaidoBidAdapter.js +1 -1
  133. package/dist/relevatehealthBidAdapter.js +1 -1
  134. package/dist/retailspotBidAdapter.js +1 -1
  135. package/dist/rhythmoneBidAdapter.js +1 -1
  136. package/dist/riseUtils.js +1 -1
  137. package/dist/rubiconBidAdapter.js +1 -1
  138. package/dist/seedingAllianceBidAdapter.js +1 -1
  139. package/dist/seedtagBidAdapter.js +1 -1
  140. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  141. package/dist/sharethroughBidAdapter.js +1 -1
  142. package/dist/showheroes-bsBidAdapter.js +1 -1
  143. package/dist/smaatoBidAdapter.js +1 -1
  144. package/dist/smartadserverBidAdapter.js +1 -1
  145. package/dist/smartxBidAdapter.js +1 -1
  146. package/dist/smilewantedBidAdapter.js +1 -1
  147. package/dist/snigelBidAdapter.js +1 -1
  148. package/dist/sonobiBidAdapter.js +1 -1
  149. package/dist/sovrnBidAdapter.js +1 -1
  150. package/dist/sparteoBidAdapter.js +1 -1
  151. package/dist/sspBCBidAdapter.js +1 -1
  152. package/dist/stvBidAdapter.js +1 -1
  153. package/dist/sublimeBidAdapter.js +1 -1
  154. package/dist/taboolaBidAdapter.js +1 -1
  155. package/dist/tappxBidAdapter.js +1 -1
  156. package/dist/targetVideoBidAdapter.js +1 -1
  157. package/dist/teadsBidAdapter.js +1 -1
  158. package/dist/terceptAnalyticsAdapter.js +1 -1
  159. package/dist/themoneytizerBidAdapter.js +1 -1
  160. package/dist/trionBidAdapter.js +1 -1
  161. package/dist/tripleliftBidAdapter.js +1 -1
  162. package/dist/ttdBidAdapter.js +1 -1
  163. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  164. package/dist/uid2IdSystem.js +1 -1
  165. package/dist/underdogmediaBidAdapter.js +1 -1
  166. package/dist/undertoneBidAdapter.js +1 -1
  167. package/dist/unrulyBidAdapter.js +1 -1
  168. package/dist/userId.js +1 -1
  169. package/dist/vidazooUtils.js +1 -1
  170. package/dist/videobyteBidAdapter.js +1 -1
  171. package/dist/visxBidAdapter.js +1 -1
  172. package/dist/vuukleBidAdapter.js +1 -1
  173. package/dist/widespaceBidAdapter.js +1 -1
  174. package/dist/winrBidAdapter.js +1 -1
  175. package/dist/yahooAdsBidAdapter.js +1 -1
  176. package/dist/yandexBidAdapter.js +1 -1
  177. package/dist/yieldmoBidAdapter.js +1 -1
  178. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  179. package/gulpfile.js +12 -6
  180. package/integrationExamples/chromeai/japanese.html +224 -0
  181. package/integrationExamples/gpt/x-domain/creative.html +1 -1
  182. package/karma.conf.maker.js +7 -7
  183. package/karmaRunner.js +3 -3
  184. package/libraries/liveIntentId/shared.js +16 -0
  185. package/modules/.submodules.json +1 -0
  186. package/modules/aniviewBidAdapter.js +32 -23
  187. package/modules/chromeAiRtdProvider.js +421 -0
  188. package/modules/chromeAiRtdProvider.md +230 -0
  189. package/modules/fanAdapter.js +318 -124
  190. package/modules/ixBidAdapter.js +5 -0
  191. package/modules/jixieIdSystem.js +186 -0
  192. package/modules/ozoneBidAdapter.js +214 -336
  193. package/modules/prebidServerBidAdapter/index.js +59 -35
  194. package/modules/pubmaticRtdProvider.js +418 -4
  195. package/modules/pubmaticRtdProvider.md +12 -2
  196. package/modules/relevatehealthBidAdapter.js +20 -130
  197. package/modules/relevatehealthBidAdapter.md +1 -2
  198. package/modules/sovrnBidAdapter.js +4 -4
  199. package/modules/teadsBidAdapter.js +5 -0
  200. package/modules/ttdBidAdapter.js +5 -4
  201. package/modules/userId/index.js +30 -31
  202. package/package.json +5 -4
  203. package/src/adapterManager.js +3 -0
  204. package/test/spec/libraries/cmUtils_spec.js +17 -12
  205. package/test/spec/modules/aniviewBidAdapter_spec.js +15 -2
  206. package/test/spec/modules/chromeAiRtdProvider_spec.js +393 -0
  207. package/test/spec/modules/dgkeywordRtdProvider_spec.js +5 -2
  208. package/test/spec/modules/euidIdSystem_spec.js +9 -3
  209. package/test/spec/modules/fanAdapter_spec.js +264 -268
  210. package/test/spec/modules/id5IdSystem_spec.js +57 -101
  211. package/test/spec/modules/identityLinkIdSystem_spec.js +1 -0
  212. package/test/spec/modules/idxIdSystem_spec.js +2 -75
  213. package/test/spec/modules/instreamTracking_spec.js +15 -18
  214. package/test/spec/modules/ixBidAdapter_spec.js +26 -0
  215. package/test/spec/modules/jixieIdSystem_spec.js +303 -0
  216. package/test/spec/modules/liveIntentExternalIdSystem_spec.js +5 -0
  217. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +5 -0
  218. package/test/spec/modules/liveIntentIdSystem_spec.js +38 -0
  219. package/test/spec/modules/lmpIdSystem_spec.js +2 -81
  220. package/test/spec/modules/ozoneBidAdapter_spec.js +511 -658
  221. package/test/spec/modules/prebidServerBidAdapter_spec.js +72 -2
  222. package/test/spec/modules/pubmaticBidAdapter_spec.js +411 -126
  223. package/test/spec/modules/pubmaticRtdProvider_spec.js +946 -2
  224. package/test/spec/modules/raynRtdProvider_spec.js +18 -22
  225. package/test/spec/modules/relevatehealthBidAdapter_spec.js +9 -39
  226. package/test/spec/modules/sharedIdSystem_spec.js +3 -3
  227. package/test/spec/modules/sovrnBidAdapter_spec.js +71 -3
  228. package/test/spec/modules/teadsBidAdapter_spec.js +9 -4
  229. package/test/spec/modules/ttdBidAdapter_spec.js +24 -2
  230. package/test/spec/modules/uid2IdSystem_helpers.js +5 -2
  231. package/test/spec/modules/userId_spec.js +142 -387
  232. package/test/spec/modules/yieldoneAnalyticsAdapter_spec.js +13 -12
  233. package/test/spec/modules/zeotapIdPlusIdSystem_spec.js +3 -69
  234. package/wdio.shared.conf.js +2 -2
  235. package/CLAUDE.md +0 -1
@@ -1,4 +1,3 @@
1
- import { formatResponse } from '../libraries/deepintentUtils/index.js';
2
1
  import {
3
2
  registerBidder
4
3
  } from '../src/adapters/bidderFactory.js';
@@ -6,139 +5,30 @@ import {
6
5
  BANNER
7
6
  } from '../src/mediaTypes.js';
8
7
  import {
9
- deepAccess,
10
- generateUUID,
11
- isArray,
12
- logError
13
- } from '../src/utils.js';
14
- const BIDDER_CODE = 'relevatehealth';
8
+ getBannerRequest,
9
+ getBannerResponse
10
+ } from '../libraries/audUtils/bidderUtils.js';
11
+
12
+ const BCODE = 'relevatehealth';
15
13
  const ENDPOINT_URL = 'https://rtb.relevate.health/prebid/relevate';
16
14
 
17
- function buildRequests(bidRequests, bidderRequest) {
18
- const requests = [];
19
- // Loop through each bid request
20
- bidRequests.forEach(bid => {
21
- // Construct the bid request object
22
- const request = {
23
- id: generateUUID(),
24
- placementId: bid.params.placement_id,
25
- imp: [{
26
- id: bid.bidId,
27
- banner: getBanner(bid),
28
- bidfloor: getFloor(bid)
29
- }],
30
- site: getSite(bidderRequest),
31
- user: buildUser(bid)
32
- };
33
- // Get uspConsent from bidderRequest
34
- if (bidderRequest && bidderRequest.uspConsent) {
35
- request.us_privacy = bidderRequest.uspConsent;
36
- }
37
- // Get GPP Consent from bidderRequest
38
- if (bidderRequest?.gppConsent?.gppString) {
39
- request.gpp = bidderRequest.gppConsent.gppString;
40
- request.gpp_sid = bidderRequest.gppConsent.applicableSections;
41
- } else if (bidderRequest?.ortb2?.regs?.gpp) {
42
- request.gpp = bidderRequest.ortb2.regs.gpp;
43
- request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid;
44
- }
45
- // Get coppa compliance from bidderRequest
46
- if (bidderRequest?.ortb2?.regs?.coppa) {
47
- request.coppa = 1;
48
- }
49
- // Push the constructed bid request to the requests array
50
- requests.push(request);
51
- });
52
- // Return the array of bid requests
53
- return {
54
- method: 'POST',
55
- url: ENDPOINT_URL,
56
- data: JSON.stringify(requests),
57
- options: {
58
- contentType: 'application/json',
59
- }
60
- };
61
- }
62
- // Format the response as per the standards
63
- function interpretResponse(bidResponse, bidRequest) {
64
- let resp = [];
65
- if (bidResponse && bidResponse.body) {
66
- try {
67
- let bids = bidResponse.body.seatbid && bidResponse.body.seatbid[0] ? bidResponse.body.seatbid[0].bid : [];
68
- if (bids) {
69
- bids.forEach(bidObj => {
70
- let newBid = formatResponse(bidObj);
71
- newBid.mediaType = BANNER;
72
- resp.push(newBid);
73
- });
74
- }
75
- } catch (err) {
76
- logError(err);
77
- }
78
- }
79
- return resp;
80
- }
81
- // Function to check if Bid is valid
82
- function isBidRequestValid(bid) {
83
- return !!(bid.params.placement_id && bid.params.user_id);
84
- }
85
- // Function to get banner details
86
- function getBanner(bid) {
87
- if (deepAccess(bid, 'mediaTypes.banner')) {
88
- // Fetch width and height from MediaTypes object, if not provided in bid params
89
- if (deepAccess(bid, 'mediaTypes.banner.sizes') && !bid.params.height && !bid.params.width) {
90
- let sizes = deepAccess(bid, 'mediaTypes.banner.sizes');
91
- if (isArray(sizes) && sizes.length > 0) {
92
- return {
93
- h: sizes[0][1],
94
- w: sizes[0][0]
95
- };
96
- }
97
- } else {
98
- return {
99
- h: bid.params.height,
100
- w: bid.params.width
101
- };
102
- }
103
- }
104
- }
105
- // Function to get bid_floor
106
- function getFloor(bid) {
107
- if (bid.params && bid.params.bid_floor) {
108
- return bid.params.bid_floor;
109
- } else {
110
- return 0;
111
- }
112
- }
113
- // Function to get site details
114
- function getSite(bidderRequest) {
115
- let site = {};
116
- if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.page) {
117
- site.name = bidderRequest.refererInfo.domain;
118
- } else {
119
- site.name = '';
120
- }
121
- return site;
122
- }
123
- // Function to build the user object
124
- function buildUser(bid) {
125
- if (bid && bid.params) {
126
- return {
127
- id: bid.params.user_id && typeof bid.params.user_id == 'string' ? bid.params.user_id : '',
128
- // TODO: commented out because of rule violations
129
- buyeruid: '', // localStorage.getItem('adx_profile_guid') ? localStorage.getItem('adx_profile_guid') : '',
130
- keywords: bid.params.keywords && typeof bid.params.keywords == 'string' ? bid.params.keywords : '',
131
- customdata: bid.params.customdata && typeof bid.params.customdata == 'string' ? bid.params.customdata : ''
132
- };
133
- }
134
- }
135
- // Export const spec
136
15
  export const spec = {
137
- code: BIDDER_CODE,
16
+ code: BCODE,
138
17
  supportedMediaTypes: BANNER,
139
- isBidRequestValid,
140
- buildRequests,
141
- interpretResponse
18
+ // Determines whether given bid request is valid or not
19
+ isBidRequestValid: (bidReqParam) => {
20
+ return !!(bidReqParam.params.placement_id);
21
+ },
22
+ // Make a server request from the list of BidRequests
23
+ buildRequests: (bidReq, serverReq) => {
24
+ // Get Requests based on media types
25
+ return getBannerRequest(bidReq, serverReq, ENDPOINT_URL);
26
+ },
27
+ // Unpack the response from the server into a list of bids.
28
+ interpretResponse: (bidResp, bidReq) => {
29
+ const Response = getBannerResponse(bidResp, BANNER);
30
+ return Response;
31
+ }
142
32
  }
143
33
 
144
34
  registerBidder(spec);
@@ -27,11 +27,10 @@ Module that connects to relevatehealth's demand sources.
27
27
  bidder: 'relevatehealth',
28
28
  params: {
29
29
  placement_id: 110011, // Required parameter
30
- user_id: '1111111' // Required parameter
31
30
  width: 160, // Optional parameter
32
31
  height: 600, // Optional parameter
33
32
  domain: '', // Optional parameter
34
- bid_floor: 0.5 // Optional parameter
33
+ bid_floor: 0.5 // Optional parameter
35
34
  }
36
35
  }
37
36
  ]
@@ -234,15 +234,15 @@ export const spec = {
234
234
  dealId: sovrnBid.dealid || null,
235
235
  currency: 'USD',
236
236
  netRevenue: true,
237
- mediaType: sovrnBid.nurl ? BANNER : VIDEO,
237
+ mediaType: sovrnBid.mtype == 2 ? VIDEO : BANNER,
238
238
  ttl: sovrnBid.ext?.ttl || 90,
239
239
  meta: { advertiserDomains: sovrnBid && sovrnBid.adomain ? sovrnBid.adomain : [] }
240
240
  }
241
241
 
242
- if (sovrnBid.nurl) {
243
- bid.ad = decodeURIComponent(`${sovrnBid.adm}<img src="${sovrnBid.nurl}">`)
244
- } else {
242
+ if (sovrnBid.mtype == 2) {
245
243
  bid.vastXml = decodeURIComponent(sovrnBid.adm)
244
+ } else {
245
+ bid.ad = sovrnBid.nurl ? decodeURIComponent(`${sovrnBid.adm}<img src="${sovrnBid.nurl}">`) : decodeURIComponent(sovrnBid.adm)
246
246
  }
247
247
 
248
248
  return bid
@@ -80,6 +80,7 @@ export const spec = {
80
80
  hardwareConcurrency: getHC(),
81
81
  deviceMemory: getDM(),
82
82
  hb_version: '$prebid.version$',
83
+ eids: getUserIdAsEids(validBidRequests),
83
84
  ...getSharedViewerIdParameters(validBidRequests),
84
85
  outbrainId: storage.getDataFromLocalStorage(OB_USER_TOKEN_KEY),
85
86
  ...getFirstPartyTeadsIdParameter(validBidRequests)
@@ -215,6 +216,10 @@ function getSharedViewerIdParameters(validBidRequests) {
215
216
  return sharedViewerIdObject;
216
217
  }
217
218
 
219
+ function getUserIdAsEids(validBidRequests) {
220
+ return validBidRequests?.[0]?.userIdAsEids || [];
221
+ }
222
+
218
223
  function getReferrerInfo(bidderRequest) {
219
224
  let ref = '';
220
225
  if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.page) {
@@ -107,13 +107,14 @@ function getUser(bidderRequest, firstPartyData) {
107
107
  utils.deepSetValue(user, 'ext.consent', bidderRequest.gdprConsent.consentString);
108
108
  }
109
109
 
110
- if (utils.isStr(utils.deepAccess(bidderRequest, 'bids.0.userId.tdid'))) {
111
- user.buyeruid = bidderRequest.bids[0].userId.tdid;
112
- }
113
-
114
110
  var eids = utils.deepAccess(bidderRequest, 'bids.0.userIdAsEids')
115
111
  if (eids && eids.length) {
116
112
  utils.deepSetValue(user, 'ext.eids', eids);
113
+
114
+ const tdid = eids.find(eid => eid.source == 'adserver.org')?.uids?.[0]?.id;
115
+ if (tdid) {
116
+ user.buyeruid = tdid
117
+ }
117
118
  }
118
119
 
119
120
  utils.mergeDeep(user, firstPartyData.user)
@@ -571,25 +571,21 @@ export function enrichEids(ortb2Fragments) {
571
571
  export function addIdData({adUnits, ortb2Fragments}) {
572
572
  ortb2Fragments = ortb2Fragments ?? {global: {}, bidder: {}}
573
573
  enrichEids(ortb2Fragments);
574
- if ([adUnits].some(i => !Array.isArray(i) || !i.length)) {
575
- return;
574
+
575
+ // Set bid.userId for backward compatibility with tests
576
+ if (adUnits && Array.isArray(adUnits) && adUnits.length) {
577
+ const globalIds = getIds(initializedSubmodules.global);
578
+ adUnits.forEach(adUnit => {
579
+ if (adUnit.bids && Array.isArray(adUnit.bids)) {
580
+ adUnit.bids.forEach(bid => {
581
+ const bidderIds = Object.assign({}, globalIds, getIds(initializedSubmodules.bidder[bid.bidder] ?? {}));
582
+ if (Object.keys(bidderIds).length > 0) {
583
+ bid.userId = bidderIds;
584
+ }
585
+ });
586
+ }
587
+ });
576
588
  }
577
- const globalIds = getIds(initializedSubmodules.global);
578
- const globalEids = ortb2Fragments.global.user?.ext?.eids || [];
579
- adUnits.forEach(adUnit => {
580
- if (adUnit.bids && isArray(adUnit.bids)) {
581
- adUnit.bids.forEach(bid => {
582
- const bidderIds = Object.assign({}, globalIds, getIds(initializedSubmodules.bidder[bid.bidder] ?? {}));
583
- const bidderEids = globalEids.concat(ortb2Fragments.bidder?.[bid.bidder]?.user?.ext?.eids || []);
584
- if (Object.keys(bidderIds).length > 0) {
585
- bid.userId = bidderIds;
586
- }
587
- if (bidderEids.length > 0) {
588
- bid.userIdAsEids = bidderEids;
589
- }
590
- });
591
- }
592
- });
593
589
  }
594
590
 
595
591
  const INIT_CANCELED = {};
@@ -724,15 +720,22 @@ export const startAuctionHook = timedAuctionHook('userId', function requestBidsH
724
720
  });
725
721
 
726
722
  /**
727
- * Append user id data from config to bids to be accessed in adapters when there are no submodules.
728
- * @param {function} fn required; The next function in the chain, used by hook.js
729
- * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
723
+ * Alias bid requests' `userIdAsEids` to `ortb2.user.ext.eids`
724
+ * Do this lazily (instead of attaching a copy) so that it also shows EIDs added after the userId module runs (e.g. from RTD modules)
730
725
  */
731
- export const addUserIdsHook = timedAuctionHook('userId', function requestBidsHook(fn, reqBidsConfigObj) {
732
- addIdData(reqBidsConfigObj);
733
- // calling fn allows prebid to continue processing
734
- fn.call(this, reqBidsConfigObj);
735
- });
726
+ function aliasEidsHook(next, bidderRequests) {
727
+ bidderRequests.forEach(bidderRequest => {
728
+ bidderRequest.bids.forEach(bid =>
729
+ Object.defineProperty(bid, 'userIdAsEids', {
730
+ configurable: true,
731
+ get() {
732
+ return bidderRequest.ortb2.user?.ext?.eids;
733
+ }
734
+ })
735
+ )
736
+ })
737
+ next(bidderRequests);
738
+ }
736
739
 
737
740
  /**
738
741
  * Is startAuctionHook added
@@ -1158,7 +1161,6 @@ function updateSubmodules() {
1158
1161
 
1159
1162
  if (submodules.length) {
1160
1163
  if (!addedStartAuctionHook()) {
1161
- startAuction.getHooks({hook: addUserIdsHook}).remove();
1162
1164
  startAuction.before(startAuctionHook, 100) // use higher priority than dataController / rtd
1163
1165
  adapterManager.callDataDeletionRequest.before(requestDataDeletion);
1164
1166
  coreGetPPID.after((next) => next(getPPID()));
@@ -1259,6 +1261,7 @@ export function init(config, {mkDelay = delay} = {}) {
1259
1261
  }
1260
1262
  }
1261
1263
  });
1264
+ adapterManager.makeBidRequests.after(aliasEidsHook);
1262
1265
 
1263
1266
  // exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes.
1264
1267
  (getGlobal()).getUserIds = getUserIds;
@@ -1268,10 +1271,6 @@ export function init(config, {mkDelay = delay} = {}) {
1268
1271
  (getGlobal()).refreshUserIds = normalizePromise(refreshUserIds);
1269
1272
  (getGlobal()).getUserIdsAsync = normalizePromise(getUserIdsAsync);
1270
1273
  (getGlobal()).getUserIdsAsEidBySource = getUserIdsAsEidBySource;
1271
- if (!addedStartAuctionHook()) {
1272
- // Add ortb2.user.ext.eids even if 0 submodules are added
1273
- startAuction.before(addUserIdsHook, 100); // use higher priority than dataController / rtd
1274
- }
1275
1274
  }
1276
1275
 
1277
1276
  export function resetUserIds() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "9.52.0",
3
+ "version": "9.53.2",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.public.js",
6
6
  "exports": {
@@ -100,6 +100,7 @@
100
100
  "karma-sourcemap-loader": "^0.3.7",
101
101
  "karma-spec-reporter": "^0.0.32",
102
102
  "karma-webpack": "^5.0.0",
103
+ "lcov-result-merger": "^5.0.1",
103
104
  "lodash": "^4.17.21",
104
105
  "mocha": "^10.7.3",
105
106
  "morgan": "^1.10.0",
@@ -122,8 +123,7 @@
122
123
  "webpack": "^5.70.0",
123
124
  "webpack-bundle-analyzer": "^4.5.0",
124
125
  "webpack-manifest-plugin": "^5.0.0",
125
- "webpack-stream": "^7.0.0",
126
- "yargs": "^1.3.1"
126
+ "webpack-stream": "^7.0.0"
127
127
  },
128
128
  "dependencies": {
129
129
  "@babel/core": "^7.27.4",
@@ -138,7 +138,8 @@
138
138
  "fun-hooks": "^1.1.0",
139
139
  "gulp-wrap": "^0.15.0",
140
140
  "klona": "^2.0.6",
141
- "live-connect-js": "^7.2.0"
141
+ "live-connect-js": "^7.2.0",
142
+ "yargs": "^1.3.1"
142
143
  },
143
144
  "optionalDependencies": {
144
145
  "fsevents": "^2.3.2"
@@ -207,6 +207,9 @@ function getAdUnitCopyForPrebidServer(adUnits, s2sConfig) {
207
207
 
208
208
  // don't send empty requests
209
209
  adUnitsCopy = adUnitsCopy.filter(adUnit => {
210
+ if (s2sConfig.filterBidderlessCalls) {
211
+ if (adUnit.bids.length === 1 && adUnit.bids[0].bidder == null) return false;
212
+ }
210
213
  return adUnit.bids.length !== 0 || adUnit.s2sBid != null;
211
214
  });
212
215
  return {adUnits: adUnitsCopy, hasModuleBids};
@@ -2,13 +2,15 @@ import * as utils from 'src/utils.js';
2
2
  import {lookupConsentData, consentManagementHook} from '../../../libraries/consentManagement/cmUtils';
3
3
 
4
4
  describe('consent management utils', () => {
5
- let sandbox;
5
+ let sandbox, clock;
6
6
  beforeEach(() => {
7
7
  sandbox = sinon.createSandbox();
8
+ clock = sandbox.useFakeTimers();
8
9
  ['logError', 'logInfo', 'logWarn'].forEach(n => sandbox.stub(utils, n));
9
10
  });
10
11
  afterEach(() => {
11
12
  sandbox.restore();
13
+ clock.restore();
12
14
  });
13
15
 
14
16
  describe('consentManagementHook', () => {
@@ -168,7 +170,7 @@ describe('consent management utils', () => {
168
170
 
169
171
  it('should not time out after it resolves', async () => {
170
172
  await runLookup();
171
- await new Promise((resolve) => setTimeout(resolve, timeout + 10));
173
+ clock.tick(timeout + 10);
172
174
  sinon.assert.notCalled(consentDataHandler.setConsentData);
173
175
  });
174
176
  });
@@ -187,7 +189,9 @@ describe('consent management utils', () => {
187
189
  [0, 100].forEach(timeout => {
188
190
  it(`should resolve with null consent after cmpTimeout ( = ${timeout}ms)`, async () => {
189
191
  cmpTimeout = timeout;
190
- const {consentData, error} = await runLookup();
192
+ const lookup = runLookup();
193
+ clock.tick(timeout + 1);
194
+ const {consentData, error} = await lookup;
191
195
  sinon.assert.calledWith(consentDataHandler.setConsentData, {consent: null});
192
196
  expect(consentData).to.eql({consent: null})
193
197
  expect(error.message).to.match(/.*CMP to load.*/)
@@ -198,26 +202,27 @@ describe('consent management utils', () => {
198
202
  cmpTimeout = 100;
199
203
  actionTimeout = timeout;
200
204
  const lookup = runLookup();
201
- await new Promise((resolve) => setTimeout(resolve, 10));
205
+ clock.tick(10);
202
206
  setProvisionalConsent({consent: 'provisional'});
207
+ clock.tick(timeout + 1);
203
208
  const {consentData, error} = await lookup;
204
209
  expect(consentData).to.eql({consent: 'provisional'});
205
210
  expect(error.message).to.match(/.*action.*/)
206
211
  });
207
212
  });
208
213
 
209
- it('should not reset action timeout if provisional consent is updated multiple times', (done) => {
214
+ it('should not reset action timeout if provisional consent is updated multiple times', async () => {
210
215
  actionTimeout = 100;
211
216
  let consentData;
212
- runLookup().then((res) => {
217
+ const lookup = runLookup().then((res) => {
213
218
  consentData = res.consentData;
214
- })
219
+ });
215
220
  setProvisionalConsent({consent: 1});
216
- setTimeout(() => setProvisionalConsent({consent: 2}), 20);
217
- setTimeout(() => {
218
- expect(consentData).to.eql({consent: 2});
219
- done();
220
- }, 100)
221
+ clock.tick(20);
222
+ setProvisionalConsent({consent: 2});
223
+ clock.tick(80);
224
+ await lookup;
225
+ expect(consentData).to.eql({consent: 2});
221
226
  })
222
227
  });
223
228
  });
@@ -222,6 +222,20 @@ describe('Aniview Bid Adapter', function () {
222
222
  expect(imp.bidfloorcur).not.exist;
223
223
  });
224
224
 
225
+ it('should have vastUrl if adm is not provided but nurl is', function () {
226
+ const bidRequests = spec.buildRequests(videoBidRequest.bids, videoBidRequest);
227
+ const bidderResponse = MOCK.bidderResponse();
228
+
229
+ delete bidderResponse.body.seatbid[0].bid[0].adm
230
+
231
+ const bids = spec.interpretResponse(bidderResponse, bidRequests[0]);
232
+ const bid = bids[0];
233
+
234
+ expect(bid.vastXml).to.not.exist;
235
+ expect(bid.vastUrl).to.exist.and.to.not.have.string('${AUCTION_PRICE}');
236
+ expect(bid.vastUrl).to.have.string('cpm=' + PRICE);
237
+ });
238
+
225
239
  it('should use dev environment', function () {
226
240
  const DEV_ENDPOINT = 'https://dev.aniview.com/sspRTB2';
227
241
  videoBidRequest.bids[0].params.dev = { endpoint: DEV_ENDPOINT };
@@ -257,8 +271,7 @@ describe('Aniview Bid Adapter', function () {
257
271
  expect(bids.length).to.greaterThan(0);
258
272
  expect(bid.vastXml).to.exist.and.to.not.have.string('${AUCTION_PRICE}');
259
273
  expect(bid.vastXml).to.have.string('cpm=' + PRICE);
260
- expect(bid.vastUrl).to.exist.and.to.not.have.string('${AUCTION_PRICE}');
261
- expect(bid.vastUrl).to.have.string('cpm=' + PRICE);
274
+ expect(bid.vastUrl).to.not.exist;
262
275
  expect(bid.requestId).to.equal(bidRequests[0].data.imp[0].id);
263
276
  expect(bid.cpm).to.equal(PRICE);
264
277
  expect(bid.ttl).to.equal(TTL);