prebid.js 6.26.0 → 6.29.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 (261) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adWMGAnalyticsAdapter.js +1 -1
  3. package/dist/adagioAnalyticsAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adfBidAdapter.js +1 -1
  7. package/dist/adgenerationBidAdapter.js +1 -1
  8. package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
  9. package/dist/adlooxAdServerVideo.js +1 -1
  10. package/dist/adlooxAnalyticsAdapter.js +1 -1
  11. package/dist/adlooxRtdProvider.js +1 -1
  12. package/dist/adoceanBidAdapter.js +1 -1
  13. package/dist/adomikAnalyticsAdapter.js +1 -1
  14. package/dist/adrelevantisBidAdapter.js +1 -1
  15. package/dist/adxcgAnalyticsAdapter.js +1 -1
  16. package/dist/adxcgBidAdapter.js +1 -1
  17. package/dist/adxpremiumAnalyticsAdapter.js +1 -1
  18. package/dist/adyoulikeBidAdapter.js +1 -1
  19. package/dist/ajaBidAdapter.js +1 -1
  20. package/dist/akamaiDapRtdProvider.js +1 -1
  21. package/dist/amxBidAdapter.js +1 -1
  22. package/dist/amxIdSystem.js +1 -1
  23. package/dist/appierAnalyticsAdapter.js +1 -1
  24. package/dist/appnexusAnalyticsAdapter.js +1 -1
  25. package/dist/appnexusBidAdapter.js +1 -1
  26. package/dist/asoBidAdapter.js +1 -1
  27. package/dist/atsAnalyticsAdapter.js +1 -1
  28. package/dist/audiencerunBidAdapter.js +1 -1
  29. package/dist/automatadBidAdapter.js +1 -1
  30. package/dist/axonixBidAdapter.js +1 -1
  31. package/dist/bidglassBidAdapter.js +1 -1
  32. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  33. package/dist/big-richmediaBidAdapter.js +1 -1
  34. package/dist/bluebillywigBidAdapter.js +1 -1
  35. package/dist/bridgewellBidAdapter.js +1 -1
  36. package/dist/brightMountainMediaBidAdapter.js +1 -1
  37. package/dist/byDataAnalyticsAdapter.js +1 -1
  38. package/dist/colossussspBidAdapter.js +1 -1
  39. package/dist/concertAnalyticsAdapter.js +1 -1
  40. package/dist/concertBidAdapter.js +1 -1
  41. package/dist/connectadBidAdapter.js +1 -1
  42. package/dist/consumableBidAdapter.js +1 -1
  43. package/dist/conversantBidAdapter.js +1 -1
  44. package/dist/craftBidAdapter.js +1 -1
  45. package/dist/criteoBidAdapter.js +1 -1
  46. package/dist/datablocksAnalyticsAdapter.js +1 -1
  47. package/dist/dspxBidAdapter.js +1 -1
  48. package/dist/eplanningAnalyticsAdapter.js +1 -1
  49. package/dist/eplanningBidAdapter.js +1 -1
  50. package/dist/fintezaAnalyticsAdapter.js +1 -1
  51. package/dist/ftrackIdSystem.js +1 -1
  52. package/dist/gdprEnforcement.js +1 -1
  53. package/dist/glimpseBidAdapter.js +1 -1
  54. package/dist/gmosspBidAdapter.js +1 -1
  55. package/dist/goldbachBidAdapter.js +1 -1
  56. package/dist/gridBidAdapter.js +1 -1
  57. package/dist/gridNMBidAdapter.js +1 -1
  58. package/dist/gumgumBidAdapter.js +1 -1
  59. package/dist/h12mediaBidAdapter.js +1 -1
  60. package/dist/hadronAnalyticsAdapter.js +1 -1
  61. package/dist/hadronRtdProvider.js +1 -1
  62. package/dist/id5AnalyticsAdapter.js +1 -1
  63. package/dist/id5IdSystem.js +1 -1
  64. package/dist/impactifyBidAdapter.js +1 -1
  65. package/dist/improvedigitalBidAdapter.js +1 -1
  66. package/dist/incrxBidAdapter.js +1 -0
  67. package/dist/inmarBidAdapter.js +1 -1
  68. package/dist/inskinBidAdapter.js +1 -1
  69. package/dist/insticatorBidAdapter.js +1 -1
  70. package/dist/invisiblyAnalyticsAdapter.js +1 -1
  71. package/dist/ixBidAdapter.js +1 -1
  72. package/dist/jixieBidAdapter.js +1 -1
  73. package/dist/justpremiumBidAdapter.js +1 -1
  74. package/dist/kargoAnalyticsAdapter.js +1 -1
  75. package/dist/kargoBidAdapter.js +1 -1
  76. package/dist/koblerBidAdapter.js +1 -1
  77. package/dist/konduitAnalyticsAdapter.js +1 -1
  78. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  79. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  80. package/dist/logicadBidAdapter.js +1 -1
  81. package/dist/loglyliftBidAdapter.js +1 -1
  82. package/dist/malltvAnalyticsAdapter.js +1 -1
  83. package/dist/mantisBidAdapter.js +1 -1
  84. package/dist/marsmediaAnalyticsAdapter.js +1 -1
  85. package/dist/marsmediaBidAdapter.js +1 -1
  86. package/dist/mediafuseBidAdapter.js +1 -1
  87. package/dist/mediakeysBidAdapter.js +1 -1
  88. package/dist/medianetAnalyticsAdapter.js +1 -1
  89. package/dist/medianetBidAdapter.js +1 -1
  90. package/dist/medianetRtdProvider.js +1 -1
  91. package/dist/mediasquareBidAdapter.js +1 -1
  92. package/dist/merkleIdSystem.js +1 -1
  93. package/dist/mgidBidAdapter.js +1 -1
  94. package/dist/minutemediaBidAdapter.js +1 -1
  95. package/dist/naveggIdSystem.js +1 -1
  96. package/dist/not-for-prod/prebid.js +178 -176
  97. package/dist/novatiqIdSystem.js +1 -1
  98. package/dist/oguryBidAdapter.js +1 -1
  99. package/dist/oneVideoBidAdapter.js +1 -1
  100. package/dist/onetagBidAdapter.js +1 -1
  101. package/dist/ooloAnalyticsAdapter.js +1 -1
  102. package/dist/openxAnalyticsAdapter.js +1 -1
  103. package/dist/optimonAnalyticsAdapter.js +1 -1
  104. package/dist/outbrainBidAdapter.js +1 -1
  105. package/dist/parrableIdSystem.js +1 -1
  106. package/dist/pixfutureBidAdapter.js +1 -1
  107. package/dist/prebid-core.js +3 -3
  108. package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
  109. package/dist/pubCommonId.js +1 -1
  110. package/dist/publinkIdSystem.js +1 -1
  111. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  112. package/dist/pubmaticBidAdapter.js +1 -1
  113. package/dist/pubperfAnalyticsAdapter.js +1 -1
  114. package/dist/pubstackAnalyticsAdapter.js +1 -1
  115. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  116. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  117. package/dist/pulsepointAnalyticsAdapter.js +1 -1
  118. package/dist/pxyzBidAdapter.js +1 -1
  119. package/dist/quantcastBidAdapter.js +1 -1
  120. package/dist/readpeakBidAdapter.js +1 -1
  121. package/dist/realvuAnalyticsAdapter.js +1 -1
  122. package/dist/relaidoBidAdapter.js +1 -1
  123. package/dist/relevantAnalyticsAdapter.js +1 -1
  124. package/dist/rhythmoneBidAdapter.js +1 -1
  125. package/dist/riseBidAdapter.js +1 -1
  126. package/dist/rivrAnalyticsAdapter.js +1 -1
  127. package/dist/roxotAnalyticsAdapter.js +1 -1
  128. package/dist/rubiconAnalyticsAdapter.js +1 -1
  129. package/dist/rubiconBidAdapter.js +1 -1
  130. package/dist/scaleableAnalyticsAdapter.js +1 -1
  131. package/dist/seedingAllianceBidAdapter.js +1 -1
  132. package/dist/seedtagBidAdapter.js +1 -1
  133. package/dist/sharedIdSystem.js +1 -1
  134. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  135. package/dist/sharethroughBidAdapter.js +1 -1
  136. package/dist/sigmoidAnalyticsAdapter.js +1 -1
  137. package/dist/slimcutBidAdapter.js +1 -1
  138. package/dist/smaatoBidAdapter.js +1 -1
  139. package/dist/smartadserverBidAdapter.js +1 -1
  140. package/dist/smartxBidAdapter.js +1 -1
  141. package/dist/smilewantedBidAdapter.js +1 -1
  142. package/dist/sonobiAnalyticsAdapter.js +1 -1
  143. package/dist/sonobiBidAdapter.js +1 -1
  144. package/dist/sortableAnalyticsAdapter.js +1 -1
  145. package/dist/sortableBidAdapter.js +1 -1
  146. package/dist/sovrnAnalyticsAdapter.js +1 -1
  147. package/dist/sovrnBidAdapter.js +1 -1
  148. package/dist/spotxBidAdapter.js +1 -1
  149. package/dist/sspBCBidAdapter.js +1 -1
  150. package/dist/staqAnalyticsAdapter.js +1 -1
  151. package/dist/sublimeBidAdapter.js +1 -1
  152. package/dist/synacormediaBidAdapter.js +1 -1
  153. package/dist/taboolaBidAdapter.js +1 -0
  154. package/dist/targetVideoBidAdapter.js +1 -1
  155. package/dist/teadsBidAdapter.js +1 -1
  156. package/dist/telariaBidAdapter.js +1 -1
  157. package/dist/terceptAnalyticsAdapter.js +1 -1
  158. package/dist/trionBidAdapter.js +1 -1
  159. package/dist/tripleliftBidAdapter.js +1 -1
  160. package/dist/trustxBidAdapter.js +1 -1
  161. package/dist/ttdBidAdapter.js +1 -1
  162. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  163. package/dist/underdogmediaBidAdapter.js +1 -1
  164. package/dist/undertoneBidAdapter.js +1 -1
  165. package/dist/userId.js +1 -1
  166. package/dist/vidazooBidAdapter.js +1 -1
  167. package/dist/videobyteBidAdapter.js +1 -1
  168. package/dist/visxBidAdapter.js +1 -1
  169. package/dist/vuukleBidAdapter.js +1 -1
  170. package/dist/widespaceBidAdapter.js +1 -1
  171. package/dist/winrBidAdapter.js +1 -1
  172. package/dist/yahoosspBidAdapter.js +1 -1
  173. package/dist/yieldmoBidAdapter.js +1 -1
  174. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  175. package/dist/yuktamediaAnalyticsAdapter.js +1 -1
  176. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  177. package/dist/zeta_global_sspBidAdapter.js +1 -1
  178. package/integrationExamples/gpt/akamaidap_segments_example.html +5 -3
  179. package/modules/.submodules.json +1 -0
  180. package/modules/adfBidAdapter.js +0 -3
  181. package/modules/adlooxAnalyticsAdapter.js +9 -5
  182. package/modules/adlooxAnalyticsAdapter.md +3 -3
  183. package/modules/adlooxRtdProvider.js +3 -5
  184. package/modules/adlooxRtdProvider.md +2 -2
  185. package/modules/adoceanBidAdapter.js +29 -1
  186. package/modules/adyoulikeBidAdapter.js +3 -0
  187. package/modules/akamaiDapRtdProvider.js +469 -139
  188. package/modules/akamaiDapRtdProvider.md +5 -3
  189. package/modules/automatadBidAdapter.js +9 -5
  190. package/modules/colossussspBidAdapter.js +17 -17
  191. package/modules/conversantBidAdapter.js +2 -2
  192. package/modules/criteoBidAdapter.js +1 -1
  193. package/modules/ftrackIdSystem.js +5 -8
  194. package/modules/gdprEnforcement.js +15 -9
  195. package/modules/gridBidAdapter.js +4 -0
  196. package/modules/hadronAnalyticsAdapter.js +5 -1
  197. package/modules/hadronRtdProvider.js +15 -13
  198. package/modules/incrxBidAdapter.js +87 -0
  199. package/modules/{vertozBidAdapter.md → incrxBidAdapter.md} +6 -6
  200. package/modules/inskinBidAdapter.js +4 -3
  201. package/modules/insticatorBidAdapter.js +109 -42
  202. package/modules/ixBidAdapter.js +3 -2
  203. package/modules/ixBidAdapter.md +1 -1
  204. package/modules/kargoBidAdapter.js +32 -1
  205. package/modules/koblerBidAdapter.js +54 -45
  206. package/modules/koblerBidAdapter.md +12 -17
  207. package/modules/mantisBidAdapter.js +4 -8
  208. package/modules/medianetBidAdapter.js +2 -2
  209. package/modules/medianetRtdProvider.js +4 -6
  210. package/modules/merkleIdSystem.js +43 -31
  211. package/modules/naveggIdSystem.js +3 -2
  212. package/modules/novatiqIdSystem.js +6 -1
  213. package/modules/pubCommonId.js +2 -1
  214. package/modules/pubmaticAnalyticsAdapter.js +49 -33
  215. package/modules/relaidoBidAdapter.js +0 -3
  216. package/modules/sharedIdSystem.js +5 -11
  217. package/modules/slimcutBidAdapter.js +2 -2
  218. package/modules/spotxBidAdapter.js +1 -1
  219. package/modules/synacormediaBidAdapter.js +11 -2
  220. package/modules/taboolaBidAdapter.js +265 -0
  221. package/modules/taboolaBidAdapter.md +49 -0
  222. package/modules/telariaBidAdapter.js +3 -3
  223. package/modules/userId/eids.js +25 -5
  224. package/modules/zeta_global_sspBidAdapter.js +3 -2
  225. package/package.json +1 -1
  226. package/src/AnalyticsAdapter.js +5 -1
  227. package/src/adloader.js +6 -1
  228. package/src/storageManager.js +5 -4
  229. package/test/mocks/analyticsStub.js +13 -0
  230. package/test/mocks/xhr.js +22 -0
  231. package/test/spec/AnalyticsAdapter_spec.js +4 -0
  232. package/test/spec/modules/adfBidAdapter_spec.js +1 -1
  233. package/test/spec/modules/adoceanBidAdapter_spec.js +25 -1
  234. package/test/spec/modules/adriverIdSystem_spec.js +7 -3
  235. package/test/spec/modules/adyoulikeBidAdapter_spec.js +16 -1
  236. package/test/spec/modules/akamaiDapRtdProvider_spec.js +457 -109
  237. package/test/spec/modules/automatadBidAdapter_spec.js +4 -0
  238. package/test/spec/modules/conversantBidAdapter_spec.js +36 -5
  239. package/test/spec/modules/datablocksBidAdapter_spec.js +9 -8
  240. package/test/spec/modules/eids_spec.js +48 -3
  241. package/test/spec/modules/fintezaAnalyticsAdapter_spec.js +4 -4
  242. package/test/spec/modules/ftrackIdSystem_spec.js +11 -22
  243. package/test/spec/modules/gdprEnforcement_spec.js +100 -53
  244. package/test/spec/modules/gridBidAdapter_spec.js +11 -0
  245. package/test/spec/modules/incrxBidAdapter_spec.js +100 -0
  246. package/test/spec/modules/insticatorBidAdapter_spec.js +46 -1
  247. package/test/spec/modules/ixBidAdapter_spec.js +1 -1
  248. package/test/spec/modules/kargoBidAdapter_spec.js +27 -0
  249. package/test/spec/modules/koblerBidAdapter_spec.js +160 -124
  250. package/test/spec/modules/medianetRtdProvider_spec.js +146 -0
  251. package/test/spec/modules/merkleIdSystem_spec.js +58 -37
  252. package/test/spec/modules/naveggIdSystem_spec.js +25 -1
  253. package/test/spec/modules/proxistoreBidAdapter_spec.js +0 -2
  254. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +117 -0
  255. package/test/spec/modules/sovrnBidAdapter_spec.js +253 -264
  256. package/test/spec/modules/synacormediaBidAdapter_spec.js +74 -0
  257. package/test/spec/modules/taboolaBidAdapter_spec.js +455 -0
  258. package/test/spec/modules/userId_spec.js +27 -1
  259. package/test/spec/modules/vidazooBidAdapter_spec.js +9 -4
  260. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +4 -2
  261. package/test/test_deps.js +1 -0
@@ -0,0 +1,265 @@
1
+ 'use strict';
2
+
3
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
4
+ import {BANNER} from '../src/mediaTypes.js';
5
+ import {config} from '../src/config.js';
6
+ import {getWindowSelf, getWindowTop} from '../src/utils.js'
7
+ import {getStorageManager} from '../src/storageManager.js';
8
+
9
+ const BIDDER_CODE = 'taboola';
10
+ const GVLID = 42;
11
+ const CURRENCY = 'USD';
12
+ export const END_POINT_URL = 'https://hb.bidder.taboola.com/TaboolaHBOpenRTBRequestHandlerServlet';
13
+ const USER_ID = 'user-id';
14
+ const STORAGE_KEY = `taboola global:${USER_ID}`;
15
+ const COOKIE_KEY = 'trc_cookie_storage';
16
+
17
+ /**
18
+ * extract User Id by that order:
19
+ * 1. local storage
20
+ * 2. first party cookie
21
+ * 3. rendered trc
22
+ * 4. new user set it to 0
23
+ */
24
+ export const userData = {
25
+ storageManager: getStorageManager({gvlid: GVLID, bidderCode: BIDDER_CODE}),
26
+ getUserId: () => {
27
+ const {getFromLocalStorage, getFromCookie, getFromTRC} = userData;
28
+
29
+ try {
30
+ return getFromLocalStorage() || getFromCookie() || getFromTRC();
31
+ } catch (ex) {
32
+ return 0;
33
+ }
34
+ },
35
+ getFromCookie() {
36
+ const {cookiesAreEnabled, getCookie} = userData.storageManager;
37
+ if (cookiesAreEnabled()) {
38
+ const cookieData = getCookie(COOKIE_KEY);
39
+ const userId = userData.getCookieDataByKey(cookieData, USER_ID);
40
+ if (userId) {
41
+ return userId;
42
+ }
43
+ }
44
+ },
45
+ getCookieDataByKey(cookieData, key) {
46
+ const [, value = ''] = cookieData.split(`${key}=`)
47
+ return value;
48
+ },
49
+ getFromLocalStorage() {
50
+ const {hasLocalStorage, localStorageIsEnabled, getDataFromLocalStorage} = userData.storageManager;
51
+
52
+ if (hasLocalStorage() && localStorageIsEnabled()) {
53
+ return getDataFromLocalStorage(STORAGE_KEY);
54
+ }
55
+ },
56
+ getFromTRC() {
57
+ return window.TRC ? window.TRC.user_id : 0;
58
+ }
59
+ }
60
+
61
+ export const internal = {
62
+ getPageUrl: (refererInfo = {}) => {
63
+ if (refererInfo.canonicalUrl) {
64
+ return refererInfo.canonicalUrl;
65
+ }
66
+
67
+ if (config.getConfig('pageUrl')) {
68
+ return config.getConfig('pageUrl');
69
+ }
70
+
71
+ try {
72
+ return getWindowTop().location.href;
73
+ } catch (e) {
74
+ return getWindowSelf().location.href;
75
+ }
76
+ },
77
+ getReferrer: (refererInfo = {}) => {
78
+ if (refererInfo.referer) {
79
+ return refererInfo.referer;
80
+ }
81
+
82
+ try {
83
+ return getWindowTop().document.referrer;
84
+ } catch (e) {
85
+ return getWindowSelf().document.referrer;
86
+ }
87
+ }
88
+ }
89
+
90
+ export const spec = {
91
+ supportedMediaTypes: [BANNER],
92
+ gvlid: GVLID,
93
+ code: BIDDER_CODE,
94
+ isBidRequestValid: (bidRequest) => {
95
+ return !!(bidRequest.sizes &&
96
+ bidRequest.params &&
97
+ bidRequest.params.publisherId &&
98
+ bidRequest.params.tagId);
99
+ },
100
+ buildRequests: (validBidRequests, bidderRequest) => {
101
+ const [bidRequest] = validBidRequests;
102
+ const {refererInfo, gdprConsent = {}, uspConsent} = bidderRequest;
103
+ const {publisherId} = bidRequest.params;
104
+ const site = getSiteProperties(bidRequest.params, refererInfo);
105
+ const device = {ua: navigator.userAgent};
106
+ const imps = getImps(validBidRequests);
107
+ const user = {
108
+ buyeruid: userData.getUserId(gdprConsent, uspConsent),
109
+ ext: {}
110
+ };
111
+ const regs = {
112
+ coppa: 0,
113
+ ext: {}
114
+ };
115
+
116
+ if (gdprConsent.gdprApplies) {
117
+ user.ext.consent = bidderRequest.gdprConsent.consentString;
118
+ regs.ext.gdpr = 1;
119
+ }
120
+
121
+ if (uspConsent) {
122
+ regs.ext.us_privacy = uspConsent;
123
+ }
124
+
125
+ if (config.getConfig('coppa')) {
126
+ regs.coppa = 1
127
+ }
128
+
129
+ const ortb2 = config.getConfig('ortb2') || {
130
+ badv: [],
131
+ bcat: []
132
+ };
133
+
134
+ const request = {
135
+ id: bidderRequest.auctionId,
136
+ imp: imps,
137
+ site,
138
+ device,
139
+ source: {fd: 1},
140
+ tmax: bidderRequest.timeout,
141
+ bcat: ortb2.bcat,
142
+ badv: ortb2.badv,
143
+ user,
144
+ regs
145
+ };
146
+
147
+ const url = [END_POINT_URL, publisherId].join('/');
148
+
149
+ return {
150
+ url,
151
+ method: 'POST',
152
+ data: JSON.stringify(request),
153
+ bids: validBidRequests,
154
+ options: {
155
+ withCredentials: false
156
+ },
157
+ };
158
+ },
159
+ interpretResponse: (serverResponse, {bids}) => {
160
+ if (!bids) {
161
+ return [];
162
+ }
163
+
164
+ const {bidResponses, cur: currency} = getBidResponses(serverResponse);
165
+
166
+ if (!bidResponses) {
167
+ return [];
168
+ }
169
+
170
+ return bids.map((bid, id) => getBid(bid.bidId, currency, bidResponses[id])).filter(Boolean);
171
+ },
172
+ };
173
+
174
+ function getSiteProperties({publisherId, bcat = []}, refererInfo) {
175
+ const {getPageUrl, getReferrer} = internal;
176
+ return {
177
+ id: publisherId,
178
+ name: publisherId,
179
+ domain: window.location.host,
180
+ page: getPageUrl(refererInfo),
181
+ ref: getReferrer(refererInfo),
182
+ publisher: {
183
+ id: publisherId
184
+ },
185
+ content: {
186
+ language: navigator.language
187
+ }
188
+ }
189
+ }
190
+
191
+ function getImps(validBidRequests) {
192
+ return validBidRequests.map((bid, id) => {
193
+ const {tagId, bidfloor = null, bidfloorcur = CURRENCY} = bid.params;
194
+
195
+ return {
196
+ id: id + 1,
197
+ banner: getBanners(bid),
198
+ tagid: tagId,
199
+ bidfloor,
200
+ bidfloorcur,
201
+ };
202
+ });
203
+ }
204
+
205
+ function getBanners(bid) {
206
+ return getSizes(bid.sizes);
207
+ }
208
+
209
+ function getSizes(sizes) {
210
+ return {
211
+ format: sizes.map(size => {
212
+ return {
213
+ w: size[0],
214
+ h: size[1]
215
+ }
216
+ })
217
+ }
218
+ }
219
+
220
+ function getBidResponses({body}) {
221
+ if (!body) {
222
+ return [];
223
+ }
224
+
225
+ const {seatbid, cur} = body;
226
+
227
+ if (!seatbid.length || !seatbid[0].bid) {
228
+ return [];
229
+ }
230
+
231
+ return {
232
+ bidResponses: seatbid[0].bid,
233
+ cur
234
+ };
235
+ }
236
+
237
+ function getBid(requestId, currency, bidResponse) {
238
+ if (!bidResponse) {
239
+ return;
240
+ }
241
+
242
+ const {
243
+ price: cpm, crid: creativeId, adm: ad, w: width, h: height, adomain: advertiserDomains, meta = {}
244
+ } = bidResponse;
245
+
246
+ if (advertiserDomains && advertiserDomains.length > 0) {
247
+ meta.advertiserDomains = advertiserDomains
248
+ }
249
+
250
+ return {
251
+ requestId,
252
+ ttl: 360,
253
+ mediaType: BANNER,
254
+ cpm,
255
+ creativeId,
256
+ currency,
257
+ ad,
258
+ width,
259
+ height,
260
+ meta,
261
+ netRevenue: false
262
+ };
263
+ }
264
+
265
+ registerBidder(spec);
@@ -0,0 +1,49 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Taboola Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: prebid@taboola.com
7
+ ```
8
+
9
+ # Description
10
+
11
+ Module that connects to Taboola bidder to fetch bids.
12
+ - Supports `display` format
13
+ - Uses `OpenRTB` standard
14
+
15
+ The Taboola Bidding adapter requires setup before beginning. Please contact us on prebid@taboola.com
16
+
17
+ # Test Display Parameters
18
+ ``` javascript
19
+ var adUnits = [{
20
+ code: 'your-unit-container-id',
21
+ mediaTypes: {
22
+ banner: {
23
+ sizes: [[300, 250], [300,600]]
24
+ }
25
+ },
26
+ bids: [{
27
+ bidder: 'taboola',
28
+ params: {
29
+ tagId: 'tester-placement', // Placement Name
30
+ publisherId: 'tester-pub', // your-publisher-id
31
+ bidfloor: 0.25, // Optional - default is null
32
+ bcat: ['IAB1-1'], // Optional - default is []
33
+ badv: ['example.com'] // Optional - default is []
34
+ }
35
+ }]
36
+ }];
37
+ ```
38
+
39
+ # Parameters
40
+
41
+ | Name | Scope | Description | Example | Type |
42
+ |----------------|----------|---------------------------------------------------------|----------------------------|--------------|
43
+ | `tagId` | required | Tag ID / Placement Name <br>(as provided by Taboola) | `'Below The Article'` | `String` |
44
+ | `publisherId` | required | Alphabetic Publisher ID <br>(as provided by Taboola) | `'acme-publishing'` | `String` |
45
+ | `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `Array` |
46
+ | `badv` | optional | Blocked Advertiser Domains | `'example.com'` | `String Url` |
47
+ | `bidfloor` | optional | CPM bid floor | `0.25` | `Integer` |
48
+
49
+
@@ -9,10 +9,10 @@ const EVENTS_ENDPOINT = `events.${DOMAIN}/diag`;
9
9
 
10
10
  export const spec = {
11
11
  code: BIDDER_CODE,
12
- gvlid: 52,
12
+ gvlid: 202,
13
13
  aliases: [
14
- { code: 'tremor', gvlid: 52 },
15
- { code: 'tremorvideo', gvlid: 52 }
14
+ { code: 'tremor', gvlid: 202 },
15
+ { code: 'tremorvideo', gvlid: 202 }
16
16
  ],
17
17
  supportedMediaTypes: [VIDEO],
18
18
  /**
@@ -151,15 +151,25 @@ export const USER_IDS_CONFIG = {
151
151
 
152
152
  // merkleId
153
153
  'merkleId': {
154
- source: 'merkleinc.com',
155
154
  atype: 3,
155
+ getSource: function(data) {
156
+ if (data?.ext?.ssp) {
157
+ return `${data.ext.ssp}.merkleinc.com`
158
+ }
159
+ return 'merkleinc.com'
160
+ },
156
161
  getValue: function(data) {
157
162
  return data.id;
158
163
  },
159
164
  getUidExt: function(data) {
160
- return (data && data.keyID) ? {
161
- keyID: data.keyID
162
- } : undefined;
165
+ if (data.keyID) {
166
+ return {
167
+ keyID: data.keyID
168
+ }
169
+ }
170
+ if (data.ext) {
171
+ return data.ext;
172
+ }
163
173
  }
164
174
  },
165
175
 
@@ -327,7 +337,8 @@ function createEidObject(userIdData, subModuleKey) {
327
337
  const conf = USER_IDS_CONFIG[subModuleKey];
328
338
  if (conf && userIdData) {
329
339
  let eid = {};
330
- eid.source = conf['source'];
340
+ eid.source = isFn(conf['getSource']) ? conf['getSource'](userIdData) : conf['source'];
341
+
331
342
  const value = isFn(conf['getValue']) ? conf['getValue'](userIdData) : userIdData;
332
343
  if (isStr(value)) {
333
344
  const uid = { id: value, atype: conf['atype'] };
@@ -357,10 +368,19 @@ function createEidObject(userIdData, subModuleKey) {
357
368
  // if any adapter does not want any particular userId to be passed then adapter can use Array.filter(e => e.source != 'tdid')
358
369
  export function createEidsArray(bidRequestUserId) {
359
370
  let eids = [];
371
+
360
372
  for (const subModuleKey in bidRequestUserId) {
361
373
  if (bidRequestUserId.hasOwnProperty(subModuleKey)) {
362
374
  if (subModuleKey === 'pubProvidedId') {
363
375
  eids = eids.concat(bidRequestUserId['pubProvidedId']);
376
+ } else if (Array.isArray(bidRequestUserId[subModuleKey])) {
377
+ bidRequestUserId[subModuleKey].forEach((config, index, arr) => {
378
+ const eid = createEidObject(config, subModuleKey);
379
+
380
+ if (eid) {
381
+ eids.push(eid);
382
+ }
383
+ })
364
384
  } else {
365
385
  const eid = createEidObject(bidRequestUserId[subModuleKey], subModuleKey);
366
386
  if (eid) {
@@ -99,7 +99,7 @@ export const spec = {
99
99
  user: params.user ? params.user : {},
100
100
  app: params.app ? params.app : {},
101
101
  ext: {
102
- tags: {...params.tags, shortname: params.shortname},
102
+ tags: params.tags ? params.tags : {},
103
103
  sid: params.sid ? params.sid : undefined
104
104
  }
105
105
  };
@@ -126,9 +126,10 @@ export const spec = {
126
126
  }
127
127
 
128
128
  provideEids(request, payload);
129
+ const url = params.shortname ? ENDPOINT_URL.concat('?shortname=', params.shortname) : ENDPOINT_URL;
129
130
  return {
130
131
  method: 'POST',
131
- url: ENDPOINT_URL,
132
+ url: url,
132
133
  data: JSON.stringify(payload),
133
134
  };
134
135
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "6.26.0",
3
+ "version": "6.29.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -3,6 +3,10 @@ import { ajax } from './ajax.js';
3
3
  import { logMessage, _each } from './utils.js';
4
4
  import * as events from './events.js'
5
5
 
6
+ export const _internal = {
7
+ ajax
8
+ };
9
+
6
10
  const {
7
11
  EVENTS: {
8
12
  AUCTION_INIT,
@@ -61,7 +65,7 @@ export default function AnalyticsAdapter({ url, analyticsType, global, handler }
61
65
  }
62
66
 
63
67
  function _callEndpoint({ eventType, args, callback }) {
64
- ajax(url, callback, JSON.stringify({ eventType, args }));
68
+ _internal.ajax(url, callback, JSON.stringify({ eventType, args }));
65
69
  }
66
70
 
67
71
  function _enqueue({ eventType, args }) {
package/src/adloader.js CHANGED
@@ -10,7 +10,12 @@ const _approvedLoadExternalJSList = [
10
10
  'adagio',
11
11
  'browsi',
12
12
  'brandmetrics',
13
- 'justtag'
13
+ 'justtag',
14
+ 'akamaidap',
15
+ 'ftrackId',
16
+ 'inskin',
17
+ 'hadron',
18
+ 'medianet'
14
19
  ]
15
20
 
16
21
  /**
@@ -48,7 +48,7 @@ export function newStorageManager({gvlid, moduleName, bidderCode, moduleType} =
48
48
  let hookDetails = {
49
49
  hasEnforcementHook: false
50
50
  }
51
- validateStorageEnforcement(gvlid, bidderCode || moduleName, hookDetails, function(result) {
51
+ validateStorageEnforcement(gvlid, bidderCode || moduleName, moduleType, hookDetails, function(result) {
52
52
  if (result && result.hasEnforcementHook) {
53
53
  value = cb(result);
54
54
  } else {
@@ -303,7 +303,7 @@ export function newStorageManager({gvlid, moduleName, bidderCode, moduleType} =
303
303
  /**
304
304
  * This hook validates the storage enforcement if gdprEnforcement module is included
305
305
  */
306
- export const validateStorageEnforcement = hook('async', function(gvlid, moduleName, hookDetails, callback) {
306
+ export const validateStorageEnforcement = hook('async', function(gvlid, moduleName, moduleType, hookDetails, callback) {
307
307
  callback(hookDetails);
308
308
  }, 'validateStorageEnforcement');
309
309
 
@@ -322,12 +322,13 @@ export function getCoreStorageManager(moduleName) {
322
322
  * @param {Number=} gvlid? Vendor id - required for proper GDPR integration
323
323
  * @param {string=} bidderCode? - required for bid adapters
324
324
  * @param {string=} moduleName? module name
325
+ * @param {string=} moduleType? module type
325
326
  */
326
- export function getStorageManager({gvlid, moduleName, bidderCode} = {}) {
327
+ export function getStorageManager({gvlid, moduleName, bidderCode, moduleType} = {}) {
327
328
  if (arguments.length > 1 || (arguments.length > 0 && !isPlainObject(arguments[0]))) {
328
329
  throw new Error('Invalid invocation for getStorageManager')
329
330
  }
330
- return newStorageManager({gvlid, moduleName, bidderCode});
331
+ return newStorageManager({gvlid, moduleName, bidderCode, moduleType});
331
332
  }
332
333
 
333
334
  export function resetData() {
@@ -0,0 +1,13 @@
1
+ import {_internal} from '../../src/AnalyticsAdapter.js';
2
+
3
+ before(() => {
4
+ // stub out analytics networking to avoid random events polluting the global xhr mock
5
+ disableAjaxForAnalytics();
6
+ })
7
+
8
+ export function disableAjaxForAnalytics() {
9
+ sinon.stub(_internal, 'ajax').callsFake(() => null);
10
+ }
11
+ export function enableAjaxForAnalytics() {
12
+ _internal.ajax.restore();
13
+ }
package/test/mocks/xhr.js CHANGED
@@ -1,3 +1,4 @@
1
+ import {getUniqueIdentifierStr} from '../../src/utils.js';
1
2
 
2
3
  export let server = sinon.createFakeServer();
3
4
  export let xhr = global.XMLHttpRequest;
@@ -7,3 +8,24 @@ beforeEach(function() {
7
8
  server = sinon.createFakeServer();
8
9
  xhr = global.XMLHttpRequest;
9
10
  });
11
+
12
+ const bid = getUniqueIdentifierStr().substring(4);
13
+ let fid = 0;
14
+
15
+ /* eslint-disable */
16
+ afterEach(function () {
17
+ if (this?.currentTest?.state === 'failed') {
18
+ const prepend = (() => {
19
+ const preamble = `[Failure ${bid}-${fid++}]`;
20
+ return (s) => s.split('\n').map(s => `${preamble} ${s}`).join('\n');
21
+ })();
22
+
23
+
24
+ console.log(prepend(`XHR mock state after failure (for test '${this.currentTest.fullTitle()}'): ${server.requests.length} requests`))
25
+ server.requests.forEach((req, i) => {
26
+ console.log(prepend(`Request #${i}:`));
27
+ console.log(prepend(JSON.stringify(req, null, 2)));
28
+ })
29
+ }
30
+ });
31
+ /* eslint-enable */
@@ -2,6 +2,7 @@ import { expect } from 'chai';
2
2
  import * as events from 'src/events.js';
3
3
  import CONSTANTS from 'src/constants.json';
4
4
  import { server } from 'test/mocks/xhr.js';
5
+ import {disableAjaxForAnalytics, enableAjaxForAnalytics} from '../mocks/analyticsStub.js';
5
6
 
6
7
  const REQUEST_BIDS = CONSTANTS.EVENTS.REQUEST_BIDS;
7
8
  const BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED;
@@ -25,6 +26,9 @@ FEATURE: Analytics Adapters API
25
26
  AND an \`example\` instance of \`AnalyticsAdapter\`\n`, () => {
26
27
  let adapter;
27
28
 
29
+ before(enableAjaxForAnalytics);
30
+ after(disableAjaxForAnalytics);
31
+
28
32
  beforeEach(function () {
29
33
  adapter = new AnalyticsAdapter(config);
30
34
  });
@@ -75,7 +75,7 @@ describe('Adf adapter', function () {
75
75
 
76
76
  assert.equal(request.method, 'POST');
77
77
  assert.equal(request.url, 'https://10.8.57.207/adx/openrtb');
78
- assert.deepEqual(request.options, {contentType: 'application/json'});
78
+ assert.equal(request.options, undefined);
79
79
  assert.ok(request.data);
80
80
  });
81
81
 
@@ -83,6 +83,20 @@ describe('AdoceanAdapter', function () {
83
83
  'auctionId': '1d1a030790a475',
84
84
  }
85
85
  ];
86
+ const schainExample = {
87
+ 'schain': {
88
+ ver: '1.0',
89
+ complete: 1,
90
+ nodes: [
91
+ {
92
+ asi: 'directseller.com',
93
+ sid: '00001!,2',
94
+ rid: 'BidRequest1',
95
+ hp: 1
96
+ }
97
+ ]
98
+ }
99
+ };
86
100
 
87
101
  const bidderRequest = {
88
102
  gdprConsent: {
@@ -134,7 +148,17 @@ describe('AdoceanAdapter', function () {
134
148
  expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600-myaowafpdwlrks~300x200_600x250');
135
149
  expect((requests[0].url.match(/aosspsizes=/g) || []).length).to.equal(1);
136
150
  });
137
- })
151
+
152
+ it('should attach schain parameter if available', function() {
153
+ let requests = spec.buildRequests(bidRequests, bidderRequest);
154
+ expect(requests.some(e => e.url.includes('schain='))).to.be.false;
155
+
156
+ const bidsWithSchain = deepClone(bidRequests).map(e => ({...e, ...schainExample}));
157
+ requests = spec.buildRequests(bidsWithSchain, bidderRequest);
158
+ expect(requests.every(e => e.url.includes('schain=1.0,1!directseller.com,00001%21%2C2,1,BidRequest1,,,0')),
159
+ `One of urls does not contain valid schain param: ${requests.map(e => e.url).join('\n')}`).to.be.true;
160
+ });
161
+ });
138
162
 
139
163
  describe('interpretResponse', function () {
140
164
  const response = {
@@ -67,12 +67,16 @@ describe('AdriverIdSystem', function () {
67
67
  let request = server.requests[0];
68
68
  request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ adrcid: response.adrcid }));
69
69
 
70
- let now = new Date();
71
- now.setTime(now.getTime() + 86400 * 1825 * 1000);
70
+ let expectedExpiration = new Date();
71
+ expectedExpiration.setTime(expectedExpiration.getTime() + 86400 * 1825 * 1000);
72
72
  const minimalDate = new Date(0).toString();
73
73
 
74
+ function dateStringFor(date, maxDeltaMs = 2000) {
75
+ return sinon.match((val) => Math.abs(date.getTime() - new Date(val).getTime()) <= maxDeltaMs)
76
+ }
77
+
74
78
  if (response.adrcid) {
75
- expect(setCookieStub.calledWith('adrcid', response.adrcid, now.toUTCString())).to.be.true;
79
+ expect(setCookieStub.calledWith('adrcid', response.adrcid, dateStringFor(expectedExpiration))).to.be.true;
76
80
  expect(setLocalStorageStub.calledWith('adrcid', response.adrcid)).to.be.true;
77
81
  } else {
78
82
  expect(setCookieStub.calledWith('adrcid', '', minimalDate)).to.be.false;
@@ -91,6 +91,20 @@ describe('Adyoulike Adapter', function () {
91
91
  }
92
92
  },
93
93
  },
94
+ 'schain': {
95
+ validation: 'strict',
96
+ config: {
97
+ ver: '1.0',
98
+ complete: 1,
99
+ nodes: [
100
+ {
101
+ asi: 'indirectseller.com',
102
+ sid: '00001',
103
+ hp: 1
104
+ }
105
+ ]
106
+ }
107
+ },
94
108
  'transactionId': 'bid_id_0_transaction_id'
95
109
  }
96
110
  ];
@@ -614,7 +628,7 @@ describe('Adyoulike Adapter', function () {
614
628
  expect(request.url).to.contain(getEndpoint());
615
629
  });
616
630
 
617
- it('should add gdpr/usp consent information to the request', function () {
631
+ it('should add gdpr/usp consent information and SChain to the request', function () {
618
632
  let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
619
633
  let uspConsentData = '1YCC';
620
634
  let bidderRequest = {
@@ -637,6 +651,7 @@ describe('Adyoulike Adapter', function () {
637
651
  expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString);
638
652
  expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true;
639
653
  expect(payload.uspConsent).to.exist.and.to.equal(uspConsentData);
654
+ expect(payload.Bids.bid_id_0.SChain).to.exist.and.to.deep.equal(bidRequestWithSinglePlacement[0].schain);
640
655
  });
641
656
 
642
657
  it('should not set a default value for gdpr consentRequired', function () {