prebid.js 7.52.0 → 7.54.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 (236) hide show
  1. package/dist/1plusXRtdProvider.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/adhashBidAdapter.js +1 -1
  8. package/dist/adkernelBidAdapter.js +1 -1
  9. package/dist/adqueryBidAdapter.js +1 -1
  10. package/dist/adrelevantisBidAdapter.js +1 -1
  11. package/dist/adtrgtmeBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/adyoulikeBidAdapter.js +1 -1
  14. package/dist/airgridRtdProvider.js +1 -1
  15. package/dist/ajaBidAdapter.js +1 -1
  16. package/dist/amxBidAdapter.js +1 -1
  17. package/dist/amxIdSystem.js +1 -1
  18. package/dist/appierAnalyticsAdapter.js +1 -1
  19. package/dist/appnexusBidAdapter.js +1 -1
  20. package/dist/asoBidAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/beopBidAdapter.js +1 -1
  23. package/dist/bidglassBidAdapter.js +1 -1
  24. package/dist/big-richmediaBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/carodaBidAdapter.js +1 -1
  28. package/dist/chtnwBidAdapter.js +1 -1
  29. package/dist/conceptxBidAdapter.js +1 -0
  30. package/dist/concertBidAdapter.js +1 -1
  31. package/dist/connectadBidAdapter.js +1 -1
  32. package/dist/consumableBidAdapter.js +1 -1
  33. package/dist/conversantAnalyticsAdapter.js +1 -1
  34. package/dist/conversantBidAdapter.js +1 -1
  35. package/dist/craftBidAdapter.js +1 -1
  36. package/dist/criteoBidAdapter.js +1 -1
  37. package/dist/cwireBidAdapter.js +1 -1
  38. package/dist/dspxBidAdapter.js +1 -1
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/eskimiBidAdapter.js +1 -1
  41. package/dist/euidIdSystem.js +1 -0
  42. package/dist/feedadBidAdapter.js +1 -1
  43. package/dist/finativeBidAdapter.js +1 -1
  44. package/dist/freepassIdSystem.js +1 -0
  45. package/dist/freewheel-sspBidAdapter.js +1 -1
  46. package/dist/glimpseBidAdapter.js +1 -1
  47. package/dist/gmosspBidAdapter.js +1 -1
  48. package/dist/goldbachBidAdapter.js +1 -1
  49. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  50. package/dist/greenbidsRtdProvider.js +1 -1
  51. package/dist/gridBidAdapter.js +1 -1
  52. package/dist/gumgumBidAdapter.js +1 -1
  53. package/dist/h12mediaBidAdapter.js +1 -1
  54. package/dist/hypelabBidAdapter.js +1 -0
  55. package/dist/id5IdSystem.js +1 -1
  56. package/dist/improvedigitalBidAdapter.js +1 -1
  57. package/dist/inmarBidAdapter.js +1 -1
  58. package/dist/insticatorBidAdapter.js +1 -1
  59. package/dist/ixBidAdapter.js +1 -1
  60. package/dist/justpremiumBidAdapter.js +1 -1
  61. package/dist/kargoBidAdapter.js +1 -1
  62. package/dist/konduitAnalyticsAdapter.js +1 -1
  63. package/dist/kueezBidAdapter.js +1 -1
  64. package/dist/kueezRtbBidAdapter.js +1 -1
  65. package/dist/kulturemediaBidAdapter.js +1 -1
  66. package/dist/lassoBidAdapter.js +1 -1
  67. package/dist/lifestreetBidAdapter.js +1 -1
  68. package/dist/limelightDigitalBidAdapter.js +1 -1
  69. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  70. package/dist/logicadBidAdapter.js +1 -1
  71. package/dist/loglyliftBidAdapter.js +1 -1
  72. package/dist/magniteAnalyticsAdapter.js +1 -1
  73. package/dist/malltvAnalyticsAdapter.js +1 -1
  74. package/dist/marsmediaBidAdapter.js +1 -1
  75. package/dist/mediafuseBidAdapter.js +1 -1
  76. package/dist/mediasquareBidAdapter.js +1 -1
  77. package/dist/mgidBidAdapter.js +1 -1
  78. package/dist/minutemediaBidAdapter.js +1 -1
  79. package/dist/minutemediaplusBidAdapter.js +1 -1
  80. package/dist/nexx360BidAdapter.js +1 -1
  81. package/dist/not-for-prod/prebid.js +153 -148
  82. package/dist/oguryBidAdapter.js +1 -1
  83. package/dist/onetagBidAdapter.js +1 -1
  84. package/dist/ooloAnalyticsAdapter.js +1 -1
  85. package/dist/optidigitalBidAdapter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/oxxionRtdProvider.js +1 -1
  88. package/dist/pairIdSystem.js +1 -1
  89. package/dist/parrableIdSystem.js +1 -1
  90. package/dist/pixfutureBidAdapter.js +1 -1
  91. package/dist/prebid-core.js +1 -1
  92. package/dist/proxistoreBidAdapter.js +1 -1
  93. package/dist/publinkIdSystem.js +1 -1
  94. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  95. package/dist/pubmaticBidAdapter.js +1 -1
  96. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  97. package/dist/pxyzBidAdapter.js +1 -1
  98. package/dist/quantcastBidAdapter.js +1 -1
  99. package/dist/readpeakBidAdapter.js +1 -1
  100. package/dist/relaidoBidAdapter.js +1 -1
  101. package/dist/retailspotBidAdapter.js +1 -1
  102. package/dist/rhythmoneBidAdapter.js +1 -1
  103. package/dist/richaudienceBidAdapter.js +1 -1
  104. package/dist/riseBidAdapter.js +1 -1
  105. package/dist/rubiconAnalyticsAdapter.js +1 -1
  106. package/dist/rubiconBidAdapter.js +1 -1
  107. package/dist/schain.js +1 -1
  108. package/dist/seedingAllianceBidAdapter.js +1 -1
  109. package/dist/seedtagBidAdapter.js +1 -1
  110. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  111. package/dist/sharethroughBidAdapter.js +1 -1
  112. package/dist/shinezBidAdapter.js +1 -1
  113. package/dist/sirdataRtdProvider.js +1 -1
  114. package/dist/smaatoBidAdapter.js +1 -1
  115. package/dist/smartadserverBidAdapter.js +1 -1
  116. package/dist/smartxBidAdapter.js +1 -1
  117. package/dist/smilewantedBidAdapter.js +1 -1
  118. package/dist/sonobiBidAdapter.js +1 -1
  119. package/dist/sovrnAnalyticsAdapter.js +1 -1
  120. package/dist/sovrnBidAdapter.js +1 -1
  121. package/dist/sspBCBidAdapter.js +1 -1
  122. package/dist/stroeerCoreBidAdapter.js +1 -1
  123. package/dist/stvBidAdapter.js +1 -1
  124. package/dist/sublimeBidAdapter.js +1 -1
  125. package/dist/synacormediaBidAdapter.js +1 -1
  126. package/dist/targetVideoBidAdapter.js +1 -1
  127. package/dist/teadsBidAdapter.js +1 -1
  128. package/dist/topicsFpdModule.js +1 -1
  129. package/dist/trionBidAdapter.js +1 -1
  130. package/dist/tripleliftBidAdapter.js +1 -1
  131. package/dist/ttdBidAdapter.js +1 -1
  132. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  133. package/dist/uid2IdSystem.js +1 -1
  134. package/dist/uid2IdSystem_shared.js +1 -0
  135. package/dist/underdogmediaBidAdapter.js +1 -1
  136. package/dist/undertoneBidAdapter.js +1 -1
  137. package/dist/userId.js +1 -1
  138. package/dist/vidazooBidAdapter.js +1 -1
  139. package/dist/videobyteBidAdapter.js +1 -1
  140. package/dist/videojsVideoProvider.js +1 -1
  141. package/dist/viouslyBidAdapter.js +1 -1
  142. package/dist/visxBidAdapter.js +1 -1
  143. package/dist/vrtcalBidAdapter.js +1 -1
  144. package/dist/vuukleBidAdapter.js +1 -1
  145. package/dist/weboramaRtdProvider.js +1 -1
  146. package/dist/widespaceBidAdapter.js +1 -1
  147. package/dist/winrBidAdapter.js +1 -1
  148. package/dist/yahoosspBidAdapter.js +1 -1
  149. package/dist/yieldlabBidAdapter.js +1 -1
  150. package/dist/yieldmoBidAdapter.js +1 -1
  151. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  152. package/dist/zeta_global_sspBidAdapter.js +1 -1
  153. package/integrationExamples/gpt/userId_example.html +20 -6
  154. package/modules/.submodules.json +3 -1
  155. package/modules/1plusXRtdProvider.js +31 -60
  156. package/modules/adagioBidAdapter.js +86 -24
  157. package/modules/adhashBidAdapter.js +56 -34
  158. package/modules/adkernelBidAdapter.js +2 -2
  159. package/modules/airgridRtdProvider.js +11 -12
  160. package/modules/asoBidAdapter.js +2 -1
  161. package/modules/beopBidAdapter.js +6 -0
  162. package/modules/conceptxBidAdapter.js +70 -0
  163. package/modules/conceptxBidAdapter.md +36 -0
  164. package/modules/criteoBidAdapter.js +9 -2
  165. package/modules/eskimiBidAdapter.js +171 -41
  166. package/modules/eskimiBidAdapter.md +35 -16
  167. package/modules/euidIdSystem.js +121 -0
  168. package/modules/euidIdSystem.md +131 -0
  169. package/modules/freepassIdSystem.js +61 -0
  170. package/modules/freepassIdSystem.md +47 -0
  171. package/modules/greenbidsAnalyticsAdapter.js +1 -1
  172. package/modules/hypelabBidAdapter.js +153 -0
  173. package/modules/hypelabBidAdapter.md +38 -0
  174. package/modules/id5IdSystem.js +3 -5
  175. package/modules/ixBidAdapter.js +12 -1
  176. package/modules/limelightDigitalBidAdapter.js +1 -1
  177. package/modules/logicadBidAdapter.js +14 -1
  178. package/modules/mediasquareBidAdapter.js +13 -5
  179. package/modules/nexx360BidAdapter.js +1 -0
  180. package/modules/oxxionRtdProvider.js +7 -29
  181. package/modules/pairIdSystem.js +10 -5
  182. package/modules/proxistoreBidAdapter.js +11 -14
  183. package/modules/pubmaticAnalyticsAdapter.js +31 -8
  184. package/modules/richaudienceBidAdapter.js +10 -1
  185. package/modules/riseBidAdapter.js +1 -1
  186. package/modules/schain.js +2 -2
  187. package/modules/sirdataRtdProvider.js +73 -146
  188. package/modules/sovrnBidAdapter.js +4 -1
  189. package/modules/stroeerCoreBidAdapter.js +55 -6
  190. package/modules/teadsBidAdapter.js +0 -1
  191. package/modules/topicsFpdModule.js +4 -1
  192. package/modules/uid2IdSystem.js +27 -210
  193. package/modules/uid2IdSystem.md +104 -23
  194. package/modules/uid2IdSystem_shared.js +232 -0
  195. package/modules/userId/eids.js +8 -0
  196. package/modules/userId/userId.md +2 -1
  197. package/modules/videojsVideoProvider.js +2 -0
  198. package/modules/viouslyBidAdapter.js +2 -2
  199. package/modules/vrtcalBidAdapter.js +5 -0
  200. package/modules/weboramaRtdProvider.js +25 -95
  201. package/modules/weboramaRtdProvider.md +4 -4
  202. package/modules/yieldlabBidAdapter.js +23 -14
  203. package/modules/zeta_global_sspBidAdapter.js +27 -22
  204. package/package.json +1 -1
  205. package/src/adloader.js +1 -0
  206. package/test/spec/modules/1plusXRtdProvider_spec.js +98 -149
  207. package/test/spec/modules/adagioBidAdapter_spec.js +46 -17
  208. package/test/spec/modules/adhashBidAdapter_spec.js +18 -2
  209. package/test/spec/modules/airgridRtdProvider_spec.js +2 -0
  210. package/test/spec/modules/beopBidAdapter_spec.js +24 -0
  211. package/test/spec/modules/conceptxBidAdapter_spec.js +136 -0
  212. package/test/spec/modules/criteoBidAdapter_spec.js +1 -1
  213. package/test/spec/modules/eids_spec.js +15 -0
  214. package/test/spec/modules/eskimiBidAdapter_spec.js +264 -112
  215. package/test/spec/modules/euidIdSystem_spec.js +130 -0
  216. package/test/spec/modules/freepassIdSystem_spec.js +186 -0
  217. package/test/spec/modules/hypelabBidAdapter_spec.js +281 -0
  218. package/test/spec/modules/id5IdSystem_spec.js +10 -3
  219. package/test/spec/modules/ixBidAdapter_spec.js +30 -0
  220. package/test/spec/modules/logicadBidAdapter_spec.js +122 -2
  221. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -0
  222. package/test/spec/modules/oxxionRtdProvider_spec.js +3 -2
  223. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +7 -0
  224. package/test/spec/modules/richaudienceBidAdapter_spec.js +44 -0
  225. package/test/spec/modules/schain_spec.js +9 -0
  226. package/test/spec/modules/sirdataRtdProvider_spec.js +110 -17
  227. package/test/spec/modules/sovrnBidAdapter_spec.js +13 -0
  228. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +151 -6
  229. package/test/spec/modules/teadsBidAdapter_spec.js +7 -0
  230. package/test/spec/modules/uid2IdSystem_helpers.js +70 -0
  231. package/test/spec/modules/uid2IdSystem_spec.js +131 -86
  232. package/test/spec/modules/userId_spec.js +16 -12
  233. package/test/spec/modules/vrtcalBidAdapter_spec.js +9 -2
  234. package/test/spec/modules/weboramaRtdProvider_spec.js +331 -205
  235. package/test/spec/modules/yieldlabBidAdapter_spec.js +42 -2
  236. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +200 -4
@@ -1,9 +1,9 @@
1
- import {registerBidder} from '../src/adapters/bidderFactory.js';
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
2
  import { getStorageManager } from '../src/storageManager.js';
3
3
  import { includes } from '../src/polyfill.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
5
 
6
- const VERSION = '3.2';
6
+ const VERSION = '3.6';
7
7
  const BAD_WORD_STEP = 0.1;
8
8
  const BAD_WORD_MIN = 0.2;
9
9
  const ADHASH_BIDDER_CODE = 'adhash';
@@ -19,6 +19,8 @@ const ADHASH_BIDDER_CODE = 'adhash';
19
19
  * @returns boolean flag is the page safe
20
20
  */
21
21
  function brandSafety(badWords, maxScore) {
22
+ const delimiter = '~';
23
+
22
24
  /**
23
25
  * Performs the ROT13 encoding on the string argument and returns the resulting string.
24
26
  * The Adhash bidder uses ROT13 so that the response is not blocked by:
@@ -40,17 +42,17 @@ function brandSafety(badWords, maxScore) {
40
42
  /**
41
43
  * Calculates the scoring for each bad word with dimishing returns
42
44
  * @param {integer} points points that this word costs
43
- * @param {integer} occurances number of occurances
45
+ * @param {integer} occurrences number of occurrences
44
46
  * @returns {float} final score
45
47
  */
46
- const scoreCalculator = (points, occurances) => {
48
+ const scoreCalculator = (points, occurrences) => {
47
49
  let positive = true;
48
50
  if (points < 0) {
49
51
  points *= -1;
50
52
  positive = false;
51
53
  }
52
54
  let result = 0;
53
- for (let i = 0; i < occurances; i++) {
55
+ for (let i = 0; i < occurrences; i++) {
54
56
  result += Math.max(points - i * BAD_WORD_STEP, BAD_WORD_MIN);
55
57
  }
56
58
  return positive ? result : -result;
@@ -60,22 +62,50 @@ function brandSafety(badWords, maxScore) {
60
62
  * Checks what rule will match in the given array with words
61
63
  * @param {string} rule rule type (full, partial, starts, ends, regexp)
62
64
  * @param {string} decodedWord decoded word
63
- * @param {array} wordsToMatch array to find a match
65
+ * @param {string} wordsToMatch list of all words on the page separated by delimiters
64
66
  * @returns {object|boolean} matched rule and occurances. If nothing is matched returns false
65
67
  */
66
68
  const wordsMatchedWithRule = function (rule, decodedWord, wordsToMatch) {
67
- if (rule === 'full' && wordsToMatch && wordsToMatch.includes(decodedWord)) {
68
- return { rule, occurances: wordsToMatch.filter(element => element === decodedWord).length };
69
- } else if (rule === 'partial' && wordsToMatch && wordsToMatch.some(element => element.indexOf(decodedWord) > -1)) {
70
- return { rule, occurances: wordsToMatch.filter(element => element.indexOf(decodedWord) > -1).length };
71
- } else if (rule === 'starts' && wordsToMatch && wordsToMatch.some(word => word.startsWith(decodedWord))) {
72
- return { rule, occurances: wordsToMatch.filter(element => element.startsWith(decodedWord)).length };
73
- } else if (rule === 'ends' && wordsToMatch && wordsToMatch.some(word => word.endsWith(decodedWord))) {
74
- return { rule, occurances: wordsToMatch.filter(element => element.endsWith(decodedWord)).length };
75
- } else if (rule === 'regexp' && wordsToMatch && wordsToMatch.some(element => element.match(new RegExp(decodedWord, 'i')))) {
76
- return { rule, occurances: wordsToMatch.filter(element => element.match(new RegExp(decodedWord, 'i'))).length };
69
+ if (!wordsToMatch) {
70
+ return false;
71
+ }
72
+
73
+ let occurrences;
74
+ let adjustedWordToMatch;
75
+ decodedWord = decodedWord.split(' ').join(`${delimiter}${delimiter}`);
76
+ switch (rule) {
77
+ case 'full':
78
+ adjustedWordToMatch = `${delimiter}${decodedWord}${delimiter}`;
79
+ break;
80
+ case 'partial':
81
+ adjustedWordToMatch = decodedWord;
82
+ break;
83
+ case 'starts':
84
+ adjustedWordToMatch = `${delimiter}${decodedWord}`;
85
+ break;
86
+ case 'ends':
87
+ adjustedWordToMatch = `${decodedWord}${delimiter}`;
88
+ break;
89
+ case 'combo':
90
+ const allOccurrences = [];
91
+ const paddedWordsToMatch = `${delimiter}${wordsToMatch}${delimiter}`;
92
+ const decodedWordsSplit = decodedWord.split(`${delimiter}${delimiter}`);
93
+ for (const decodedWordPart of decodedWordsSplit) {
94
+ adjustedWordToMatch = `${delimiter}${decodedWordPart}${delimiter}`;
95
+ allOccurrences.push(paddedWordsToMatch.split(adjustedWordToMatch).length - 1);
96
+ }
97
+ occurrences = Math.min(...allOccurrences);
98
+ return occurrences > 0 ? { rule, occurrences } : false;
99
+ case 'regexp':
100
+ occurrences = [...wordsToMatch.matchAll(new RegExp(decodedWord, 'gi'))].length;
101
+ return occurrences > 0 ? { rule, occurrences } : false;
102
+ default:
103
+ return false;
77
104
  }
78
- return false;
105
+
106
+ const paddedWordsToMatch = `${delimiter}${wordsToMatch}${delimiter}`;
107
+ occurrences = paddedWordsToMatch.split(adjustedWordToMatch).length - 1;
108
+ return occurrences > 0 ? { rule, occurrences } : false;
79
109
  };
80
110
 
81
111
  // Default parameters if the bidder is unable to send some of them
@@ -91,11 +121,11 @@ function brandSafety(badWords, maxScore) {
91
121
  .toLowerCase()
92
122
  .trim();
93
123
  const content = window.top.document.body.innerText.toLowerCase();
94
- const contentWords = content.trim().split(/\s+/).length;
95
124
  // \p{L} matches a single unicode code point in the category 'letter'. Matches any kind of letter from any language.
96
125
  const regexp = new RegExp('[\\p{L}]+', 'gu');
97
- const words = content.match(regexp);
98
- const wordsInUrl = wordsAndNumbersInUrl.match(regexp);
126
+ const wordsMatched = content.match(regexp);
127
+ const words = wordsMatched.join(`${delimiter}${delimiter}`);
128
+ const wordsInUrl = wordsAndNumbersInUrl.match(regexp).join(`${delimiter}${delimiter}`);
99
129
 
100
130
  for (const [word, rule, points] of badWords) {
101
131
  const decodedWord = rot13(word.toLowerCase());
@@ -110,19 +140,11 @@ function brandSafety(badWords, maxScore) {
110
140
 
111
141
  // Check if site content's words match any of our brand safety rules
112
142
  const matchedRule = wordsMatchedWithRule(rule, decodedWord, words);
113
- if (matchedRule.rule === 'full') {
114
- score += scoreCalculator(points, matchedRule.occurances);
115
- } else if (matchedRule.rule === 'partial') {
116
- score += scoreCalculator(points, matchedRule.occurances);
117
- } else if (matchedRule.rule === 'starts') {
118
- score += scoreCalculator(points, matchedRule.occurances);
119
- } else if (matchedRule.rule === 'ends') {
120
- score += scoreCalculator(points, matchedRule.occurances);
121
- } else if (matchedRule.rule === 'regexp') {
122
- score += scoreCalculator(points, matchedRule.occurances);
143
+ if (matchedRule !== false) {
144
+ score += scoreCalculator(points, matchedRule.occurrences);
123
145
  }
124
146
  }
125
- return score < (maxScore * contentWords) / 1000;
147
+ return score < (maxScore * wordsMatched.length) / 1000;
126
148
  } catch (e) {
127
149
  return true;
128
150
  }
@@ -183,8 +205,8 @@ export const spec = {
183
205
  }
184
206
 
185
207
  // Needed for the ad density calculation
186
- var adHeight = validBidRequests[i].sizes[index][1];
187
- var adWidth = validBidRequests[i].sizes[index][0];
208
+ const adHeight = validBidRequests[i].sizes[index][1];
209
+ const adWidth = validBidRequests[i].sizes[index][0];
188
210
  if (!window.adsCount) {
189
211
  window.adsCount = 0;
190
212
  }
@@ -247,7 +269,7 @@ export const spec = {
247
269
  const bidderResponse = JSON.stringify({ responseText: JSON.stringify(responseBody) });
248
270
  const requestData = JSON.stringify(request.data);
249
271
 
250
- var response = {
272
+ let response = {
251
273
  requestId: request.bidRequest.bidId,
252
274
  cpm: responseBody.creatives[0].costEUR,
253
275
  width: request.bidRequest.sizes[0][0],
@@ -90,7 +90,6 @@ export const spec = {
90
90
  {code: 'denakop'},
91
91
  {code: 'rtbanalytica'},
92
92
  {code: 'unibots'},
93
- {code: 'catapultx'},
94
93
  {code: 'ergadx'},
95
94
  {code: 'turktelekom'},
96
95
  {code: 'felixads'},
@@ -100,7 +99,8 @@ export const spec = {
100
99
  {code: 'rtbdemand_com'},
101
100
  {code: 'bidbuddy'},
102
101
  {code: 'adliveconnect'},
103
- {code: 'didnadisplay'}
102
+ {code: 'didnadisplay'},
103
+ {code: 'qortex'}
104
104
  ],
105
105
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
106
106
 
@@ -12,8 +12,9 @@ import {
12
12
  deepAccess,
13
13
  } from '../src/utils.js';
14
14
  import { getGlobal } from '../src/prebidGlobal.js';
15
- import {getStorageManager} from '../src/storageManager.js';
16
- import {MODULE_TYPE_RTD} from '../src/activities/modules.js';
15
+ import { getStorageManager } from '../src/storageManager.js';
16
+ import { loadExternalScript } from '../src/adloader.js';
17
+ import { MODULE_TYPE_RTD } from '../src/activities/modules.js';
17
18
 
18
19
  const MODULE_NAME = 'realTimeData';
19
20
  const SUBMODULE_NAME = 'airgrid';
@@ -25,6 +26,11 @@ export const storage = getStorageManager({
25
26
  moduleName: SUBMODULE_NAME,
26
27
  });
27
28
 
29
+ function getModuleUrl(accountId) {
30
+ const path = accountId ?? 'sdk';
31
+ return `https://cdn.edkt.io/${path}/edgekit.min.js`;
32
+ }
33
+
28
34
  /**
29
35
  * Attach script tag to DOM
30
36
  * @param {Object} rtdConfig
@@ -33,19 +39,12 @@ export const storage = getStorageManager({
33
39
  export function attachScriptTagToDOM(rtdConfig) {
34
40
  var edktInitializor = (window.edktInitializor = window.edktInitializor || {});
35
41
  if (!edktInitializor.invoked) {
36
- edktInitializor.invoked = true;
37
42
  edktInitializor.accountId = rtdConfig.params.accountId;
38
43
  edktInitializor.publisherId = rtdConfig.params.publisherId;
39
44
  edktInitializor.apiKey = rtdConfig.params.apiKey;
40
- edktInitializor.load = function (e) {
41
- var p = e || 'sdk';
42
- var n = document.createElement('script');
43
- n.type = 'module';
44
- n.async = true;
45
- n.src = 'https://cdn.edkt.io/' + p + '/edgekit.min.js';
46
- document.getElementsByTagName('head')[0].appendChild(n);
47
- };
48
- edktInitializor.load(edktInitializor.accountId);
45
+ edktInitializor.invoked = true;
46
+ const moduleSrc = getModuleUrl(rtdConfig.params.accountId);
47
+ loadExternalScript(moduleSrc, SUBMODULE_NAME);
49
48
  }
50
49
  }
51
50
 
@@ -28,7 +28,8 @@ export const spec = {
28
28
  code: BIDDER_CODE,
29
29
  supportedMediaTypes: [BANNER, VIDEO],
30
30
  aliases: [
31
- {code: 'bcmint'}
31
+ {code: 'bcmint'},
32
+ {code: 'bidgency'}
32
33
  ],
33
34
 
34
35
  isBidRequestValid: bid => {
@@ -37,6 +37,8 @@ export const spec = {
37
37
  */
38
38
  buildRequests: function(validBidRequests, bidderRequest) {
39
39
  const slots = validBidRequests.map(beOpRequestSlotsMaker);
40
+ const firstPartyData = bidderRequest.ortb2;
41
+ const psegs = (firstPartyData && firstPartyData.user && firstPartyData.user.ext && firstPartyData.user.ext.data) ? firstPartyData.user.ext.data.permutive : undefined;
40
42
  const pageUrl = getPageUrl(bidderRequest.refererInfo, window);
41
43
  const gdpr = bidderRequest.gdprConsent;
42
44
  const firstSlot = slots[0];
@@ -68,6 +70,10 @@ export const spec = {
68
70
  tc_string: (gdpr && gdpr.gdprApplies) ? gdpr.consentString : null,
69
71
  };
70
72
 
73
+ if (psegs) {
74
+ Object.assign(payloadObject, {psegs: psegs});
75
+ }
76
+
71
77
  const payloadString = JSON.stringify(payloadObject);
72
78
  return {
73
79
  method: 'POST',
@@ -0,0 +1,70 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { BANNER } from '../src/mediaTypes.js';
3
+ // import { logError, logInfo, logWarn, parseUrl } from '../src/utils.js';
4
+
5
+ const BIDDER_CODE = 'conceptx';
6
+ let ENDPOINT_URL = 'https://conceptx.cncpt-central.com/openrtb';
7
+ // const LOG_PREFIX = 'ConceptX: ';
8
+
9
+ export const spec = {
10
+ code: BIDDER_CODE,
11
+ supportedMediaTypes: [BANNER],
12
+ isBidRequestValid: function (bid) {
13
+ return !!(bid.bidId);
14
+ },
15
+
16
+ buildRequests: function (validBidRequests, bidderRequest) {
17
+ // logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)');
18
+ const requests = [];
19
+
20
+ if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) {
21
+ ENDPOINT_URL += '?gdpr_applies=' + bidderRequest.gdprConsent.gdprApplies;
22
+ ENDPOINT_URL += '&consentString=' + bidderRequest.gdprConsent.consentString;
23
+ }
24
+ for (var i = 0; i < validBidRequests.length; i++) {
25
+ const requestParent = { adUnits: [], meta: {} };
26
+ const bid = validBidRequests[i]
27
+ const { adUnitCode, auctionId, bidId, bidder, bidderRequestId, ortb2 } = bid
28
+ requestParent.meta = { adUnitCode, auctionId, bidId, bidder, bidderRequestId, ortb2 }
29
+
30
+ const { site, adunit } = bid.params
31
+ const adUnit = { site, adunit, targetId: bid.bidId }
32
+ if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) adUnit.dimensions = bid.mediaTypes.banner.sizes
33
+ requestParent.adUnits.push(adUnit);
34
+ requests.push({
35
+ method: 'POST',
36
+ url: ENDPOINT_URL,
37
+ options: {
38
+ withCredentials: false,
39
+ },
40
+ data: JSON.stringify(requestParent),
41
+ });
42
+ }
43
+
44
+ return requests;
45
+ },
46
+
47
+ interpretResponse: function (serverResponse, bidRequest) {
48
+ const bidResponsesFromServer = serverResponse.body.bidResponses;
49
+ const firstDummy = bidResponsesFromServer[0]
50
+ const firstSeat = firstDummy.ads[0]
51
+ const bidResponses = [];
52
+ const bidResponse = {
53
+ requestId: firstSeat.requestId,
54
+ cpm: firstSeat.cpm,
55
+ width: firstSeat.width,
56
+ height: firstSeat.height,
57
+ creativeId: firstSeat.creativeId,
58
+ dealId: firstSeat.dealId,
59
+ currency: firstSeat.currency,
60
+ netRevenue: true,
61
+ ttl: firstSeat.ttl,
62
+ referrer: firstSeat.referrer,
63
+ ad: firstSeat.html
64
+ };
65
+ bidResponses.push(bidResponse);
66
+ return bidResponses;
67
+ },
68
+
69
+ }
70
+ registerBidder(spec);
@@ -0,0 +1,36 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: ConceptX Bidder Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: info@concept.dk
7
+ ```
8
+
9
+ # Description
10
+
11
+ ConceptX Bidder Adapter for Prebid.js.
12
+ Only Banner format is supported.
13
+
14
+ # Test Parameters
15
+ ```
16
+ var adUnits = [
17
+ {
18
+ code: "test-div",
19
+ mediaTypes: {
20
+ banner: {
21
+ sizes: [[980, 180]]
22
+ }
23
+ },
24
+ bids: [
25
+ {
26
+ bidder: "conceptx",
27
+ params: {
28
+ site: "example",
29
+ adunit: "some-id-3",
30
+ }
31
+ },
32
+ ]
33
+ },
34
+
35
+ ];
36
+ ```
@@ -28,7 +28,7 @@ const LOG_PREFIX = 'Criteo: ';
28
28
  Unminified source code can be found in the privately shared repo: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js
29
29
  */
30
30
  const FAST_BID_VERSION_PLACEHOLDER = '%FAST_BID_VERSION%';
31
- export const FAST_BID_VERSION_CURRENT = 135;
31
+ export const FAST_BID_VERSION_CURRENT = 136;
32
32
  const FAST_BID_VERSION_LATEST = 'latest';
33
33
  const FAST_BID_VERSION_NONE = 'none';
34
34
  const PUBLISHER_TAG_URL_TEMPLATE = 'https://static.criteo.net/js/ld/publishertag.prebid' + FAST_BID_VERSION_PLACEHOLDER + '.js';
@@ -177,7 +177,14 @@ export const spec = {
177
177
 
178
178
  if (publisherTagAvailable()) {
179
179
  // eslint-disable-next-line no-undef
180
- const adapter = new Criteo.PubTag.Adapters.Prebid(PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, bidRequests, bidderRequest, '$prebid.version$');
180
+ const adapter = new Criteo.PubTag.Adapters.Prebid(
181
+ PROFILE_ID_PUBLISHERTAG,
182
+ ADAPTER_VERSION,
183
+ bidRequests,
184
+ bidderRequest,
185
+ '$prebid.version$',
186
+ { createOutstreamVideoRenderer: createOutstreamVideoRenderer }
187
+ );
181
188
  url = adapter.buildCdbUrl();
182
189
  data = adapter.buildCdbRequest();
183
190
  } else {
@@ -1,7 +1,7 @@
1
- import {registerBidder} from '../src/adapters/bidderFactory.js';
2
- import {BANNER} from '../src/mediaTypes.js';
1
+ import { ortbConverter } from '../libraries/ortbConverter/converter.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+ import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
4
  import * as utils from '../src/utils.js';
4
- import {ortbConverter} from '../libraries/ortbConverter/converter.js'
5
5
 
6
6
  const BIDDER_CODE = 'eskimi';
7
7
  // const ENDPOINT = 'https://hb.eskimi.com/bids'
@@ -12,43 +12,35 @@ const DEFAULT_CURRENCY = 'USD';
12
12
  const DEFAULT_NET_REVENUE = true;
13
13
  const GVLID = 814;
14
14
 
15
+ const VIDEO_ORTB_PARAMS = [
16
+ 'mimes',
17
+ 'minduration',
18
+ 'maxduration',
19
+ 'placement',
20
+ 'protocols',
21
+ 'startdelay',
22
+ 'skip',
23
+ 'skipafter',
24
+ 'minbitrate',
25
+ 'maxbitrate',
26
+ 'delivery',
27
+ 'playbackmethod',
28
+ 'api',
29
+ 'linearity',
30
+ 'battr'
31
+ ];
32
+
33
+ const BANNER_ORTB_PARAMS = [
34
+ 'battr'
35
+ ]
36
+
15
37
  export const spec = {
16
38
  code: BIDDER_CODE,
17
39
  gvlid: GVLID,
18
- supportedMediaTypes: [BANNER],
19
-
20
- isBidRequestValid: function (bid) {
21
- return !!bid.params.placementId;
22
- },
23
-
24
- buildRequests(bidRequests, bidderRequest) {
25
- const data = converter.toORTB({bidRequests, bidderRequest})
26
-
27
- let bid = bidRequests.find((b) => b.params.placementId)
28
- if (!data.site) data.site = {}
29
- data.site.ext = {placementId: bid.params.placementId}
30
-
31
- if (bidderRequest.gdprConsent) {
32
- if (!data.user) data.user = {};
33
- if (!data.user.ext) data.user.ext = {};
34
- if (!data.regs) data.regs = {};
35
- if (!data.regs.ext) data.regs.ext = {};
36
- data.user.ext.consent = bidderRequest.gdprConsent.consentString;
37
- data.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
38
- }
39
-
40
- return [{
41
- method: 'POST',
42
- url: ENDPOINT,
43
- data,
44
- options: {contentType: 'application/json;charset=UTF-8', withCredentials: false}
45
- }]
46
- },
47
-
48
- interpretResponse(response, request) {
49
- return converter.fromORTB({response: response.body, request: request.data}).bids;
50
- },
51
-
40
+ supportedMediaTypes: [BANNER, VIDEO],
41
+ isBidRequestValid,
42
+ buildRequests,
43
+ interpretResponse,
52
44
  /**
53
45
  * Register bidder specific code, which will execute if a bid from this bidder won the auction
54
46
  * @param {Bid} bid The bid that won the auction
@@ -60,13 +52,151 @@ export const spec = {
60
52
  }
61
53
  }
62
54
 
63
- const converter = ortbConverter({
55
+ registerBidder(spec);
56
+
57
+ const CONVERTER = ortbConverter({
64
58
  context: {
65
59
  netRevenue: DEFAULT_NET_REVENUE,
66
60
  ttl: DEFAULT_BID_TTL,
67
- currency: DEFAULT_CURRENCY,
68
- mediaType: BANNER // TODO: support more types, we should set mtype on the winning bid
61
+ currency: DEFAULT_CURRENCY
62
+ },
63
+ imp(buildImp, bidRequest, context) {
64
+ let imp = buildImp(bidRequest, context);
65
+ imp.secure = Number(window.location.protocol === 'https:');
66
+ if (!imp.bidfloor && bidRequest.params.bidFloor) {
67
+ imp.bidfloor = bidRequest.params.bidFloor;
68
+ imp.bidfloorcur = utils.getBidIdParameter('bidFloorCur', bidRequest.params).toUpperCase() || 'USD'
69
+ }
70
+
71
+ if (bidRequest.mediaTypes[VIDEO]) {
72
+ imp = buildVideoImp(bidRequest, imp);
73
+ } else if (bidRequest.mediaTypes[BANNER]) {
74
+ imp = buildBannerImp(bidRequest, imp);
75
+ }
76
+
77
+ return imp;
69
78
  }
70
79
  });
71
80
 
72
- registerBidder(spec);
81
+ function isBidRequestValid(bidRequest) {
82
+ return (isPlacementIdValid(bidRequest) && (isValidBannerRequest(bidRequest) || isValidVideoRequest(bidRequest)));
83
+ }
84
+
85
+ function isPlacementIdValid(bidRequest) {
86
+ return utils.isNumber(bidRequest.params.placementId);
87
+ }
88
+
89
+ function isValidBannerRequest(bidRequest) {
90
+ const bannerSizes = utils.deepAccess(bidRequest, `mediaTypes.${BANNER}.sizes`);
91
+ return utils.isArray(bannerSizes) && bannerSizes.length > 0 && bannerSizes.every(size => utils.isNumber(size[0]) && utils.isNumber(size[1]));
92
+ }
93
+
94
+ function isValidVideoRequest(bidRequest) {
95
+ const videoSizes = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}.playerSize`);
96
+
97
+ return utils.isArray(videoSizes) && videoSizes.length > 0 && videoSizes.every(size => utils.isNumber(size[0]) && utils.isNumber(size[1]));
98
+ }
99
+
100
+ function buildRequests(validBids, bidderRequest) {
101
+ let videoBids = validBids.filter(bid => isVideoBid(bid));
102
+ let bannerBids = validBids.filter(bid => isBannerBid(bid));
103
+ let requests = [];
104
+
105
+ bannerBids.forEach(bid => {
106
+ requests.push(createRequest([bid], bidderRequest, BANNER));
107
+ });
108
+
109
+ videoBids.forEach(bid => {
110
+ requests.push(createRequest([bid], bidderRequest, VIDEO));
111
+ });
112
+
113
+ return requests;
114
+ }
115
+
116
+ function interpretResponse(response, request) {
117
+ return CONVERTER.fromORTB({ request: request.data, response: response.body }).bids;
118
+ }
119
+
120
+ function buildVideoImp(bidRequest, imp) {
121
+ const videoAdUnitParams = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`, {});
122
+ const videoBidderParams = utils.deepAccess(bidRequest, `params.${VIDEO}`, {});
123
+
124
+ const videoParams = { ...videoAdUnitParams, ...videoBidderParams };
125
+
126
+ const videoSizes = (videoAdUnitParams && videoAdUnitParams.playerSize) || [];
127
+
128
+ if (videoSizes && videoSizes.length > 0) {
129
+ utils.deepSetValue(imp, 'video.w', videoSizes[0][0]);
130
+ utils.deepSetValue(imp, 'video.h', videoSizes[0][1]);
131
+ }
132
+
133
+ VIDEO_ORTB_PARAMS.forEach((param) => {
134
+ if (videoParams.hasOwnProperty(param)) {
135
+ utils.deepSetValue(imp, `video.${param}`, videoParams[param]);
136
+ }
137
+ });
138
+
139
+ if (imp.video && videoParams?.context === 'outstream') {
140
+ imp.video.placement = imp.video.placement || 4;
141
+ }
142
+
143
+ return { ...imp };
144
+ }
145
+
146
+ function buildBannerImp(bidRequest, imp) {
147
+ const bannerAdUnitParams = utils.deepAccess(bidRequest, `mediaTypes.${BANNER}`, {});
148
+ const bannerBidderParams = utils.deepAccess(bidRequest, `params.${BANNER}`, {});
149
+
150
+ const bannerParams = { ...bannerAdUnitParams, ...bannerBidderParams };
151
+
152
+ let sizes = bidRequest.mediaTypes.banner.sizes;
153
+
154
+ if (sizes) {
155
+ utils.deepSetValue(imp, 'banner.w', sizes[0][0]);
156
+ utils.deepSetValue(imp, 'banner.h', sizes[0][1]);
157
+ }
158
+
159
+ BANNER_ORTB_PARAMS.forEach((param) => {
160
+ if (bannerParams.hasOwnProperty(param)) {
161
+ utils.deepSetValue(imp, `banner.${param}`, bannerParams[param]);
162
+ }
163
+ });
164
+
165
+ return { ...imp };
166
+ }
167
+
168
+ function createRequest(bidRequests, bidderRequest, mediaType) {
169
+ const data = CONVERTER.toORTB({ bidRequests, bidderRequest, context: { mediaType } })
170
+
171
+ const bid = bidRequests.find((b) => b.params.placementId)
172
+ if (!data.site) data.site = {}
173
+ data.site.ext = { placementId: bid.params.placementId }
174
+
175
+ if (bidderRequest.gdprConsent) {
176
+ if (!data.user) data.user = {};
177
+ if (!data.user.ext) data.user.ext = {};
178
+ if (!data.regs) data.regs = {};
179
+ if (!data.regs.ext) data.regs.ext = {};
180
+ data.user.ext.consent = bidderRequest.gdprConsent.consentString;
181
+ data.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
182
+ }
183
+
184
+ if (bid.params.bcat) data.bcat = bid.params.bcat;
185
+ if (bid.params.badv) data.badv = bid.params.badv;
186
+ if (bid.params.bapp) data.bapp = bid.params.bapp;
187
+
188
+ return {
189
+ method: 'POST',
190
+ url: ENDPOINT,
191
+ data: data,
192
+ options: { contentType: 'application/json;charset=UTF-8', withCredentials: false }
193
+ }
194
+ }
195
+
196
+ function isVideoBid(bid) {
197
+ return utils.deepAccess(bid, 'mediaTypes.video');
198
+ }
199
+
200
+ function isBannerBid(bid) {
201
+ return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid);
202
+ }