prebid.js 9.53.3 → 9.53.4

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 (208) hide show
  1. package/dist/33acrossAnalyticsAdapter.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/BTBidAdapter.js +1 -1
  5. package/dist/adagioAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adagioUtils.js +1 -1
  8. package/dist/addefendBidAdapter.js +1 -1
  9. package/dist/adgenerationBidAdapter.js +1 -1
  10. package/dist/adlooxRtdProvider.js +1 -1
  11. package/dist/adqueryBidAdapter.js +1 -1
  12. package/dist/adrelevantisBidAdapter.js +1 -1
  13. package/dist/adstirBidAdapter.js +1 -1
  14. package/dist/adtrgtmeBidAdapter.js +1 -1
  15. package/dist/adxcgAnalyticsAdapter.js +1 -1
  16. package/dist/adxcgBidAdapter.js +1 -1
  17. package/dist/adyoulikeBidAdapter.js +1 -1
  18. package/dist/agmaAnalyticsAdapter.js +1 -1
  19. package/dist/ajaBidAdapter.js +1 -1
  20. package/dist/amxBidAdapter.js +1 -1
  21. package/dist/amxIdSystem.js +1 -1
  22. package/dist/aniviewBidAdapter.js +1 -1
  23. package/dist/appierAnalyticsAdapter.js +1 -1
  24. package/dist/appnexusBidAdapter.js +1 -1
  25. package/dist/asoBidAdapter.js +1 -1
  26. package/dist/axonixBidAdapter.js +1 -1
  27. package/dist/beopBidAdapter.js +1 -1
  28. package/dist/bidderTimeoutUtils.js +1 -0
  29. package/dist/bidglassBidAdapter.js +1 -1
  30. package/dist/big-richmediaBidAdapter.js +1 -1
  31. package/dist/bitmediaBidAdapter.js +1 -1
  32. package/dist/bridBidAdapter.js +1 -1
  33. package/dist/bridgeuppBidAdapter.js +1 -1
  34. package/dist/bridgewellBidAdapter.js +1 -1
  35. package/dist/brightMountainMediaBidAdapter.js +1 -1
  36. package/dist/carodaBidAdapter.js +1 -1
  37. package/dist/chtnwBidAdapter.js +1 -1
  38. package/dist/chunk-core.js +1 -1
  39. package/dist/concertBidAdapter.js +1 -1
  40. package/dist/connectadBidAdapter.js +1 -1
  41. package/dist/consumableBidAdapter.js +1 -1
  42. package/dist/contxtfulBidAdapter.js +1 -1
  43. package/dist/conversantAnalyticsAdapter.js +1 -1
  44. package/dist/conversantBidAdapter.js +1 -1
  45. package/dist/craftBidAdapter.js +1 -1
  46. package/dist/criteoBidAdapter.js +1 -1
  47. package/dist/cwireBidAdapter.js +1 -1
  48. package/dist/dailymotionBidAdapter.js +1 -1
  49. package/dist/dependencies.json +10 -1
  50. package/dist/dspxBidAdapter.js +1 -1
  51. package/dist/dxkultureBidAdapter.js +1 -1
  52. package/dist/eplanningBidAdapter.js +1 -1
  53. package/dist/equativBidAdapter.js +1 -1
  54. package/dist/eskimiBidAdapter.js +1 -1
  55. package/dist/euidIdSystem.js +1 -1
  56. package/dist/exadsBidAdapter.js +1 -1
  57. package/dist/excoBidAdapter.js +1 -1
  58. package/dist/feedadBidAdapter.js +1 -1
  59. package/dist/finativeBidAdapter.js +1 -1
  60. package/dist/freewheel-sspBidAdapter.js +1 -1
  61. package/dist/fwsspBidAdapter.js +1 -1
  62. package/dist/gmosspBidAdapter.js +1 -1
  63. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  64. package/dist/greenbidsBidAdapter.js +1 -1
  65. package/dist/greenbidsRtdProvider.js +1 -1
  66. package/dist/gridBidAdapter.js +1 -1
  67. package/dist/gumgumBidAdapter.js +1 -1
  68. package/dist/h12mediaBidAdapter.js +1 -1
  69. package/dist/hypelabBidAdapter.js +1 -1
  70. package/dist/id5AnalyticsAdapter.js +1 -1
  71. package/dist/id5IdSystem.js +1 -1
  72. package/dist/imdsBidAdapter.js +1 -1
  73. package/dist/improvedigitalBidAdapter.js +1 -1
  74. package/dist/inmobiBidAdapter.js +1 -1
  75. package/dist/insticatorBidAdapter.js +1 -1
  76. package/dist/intentIqAnalyticsAdapter.js +1 -1
  77. package/dist/ixBidAdapter.js +1 -1
  78. package/dist/jixieBidAdapter.js +1 -1
  79. package/dist/justpremiumBidAdapter.js +1 -1
  80. package/dist/kargoBidAdapter.js +1 -1
  81. package/dist/kimberliteBidAdapter.js +1 -1
  82. package/dist/konduitAnalyticsAdapter.js +1 -1
  83. package/dist/kueezBidAdapter.js +1 -1
  84. package/dist/lassoBidAdapter.js +1 -1
  85. package/dist/lifestreetBidAdapter.js +1 -1
  86. package/dist/liveIntentId.js +1 -1
  87. package/dist/logicadBidAdapter.js +1 -1
  88. package/dist/loglyliftBidAdapter.js +1 -1
  89. package/dist/luceadBidAdapter.js +1 -1
  90. package/dist/mabidderBidAdapter.js +1 -1
  91. package/dist/madsenseBidAdapter.js +1 -1
  92. package/dist/magniteAnalyticsAdapter.js +1 -1
  93. package/dist/malltvAnalyticsAdapter.js +1 -1
  94. package/dist/marsmediaBidAdapter.js +1 -1
  95. package/dist/mediafuseBidAdapter.js +1 -1
  96. package/dist/medianetBidAdapter.js +1 -1
  97. package/dist/medianetUtils.js +1 -1
  98. package/dist/mediasquareBidAdapter.js +1 -1
  99. package/dist/mgidBidAdapter.js +1 -1
  100. package/dist/missenaBidAdapter.js +1 -1
  101. package/dist/mobilefuseBidAdapter.js +1 -1
  102. package/dist/nextMillenniumBidAdapter.js +1 -1
  103. package/dist/nexx360Utils.js +1 -1
  104. package/dist/nobidAnalyticsAdapter.js +1 -1
  105. package/dist/nobidBidAdapter.js +1 -1
  106. package/dist/nodalsAiRtdProvider.js +1 -1
  107. package/dist/not-for-prod/prebid.js +175 -172
  108. package/dist/objectGuard.js +1 -1
  109. package/dist/oguryBidAdapter.js +1 -1
  110. package/dist/onetagBidAdapter.js +1 -1
  111. package/dist/ooloAnalyticsAdapter.js +1 -1
  112. package/dist/openxBidAdapter.js +1 -1
  113. package/dist/optableRtdProvider.js +1 -1
  114. package/dist/optidigitalBidAdapter.js +1 -1
  115. package/dist/orbidderBidAdapter.js +1 -1
  116. package/dist/outbrainBidAdapter.js +1 -1
  117. package/dist/pixfutureBidAdapter.js +1 -1
  118. package/dist/publinkIdSystem.js +1 -1
  119. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  120. package/dist/pubmaticBidAdapter.js +1 -1
  121. package/dist/pubmaticRtdProvider.js +1 -1
  122. package/dist/pubmaticUtils.js +1 -0
  123. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  124. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  125. package/dist/pxyzBidAdapter.js +1 -1
  126. package/dist/quantcastBidAdapter.js +1 -1
  127. package/dist/readpeakBidAdapter.js +1 -1
  128. package/dist/relaidoBidAdapter.js +1 -1
  129. package/dist/retailspotBidAdapter.js +1 -1
  130. package/dist/rhythmoneBidAdapter.js +1 -1
  131. package/dist/riseUtils.js +1 -1
  132. package/dist/rtdModule.js +1 -1
  133. package/dist/rubiconBidAdapter.js +1 -1
  134. package/dist/seedingAllianceBidAdapter.js +1 -1
  135. package/dist/seedtagBidAdapter.js +1 -1
  136. package/dist/sevioBidAdapter.js +1 -0
  137. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  138. package/dist/sharethroughBidAdapter.js +1 -1
  139. package/dist/showheroes-bsBidAdapter.js +1 -1
  140. package/dist/smaatoBidAdapter.js +1 -1
  141. package/dist/smartadserverBidAdapter.js +1 -1
  142. package/dist/smartxBidAdapter.js +1 -1
  143. package/dist/smilewantedBidAdapter.js +1 -1
  144. package/dist/snigelBidAdapter.js +1 -1
  145. package/dist/sonobiBidAdapter.js +1 -1
  146. package/dist/sovrnBidAdapter.js +1 -1
  147. package/dist/sparteoBidAdapter.js +1 -1
  148. package/dist/sspBCBidAdapter.js +1 -1
  149. package/dist/stvBidAdapter.js +1 -1
  150. package/dist/sublimeBidAdapter.js +1 -1
  151. package/dist/taboolaBidAdapter.js +1 -1
  152. package/dist/tappxBidAdapter.js +1 -1
  153. package/dist/targetVideoBidAdapter.js +1 -1
  154. package/dist/teadsBidAdapter.js +1 -1
  155. package/dist/terceptAnalyticsAdapter.js +1 -1
  156. package/dist/themoneytizerBidAdapter.js +1 -1
  157. package/dist/timeoutRtdProvider.js +1 -1
  158. package/dist/trionBidAdapter.js +1 -1
  159. package/dist/tripleliftBidAdapter.js +1 -1
  160. package/dist/ttdBidAdapter.js +1 -1
  161. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  162. package/dist/uid2IdSystem.js +1 -1
  163. package/dist/underdogmediaBidAdapter.js +1 -1
  164. package/dist/undertoneBidAdapter.js +1 -1
  165. package/dist/unrulyBidAdapter.js +1 -1
  166. package/dist/vidazooUtils.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/yahooAdsBidAdapter.js +1 -1
  173. package/dist/yandexBidAdapter.js +1 -1
  174. package/dist/yieldmoBidAdapter.js +1 -1
  175. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  176. package/integrationExamples/gpt/pubmaticRtdProvider_Example.html +161 -0
  177. package/libraries/bidderTimeoutUtils/bidderTimeoutUtils.js +119 -0
  178. package/libraries/objectGuard/objectGuard.js +36 -15
  179. package/libraries/pubmaticUtils/plugins/dynamicTimeout.js +209 -0
  180. package/libraries/pubmaticUtils/plugins/floorProvider.js +168 -0
  181. package/libraries/pubmaticUtils/plugins/pluginManager.js +106 -0
  182. package/libraries/pubmaticUtils/plugins/unifiedPricingRule.js +375 -0
  183. package/libraries/pubmaticUtils/pubmaticUtils.js +76 -0
  184. package/modules/fwsspBidAdapter.js +134 -69
  185. package/modules/fwsspBidAdapter.md +121 -26
  186. package/modules/optableRtdProvider.js +33 -12
  187. package/modules/pubmaticAnalyticsAdapter.js +5 -1
  188. package/modules/pubmaticRtdProvider.js +105 -565
  189. package/modules/rtdModule/index.js +23 -2
  190. package/modules/sevioBidAdapter.js +413 -0
  191. package/modules/sevioBidAdapter.md +29 -0
  192. package/modules/sparteoBidAdapter.js +122 -10
  193. package/modules/timeoutRtdProvider.js +2 -105
  194. package/package.json +1 -1
  195. package/test/spec/activities/objectGuard_spec.js +49 -16
  196. package/test/spec/libraries/bidderTimeoutUtils/bidderTimeoutUtils_spec.js +213 -0
  197. package/test/spec/libraries/pubmaticUtils/plugins/dynamicTimeout_spec.js +746 -0
  198. package/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js +184 -0
  199. package/test/spec/libraries/pubmaticUtils/plugins/pluginManager_spec.js +489 -0
  200. package/test/spec/libraries/pubmaticUtils/plugins/unifiedPricingRule_spec.js +359 -0
  201. package/test/spec/libraries/pubmaticUtils/pubmaticUtils_spec.js +236 -0
  202. package/test/spec/modules/fwsspBidAdapter_spec.js +513 -78
  203. package/test/spec/modules/optableRtdProvider_spec.js +55 -5
  204. package/test/spec/modules/pubmaticRtdProvider_spec.js +252 -1183
  205. package/test/spec/modules/realTimeDataModule_spec.js +58 -8
  206. package/test/spec/modules/sevioBidAdapter_spec.js +513 -0
  207. package/test/spec/modules/sparteoBidAdapter_spec.js +528 -43
  208. package/test/spec/modules/timeoutRtdProvider_spec.js +1 -201
@@ -313,10 +313,31 @@ export const setBidRequestsData = timedAuctionHook('rtd', function setBidRequest
313
313
 
314
314
  const timeout = shouldDelayAuction ? _moduleConfig.auctionDelay : 0;
315
315
  waitTimeout = setTimeout(exitHook, timeout);
316
+ const fpdKey = 'ortb2Fragments';
316
317
 
317
318
  relevantSubModules.forEach(sm => {
318
- const fpdGuard = guardOrtb2Fragments(reqBidsConfigObj.ortb2Fragments || {}, activityParams(MODULE_TYPE_RTD, sm.name));
319
- sm.getBidRequestData({...reqBidsConfigObj, ortb2Fragments: fpdGuard}, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent, timeout);
319
+ const fpdGuard = guardOrtb2Fragments(reqBidsConfigObj[fpdKey] ?? {}, activityParams(MODULE_TYPE_RTD, sm.name));
320
+ // submodules need to be able to modify the request object, but we need
321
+ // to protect the FPD portion of it. Use a proxy that passes through everything
322
+ // except 'ortb2Fragments'.
323
+ const request = new Proxy(reqBidsConfigObj, {
324
+ get(target, prop, receiver) {
325
+ if (prop === fpdKey) return fpdGuard;
326
+ return Reflect.get(target, prop, receiver);
327
+ },
328
+ set(target, prop, value, receiver) {
329
+ if (prop === fpdKey) {
330
+ mergeDeep(fpdGuard, value);
331
+ return true;
332
+ }
333
+ return Reflect.set(target, prop, value, receiver);
334
+ },
335
+ deleteProperty(target, prop) {
336
+ if (prop === fpdKey) return true;
337
+ return Reflect.deleteProperty(target, prop)
338
+ }
339
+ })
340
+ sm.getBidRequestData(request, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent, timeout);
320
341
  });
321
342
 
322
343
  function onGetBidRequestDataCallback() {
@@ -0,0 +1,413 @@
1
+ import * as utils from "../src/utils.js";
2
+ import { registerBidder } from "../src/adapters/bidderFactory.js";
3
+ import { BANNER, NATIVE } from "../src/mediaTypes.js";
4
+ import { config } from "../src/config.js";
5
+ import * as converter from '../libraries/ortbConverter/converter.js';
6
+
7
+ const PREBID_VERSION = '$prebid.version$';
8
+ const ADAPTER_VERSION = '1.0';
9
+ const ORTB = converter.ortbConverter({
10
+ context: { ttl: 300 }
11
+ });
12
+ const BIDDER_CODE = "sevio";
13
+ const GVLID = `1393`;
14
+ const ENDPOINT_URL = "https://req.adx.ws/prebid";
15
+ const ACTION_METHOD = "POST";
16
+
17
+ function detectWalletsPresence() {
18
+ const _wallets = [
19
+ "ethereum",
20
+ "web3",
21
+ "cardano",
22
+ "BinanceChain",
23
+ "solana",
24
+ "tron",
25
+ "tronLink",
26
+ "tronWeb",
27
+ "tronLink",
28
+ "starknet_argentX",
29
+ "walletLinkExtension",
30
+ "coinbaseWalletExtension",
31
+ "__venom",
32
+ "martian",
33
+ "razor",
34
+ "razorWallet",
35
+ "ic", // plug wallet,
36
+ "cosmos",
37
+ "ronin",
38
+ "starknet_braavos",
39
+ "XverseProviders",
40
+ "compass",
41
+ "solflare",
42
+ "solflareWalletStandardInitialized",
43
+ "sender",
44
+ "rainbow",
45
+ ];
46
+ return _wallets.some((prop) => typeof window[prop] !== "undefined") ? 1 : 0;
47
+ }
48
+
49
+ function getPageTitle(win = window) {
50
+ try {
51
+ const ogTitle = win.top.document.querySelector('meta[property="og:title"]');
52
+ return win.top.document.title || (ogTitle && ogTitle.content) || '';
53
+ } catch (e) {
54
+ const ogTitle = document.querySelector('meta[property="og:title"]');
55
+ return document.title || (ogTitle && ogTitle.content) || '';
56
+ }
57
+ }
58
+
59
+ function getPageDescription(win = window) {
60
+ let element;
61
+
62
+ try {
63
+ element = win.top.document.querySelector('meta[name="description"]') ||
64
+ win.top.document.querySelector('meta[property="og:description"]')
65
+ } catch (e) {
66
+ element = document.querySelector('meta[name="description"]') ||
67
+ document.querySelector('meta[property="og:description"]')
68
+ }
69
+
70
+ return (element && element.content) || '';
71
+ }
72
+
73
+ function getDomComplexity(document) {
74
+ return document?.querySelectorAll('*')?.length ?? -1;
75
+ }
76
+
77
+ const normalizeKeywords = (input) => {
78
+ if (!input) return [];
79
+
80
+ if (Array.isArray(input)) {
81
+ return input.map(k => k.trim()).filter(Boolean);
82
+ }
83
+
84
+ if (typeof input === 'string') {
85
+ return input
86
+ .split(',')
87
+ .map(k => k.trim())
88
+ .filter(Boolean);
89
+ }
90
+
91
+ // Any other type → ignore
92
+ return [];
93
+ };
94
+
95
+ const detectAdType = (bid) =>
96
+ (
97
+ ["native", "banner"].find((t) => bid.mediaTypes?.[t]) || "unknown"
98
+ ).toUpperCase();
99
+
100
+ const getReferrerInfo = (bidderRequest) => {
101
+ return bidderRequest?.refererInfo?.page ?? '';
102
+ }
103
+
104
+ const parseNativeAd = function (bid) {
105
+ try {
106
+ const nativeAd = JSON.parse(bid.ad);
107
+ const native = {};
108
+
109
+ nativeAd.assets?.forEach(asset => {
110
+ if (asset.title?.text) {
111
+ native.title = asset.title.text;
112
+ }
113
+ if (asset.data) {
114
+ const value = asset.data.value;
115
+ switch (asset.data.type) {
116
+ case 1: if (value) native.sponsored = value; break;
117
+ case 2: if (value) native.desc = value; break;
118
+ case 3: if (value) native.rating = value; break;
119
+ case 4: if (value) native.likes = value; break;
120
+ case 5: if (value) native.downloads = value; break;
121
+ case 6: if (value) native.price = value; break;
122
+ case 7: if (value) native.saleprice = value; break;
123
+ case 8: if (value) native.phone = value; break;
124
+ case 9: if (value) native.address = value; break;
125
+ case 10: if (value) native.desc2 = value; break;
126
+ case 11: if (value) native.displayurl = value; break;
127
+ case 12: if (value) native.ctatext = value; break;
128
+ default: break;
129
+ }
130
+ }
131
+ if (asset.img) {
132
+ const { url, w = 0, h = 0, type } = asset.img;
133
+
134
+ if (type === 1 && url) {
135
+ native.icon = url;
136
+ native.icon_width = w;
137
+ native.icon_height = h;
138
+ } else if (type === 3 && url) {
139
+ native.image = url;
140
+ native.image_width = w;
141
+ native.image_height = h;
142
+ }
143
+ }
144
+ });
145
+
146
+ if (nativeAd.link?.url) {
147
+ native.clickUrl = nativeAd.link.url;
148
+ }
149
+
150
+ const eventTrackers = nativeAd.eventtrackers || [];
151
+
152
+ const impressionTrackers = eventTrackers
153
+ .filter(tracker => tracker.event === 1)
154
+ .map(tracker => tracker.url)
155
+ .filter(Boolean);
156
+
157
+ const viewableTrackers = eventTrackers
158
+ .filter(tracker => tracker.event === 2)
159
+ .map(tracker => tracker.url)
160
+ .filter(Boolean);
161
+
162
+ if (impressionTrackers.length) {
163
+ native.impressionTrackers = impressionTrackers;
164
+ }
165
+
166
+ if (viewableTrackers.length) {
167
+ native.viewableTrackers = viewableTrackers; // custom field
168
+ }
169
+
170
+ if (Array.isArray(nativeAd.link?.clicktrackers) && nativeAd.link.clicktrackers.length > 0) {
171
+ native.clickTrackers = nativeAd.link.clicktrackers;
172
+ }
173
+
174
+ if (nativeAd.privacy?.url) native.privacyLink = nativeAd.privacy.url;
175
+ if (nativeAd.privacy?.icon) native.privacyIcon = nativeAd.privacy.icon;
176
+
177
+ return native;
178
+ } catch (e) {
179
+ utils.logWarn('Invalid native JSON', e);
180
+ return null;
181
+ }
182
+ }
183
+ export const spec = {
184
+ code: BIDDER_CODE,
185
+ gvlid: GVLID,
186
+ isBidRequestValid: function (bid) {
187
+ if (!bid) {
188
+ utils.logWarn(BIDDER_CODE, "Invalid bid", bid);
189
+
190
+ return false;
191
+ }
192
+
193
+ if (!bid.params) {
194
+ utils.logWarn(BIDDER_CODE, "bid.params is required");
195
+
196
+ return false;
197
+ }
198
+
199
+ if (!bid.params.zone) {
200
+ utils.logWarn(BIDDER_CODE, "bid.params.zone is required");
201
+
202
+ return false;
203
+ }
204
+
205
+ return true;
206
+ },
207
+
208
+ buildRequests: function (bidRequests, bidderRequest) {
209
+ const userSyncEnabled = config.getConfig("userSync.syncEnabled");
210
+ const currencyConfig = config.getConfig('currency');
211
+ const currency =
212
+ currencyConfig?.adServerCurrency ||
213
+ currencyConfig?.defaultCurrency ||
214
+ null;
215
+ // (!) that avoids top-level side effects (the thing that can stop registerBidder from running)
216
+ const computeTTFB = (w = (typeof window !== 'undefined' ? window : undefined)) => {
217
+ try {
218
+ const wt = (() => { try { return w?.top ?? w; } catch { return w; } })();
219
+ const p = wt?.performance || wt?.webkitPerformance || wt?.msPerformance || wt?.mozPerformance;
220
+ if (!p) return '';
221
+
222
+ if (typeof p.getEntriesByType === 'function') {
223
+ const nav = p.getEntriesByType('navigation')?.[0];
224
+ if (nav?.responseStart > 0 && nav?.requestStart > 0) {
225
+ return String(Math.round(nav.responseStart - nav.requestStart));
226
+ }
227
+ }
228
+
229
+ const t = p.timing;
230
+ if (t?.responseStart > 0 && t?.requestStart > 0) {
231
+ return String(t.responseStart - t.requestStart);
232
+ }
233
+
234
+ return '';
235
+ } catch {
236
+ return '';
237
+ }
238
+ };
239
+
240
+ // simple caching
241
+ const getTTFBOnce = (() => {
242
+ let cached = false;
243
+ let done = false;
244
+ return () => {
245
+ if (done) return cached;
246
+ done = true;
247
+ cached = computeTTFB();
248
+ return cached;
249
+ };
250
+ })();
251
+ const ortbRequest = ORTB.toORTB({ bidderRequest, bidRequests });
252
+
253
+ if (bidRequests.length === 0) {
254
+ return [];
255
+ }
256
+ const gdpr = bidderRequest?.gdprConsent;
257
+ const usp = bidderRequest?.uspConsent;
258
+ const gpp = bidderRequest?.gppConsent;
259
+ const hasWallet = detectWalletsPresence();
260
+
261
+ return bidRequests.map((bidRequest) => {
262
+ const isNative = detectAdType(bidRequest)?.toLowerCase() === 'native';
263
+ const adSizes = bidRequest.mediaTypes?.banner?.sizes || bidRequest.mediaTypes?.native?.sizes || [];
264
+ const formattedSizes = Array.isArray(adSizes)
265
+ ? adSizes
266
+ .filter(size => Array.isArray(size) && size.length === 2)
267
+ .map(([width, height]) => ({ width, height }))
268
+ : [];
269
+ const originalAssets = bidRequest.mediaTypes?.native?.ortb?.assets || [];
270
+
271
+ // convert icon to img type 1
272
+ const processedAssets = originalAssets.map(asset => {
273
+ if (asset.icon) {
274
+ return {
275
+ id: asset.id,
276
+ required: asset.required || 0,
277
+ img: {
278
+ type: 1,
279
+ w: asset.icon.w,
280
+ h: asset.icon.h,
281
+ }
282
+ };
283
+ }
284
+ return asset;
285
+ });
286
+
287
+ const payload = {
288
+ userLanguage: navigator.language,
289
+ pageUrl: bidRequest?.refererInfo?.page,
290
+ pageDomain: bidRequest?.refererInfo?.referer,
291
+ userId: bidRequest.userId,
292
+ eids: (bidRequest.userIdAsEids || []).map(eid => ({
293
+ source: eid.source,
294
+ id: eid.uids?.[0]?.id
295
+ })).filter(eid => eid.source && eid.id),
296
+ ...(currency ? { currency } : {}),
297
+ ads: [
298
+ {
299
+ sizes: formattedSizes,
300
+ referenceId: bidRequest.params.referenceId,
301
+ tagId: bidRequest.params.zone,
302
+ type: detectAdType(bidRequest),
303
+ ...(isNative && { nativeRequest: { ver: "1.2", assets: processedAssets || {}} })
304
+ },
305
+ ],
306
+ keywords: {
307
+ tokens: normalizeKeywords(
308
+ ortbRequest?.site?.keywords ||
309
+ bidRequest.params?.keywords
310
+ )
311
+ },
312
+ privacy: {
313
+ gpp: gpp?.consentString || "",
314
+ tcfeu: gdpr?.consentString || "",
315
+ usp: usp?.uspString || "",
316
+ },
317
+ xPageUrl: window.location.href,
318
+ wdb: hasWallet,
319
+ externalRef: bidRequest.bidId,
320
+ userSyncOption: userSyncEnabled === false ? "OFF" : "BIDDERS",
321
+ referer: getReferrerInfo(bidderRequest),
322
+ pageReferer: document.referrer,
323
+ pageTitle: getPageTitle().slice(0, 300),
324
+ pageDescription: getPageDescription().slice(0, 300),
325
+ domComplexity: getDomComplexity(document),
326
+ device: bidderRequest?.ortb2?.device || {},
327
+ deviceWidth: screen.width,
328
+ deviceHeight: screen.height,
329
+ timeout: bidderRequest?.timeout,
330
+ viewportHeight: utils.getWinDimensions().visualViewport.height,
331
+ viewportWidth: utils.getWinDimensions().visualViewport.width,
332
+ timeToFirstByte: getTTFBOnce(),
333
+ ext: {
334
+ ...(bidderRequest?.ortb2?.ext || {}),
335
+ adapter_version: ADAPTER_VERSION,
336
+ prebid_version: PREBID_VERSION
337
+ }
338
+ };
339
+
340
+ const wrapperOn =
341
+ typeof window !== "undefined" && window.sevio_wrapper === true;
342
+
343
+ const url = wrapperOn
344
+ ? `${ENDPOINT_URL}?wrapper=true`
345
+ : ENDPOINT_URL;
346
+ return {
347
+ method: ACTION_METHOD,
348
+ url,
349
+ data: payload,
350
+ bidRequest: bidRequests[0],
351
+ };
352
+ });
353
+ },
354
+
355
+ interpretResponse(serverResponse) {
356
+ if (
357
+ !serverResponse ||
358
+ typeof serverResponse !== "object" ||
359
+ !serverResponse.body ||
360
+ typeof serverResponse.body !== "object" ||
361
+ !Array.isArray(serverResponse.body.bids)
362
+ ) {
363
+ return [];
364
+ }
365
+
366
+ const bids = serverResponse.body.bids;
367
+
368
+ bids.forEach((bid) => {
369
+ if (bid && typeof bid === "object") {
370
+ bid.bidder = BIDDER_CODE;
371
+ if ((bid.mediaType || '').toLowerCase() === 'native') {
372
+ const native = parseNativeAd(bid);
373
+ if (native) {
374
+ bid.native = native;
375
+ }
376
+ }
377
+ }
378
+ });
379
+
380
+ return bids;
381
+ },
382
+ onBidWon: function (bid) {},
383
+ onBidderError: function (bidderError) {},
384
+ getUserSyncs: function (syncOptions, serverResponses) {
385
+ const syncs = [];
386
+
387
+ if (syncOptions.pixelEnabled && serverResponses.length > 0) {
388
+ serverResponses.forEach((response) => {
389
+ if (response.body && response.body.userSyncs) {
390
+ response.body.userSyncs.forEach((sync) => {
391
+ if (sync.type === "image" && sync.url) {
392
+ syncs.push({
393
+ type: "image",
394
+ url: sync.url,
395
+ });
396
+ } else if (sync.type === "iframe" && syncOptions.iframeEnabled) {
397
+ syncs.push({
398
+ type: "iframe",
399
+ url: sync.url,
400
+ });
401
+ }
402
+ });
403
+ }
404
+ });
405
+ }
406
+
407
+ return syncs;
408
+ },
409
+ onTimeout: function (timeoutData) {},
410
+ supportedMediaTypes: [BANNER, NATIVE],
411
+ };
412
+
413
+ registerBidder(spec);
@@ -0,0 +1,29 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Sevio Bidder Adapter
5
+ Module Type: Sevio Adapter
6
+ Maintainer: technical@sevio.com
7
+ ```
8
+
9
+ # Description
10
+ Module that connects to Sevio bidder for bids. The Sevio Prebid adapter seamlessly integrates with Prebid.js
11
+ to bring high-performance, real-time bidding capabilities to publishers
12
+
13
+ # Test Parameters
14
+ ```
15
+ var adUnits = [{
16
+ code: 'sevio-ad-b7a0913d-6064-4d72-8d80-ded800a75983',
17
+ mediaTypes: {
18
+ banner: {
19
+ sizes: [[728, 90]]
20
+ }
21
+ },
22
+ bids: [{
23
+ bidder: 'sevio',
24
+ params: {
25
+ zone: 'b7a0913d-6064-4d72-8d80-ded800a75983'
26
+ }
27
+ }]
28
+ }];
29
+ ```
@@ -1,7 +1,8 @@
1
- import { deepAccess, deepSetValue, logError, parseSizesInput, triggerPixel } from '../src/utils.js';
1
+ import { deepAccess, deepSetValue, logWarn, logError, parseSizesInput, triggerPixel } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
4
- import {ortbConverter} from '../libraries/ortbConverter/converter.js'
4
+ import { ortbConverter } from '../libraries/ortbConverter/converter.js';
5
+ import { Renderer } from '../src/Renderer.js';
5
6
 
6
7
  /**
7
8
  * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
@@ -11,7 +12,7 @@ const BIDDER_CODE = 'sparteo';
11
12
  const GVLID = 1028;
12
13
  const TTL = 60;
13
14
  const HTTP_METHOD = 'POST';
14
- const REQUEST_URL = 'https://bid.sparteo.com/auction';
15
+ const REQUEST_URL = `https://bid.sparteo.com/auction?network_id=\${NETWORK_ID}\${SITE_DOMAIN_QUERY}\${APP_DOMAIN_QUERY}\${BUNDLE_QUERY}`;
15
16
  const USER_SYNC_URL_IFRAME = 'https://sync.sparteo.com/sync/iframe.html?from=prebidjs';
16
17
  let isSynced = window.sparteoCrossfire?.started || false;
17
18
 
@@ -24,14 +25,25 @@ const converter = ortbConverter({
24
25
  request(buildRequest, imps, bidderRequest, context) {
25
26
  const request = buildRequest(imps, bidderRequest, context);
26
27
 
27
- deepSetValue(request, 'site.publisher.ext.params.pbjsVersion', '$prebid.version$');
28
-
29
- if (bidderRequest.bids[0].params.networkId) {
30
- request.site.publisher.ext.params.networkId = bidderRequest.bids[0].params.networkId;
28
+ if (!!(bidderRequest?.ortb2?.site) && !!(bidderRequest?.ortb2?.app)) {
29
+ request.site = bidderRequest.ortb2.site;
30
+ delete request.app;
31
31
  }
32
32
 
33
- if (bidderRequest.bids[0].params.publisherId) {
34
- request.site.publisher.ext.params.publisherId = bidderRequest.bids[0].params.publisherId;
33
+ const hasSite = !!request.site;
34
+ const hasApp = !!request.app;
35
+ const root = hasSite ? 'site' : (hasApp ? 'app' : null);
36
+
37
+ if (root) {
38
+ deepSetValue(request, `${root}.publisher.ext.params.pbjsVersion`, '$prebid.version$');
39
+ const networkId = bidderRequest?.bids?.[0]?.params?.networkId;
40
+ if (networkId) {
41
+ deepSetValue(request, `${root}.publisher.ext.params.networkId`, networkId);
42
+ }
43
+ const pubId = bidderRequest?.bids?.[0]?.params?.publisherId;
44
+ if (pubId) {
45
+ deepSetValue(request, `${root}.publisher.ext.params.publisherId`, pubId);
46
+ }
35
47
  }
36
48
 
37
49
  return request;
@@ -54,10 +66,107 @@ const converter = ortbConverter({
54
66
  response.vastUrl = deepAccess(bid, 'ext.prebid.cache.vastXml.url') ?? null;
55
67
  }
56
68
 
69
+ // extract renderer config, if present, and create Prebid renderer
70
+ const rendererConfig = deepAccess(bid, 'ext.prebid.renderer') ?? null;
71
+ if (rendererConfig && rendererConfig.url) {
72
+ response.renderer = createRenderer(rendererConfig);
73
+ }
74
+
57
75
  return response;
58
76
  }
59
77
  });
60
78
 
79
+ function createRenderer(rendererConfig) {
80
+ const renderer = Renderer.install({
81
+ url: rendererConfig.url,
82
+ loaded: false,
83
+ config: rendererConfig
84
+ });
85
+ try {
86
+ renderer.setRender(outstreamRender);
87
+ } catch (err) {
88
+ logWarn('Sparteo Bid Adapter: Prebid Error calling setRender on renderer', err);
89
+ }
90
+ return renderer;
91
+ }
92
+
93
+ function outstreamRender(bid) {
94
+ if (!document.getElementById(bid.adUnitCode)) {
95
+ logError(`Sparteo Bid Adapter: Video renderer did not started. bidResponse.adUnitCode is probably not a DOM element : ${bid.adUnitCode}`);
96
+ return;
97
+ }
98
+
99
+ const config = bid.renderer.getConfig() ?? {};
100
+
101
+ bid.renderer.push(() => {
102
+ window.ANOutstreamVideo.renderAd({
103
+ targetId: bid.adUnitCode, // target div id to render video
104
+ adResponse: {
105
+ ad: {
106
+ video: {
107
+ content: bid.vastXml,
108
+ player_width: bid.width,
109
+ player_height: bid.height
110
+ }
111
+ }
112
+ },
113
+ sizes: [bid.width, bid.height],
114
+ rendererOptions: config.options ?? {}
115
+ });
116
+ });
117
+ }
118
+
119
+ function replaceMacros(payload, endpoint) {
120
+ const networkId =
121
+ payload?.site?.publisher?.ext?.params?.networkId ??
122
+ payload?.app?.publisher?.ext?.params?.networkId;
123
+
124
+ let siteDomain;
125
+ let appDomain;
126
+ let bundle;
127
+
128
+ if (payload?.site) {
129
+ siteDomain = payload.site?.domain;
130
+ if (!siteDomain && payload.site?.page) {
131
+ try { siteDomain = new URL(payload.site.page).hostname; } catch (e) { }
132
+ }
133
+ if (siteDomain) {
134
+ siteDomain = siteDomain.trim().split('/')[0].split(':')[0].replace(/^www\./, '');
135
+ } else {
136
+ logWarn('Domain not found. Missing the site.domain or the site.page field');
137
+ siteDomain = 'unknown';
138
+ }
139
+ } else if (payload?.app) {
140
+ appDomain = payload.app?.domain || '';
141
+ if (appDomain) {
142
+ appDomain = appDomain.trim().split('/')[0].split(':')[0].replace(/^www\./, '');
143
+ } else {
144
+ appDomain = 'unknown';
145
+ }
146
+
147
+ const raw = payload.app?.bundle ?? '';
148
+ const trimmed = String(raw).trim();
149
+ if (!trimmed || trimmed.toLowerCase() === 'null') {
150
+ logWarn('Bundle not found. Missing the app.bundle field.');
151
+ bundle = 'unknown';
152
+ } else {
153
+ bundle = trimmed;
154
+ }
155
+ }
156
+
157
+ const macroMap = {
158
+ NETWORK_ID: networkId ?? '',
159
+ BUNDLE_QUERY: payload?.app ? (bundle ? `&bundle=${encodeURIComponent(bundle)}` : '') : '',
160
+ SITE_DOMAIN_QUERY: siteDomain ? `&site_domain=${encodeURIComponent(siteDomain)}` : '',
161
+ APP_DOMAIN_QUERY: appDomain ? `&app_domain=${encodeURIComponent(appDomain)}` : ''
162
+ };
163
+
164
+ return endpoint.replace(
165
+ /\$\{(NETWORK_ID|SITE_DOMAIN_QUERY|APP_DOMAIN_QUERY|BUNDLE_QUERY)\}/g,
166
+ (_, key) => String(macroMap[key] ?? '')
167
+ );
168
+ }
169
+
61
170
  export const spec = {
62
171
  code: BIDDER_CODE,
63
172
  gvlid: GVLID,
@@ -119,9 +228,12 @@ export const spec = {
119
228
  buildRequests: function (bidRequests, bidderRequest) {
120
229
  const payload = converter.toORTB({bidRequests, bidderRequest})
121
230
 
231
+ const endpoint = bidRequests[0].params.endpoint ? bidRequests[0].params.endpoint : REQUEST_URL;
232
+ const url = replaceMacros(payload, endpoint);
233
+
122
234
  return {
123
235
  method: HTTP_METHOD,
124
- url: bidRequests[0].params.endpoint ? bidRequests[0].params.endpoint : REQUEST_URL,
236
+ url: url,
125
237
  data: payload
126
238
  };
127
239
  },