prebid.js 5.17.0 → 6.0.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 (145) hide show
  1. package/.babelrc.js +3 -6
  2. package/README.md +3 -1
  3. package/browsers.json +1 -8
  4. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  5. package/modules/.submodules.json +1 -0
  6. package/modules/adfBidAdapter.js +21 -16
  7. package/modules/adgenerationBidAdapter.js +28 -4
  8. package/modules/adkernelBidAdapter.js +2 -1
  9. package/modules/admixerBidAdapter.js +11 -0
  10. package/modules/adtelligentBidAdapter.js +2 -1
  11. package/modules/airgridRtdProvider.js +1 -1
  12. package/modules/akamaiDapRtdProvider.js +474 -0
  13. package/modules/akamaiDapRtdProvider.md +47 -0
  14. package/modules/aolBidAdapter.js +2 -1
  15. package/modules/appnexusBidAdapter.js +5 -3
  16. package/modules/atsAnalyticsAdapter.js +67 -46
  17. package/modules/atsAnalyticsAdapter.md +1 -0
  18. package/modules/betweenBidAdapter.js +20 -3
  19. package/modules/bliinkBidAdapter.js +58 -32
  20. package/modules/bliinkBidAdapter.md +29 -6
  21. package/modules/browsiRtdProvider.js +106 -18
  22. package/modules/cleanioRtdProvider.js +192 -0
  23. package/modules/cleanioRtdProvider.md +59 -0
  24. package/modules/codefuelBidAdapter.js +183 -0
  25. package/modules/codefuelBidAdapter.md +111 -0
  26. package/modules/connectIdSystem.js +104 -0
  27. package/modules/connectIdSystem.md +33 -0
  28. package/modules/cwireBidAdapter.js +272 -0
  29. package/modules/cwireBidAdapter.md +43 -0
  30. package/modules/deepintentBidAdapter.js +106 -9
  31. package/modules/deepintentBidAdapter.md +36 -1
  32. package/modules/deltaprojectsBidAdapter.js +252 -0
  33. package/modules/deltaprojectsBidAdapter.md +32 -0
  34. package/modules/dgkeywordRtdProvider.js +0 -1
  35. package/modules/engageyaBidAdapter.js +157 -0
  36. package/modules/gridBidAdapter.js +1 -0
  37. package/modules/gumgumBidAdapter.js +8 -0
  38. package/modules/inskinBidAdapter.js +7 -3
  39. package/modules/ixBidAdapter.js +8 -1
  40. package/modules/jixieBidAdapter.js +8 -2
  41. package/modules/justpremiumBidAdapter.js +6 -1
  42. package/modules/limelightDigitalBidAdapter.js +22 -2
  43. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  44. package/modules/mediakeysBidAdapter.js +2 -1
  45. package/modules/multibid/index.js +3 -3
  46. package/modules/nativoBidAdapter.js +6 -2
  47. package/modules/nextMillenniumBidAdapter.js +12 -3
  48. package/modules/oguryBidAdapter.js +36 -7
  49. package/modules/openxBidAdapter.js +34 -22
  50. package/modules/operaadsBidAdapter.js +21 -1
  51. package/modules/otmBidAdapter.js +146 -0
  52. package/modules/otmBidAdapter.md +27 -26
  53. package/modules/outbrainBidAdapter.js +5 -0
  54. package/modules/pixfutureBidAdapter.js +24 -4
  55. package/modules/pixfutureBidAdapter.md +127 -0
  56. package/modules/playwireBidAdapter.md +61 -0
  57. package/modules/prebidServerBidAdapter/index.js +1 -1
  58. package/modules/proxistoreBidAdapter.js +4 -6
  59. package/modules/publinkIdSystem.js +11 -6
  60. package/modules/pubmaticBidAdapter.js +9 -0
  61. package/modules/pubmaticBidAdapter.md +1 -1
  62. package/modules/rtdModule/index.js +2 -2
  63. package/modules/sonobiBidAdapter.js +7 -0
  64. package/modules/sortableBidAdapter.js +1 -0
  65. package/modules/talkadsBidAdapter.js +129 -0
  66. package/modules/talkadsBidAdapter.md +60 -0
  67. package/modules/teadsBidAdapter.js +3 -0
  68. package/modules/tripleliftBidAdapter.js +22 -5
  69. package/modules/trustxBidAdapter.js +8 -6
  70. package/modules/undertoneBidAdapter.js +9 -5
  71. package/modules/undertoneBidAdapter.md +5 -1
  72. package/modules/unicornBidAdapter.js +3 -3
  73. package/modules/userId/eids.js +18 -0
  74. package/modules/userId/eids.md +7 -0
  75. package/modules/userId/userId.md +12 -0
  76. package/modules/ventesBidAdapter.js +370 -0
  77. package/modules/ventesBidAdapter.md +94 -0
  78. package/modules/videobyteBidAdapter.js +13 -6
  79. package/modules/videobyteBidAdapter.md +49 -0
  80. package/modules/visxBidAdapter.js +15 -22
  81. package/modules/yahoosspBidAdapter.js +637 -0
  82. package/modules/yahoosspBidAdapter.md +795 -0
  83. package/modules/yieldlabBidAdapter.js +48 -3
  84. package/modules/yieldlabBidAdapter.md +16 -1
  85. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  86. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  87. package/package.json +1 -1
  88. package/src/adapterManager.js +5 -0
  89. package/src/adapters/bidderFactory.js +4 -3
  90. package/src/auction.js +11 -11
  91. package/src/constants.json +1 -0
  92. package/src/secureCreatives.js +6 -7
  93. package/src/targeting.js +11 -9
  94. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  95. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  96. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  97. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  98. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  99. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  100. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  101. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  102. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  103. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  104. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  105. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  106. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  107. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  108. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  109. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  110. package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
  111. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  112. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  113. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  114. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  115. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  116. package/test/spec/modules/multibid_spec.js +31 -31
  117. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  118. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  119. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  120. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  121. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  122. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  123. package/test/spec/modules/publinkIdSystem_spec.js +6 -6
  124. package/test/spec/modules/pubmaticBidAdapter_spec.js +39 -1
  125. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  126. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  127. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  128. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  129. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  130. package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
  131. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  132. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  133. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  134. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  135. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  136. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  137. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  138. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  139. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  140. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  141. package/test/spec/unit/pbjs_api_spec.js +37 -2
  142. package/test/spec/unit/secureCreatives_spec.js +54 -25
  143. package/wdio.conf.js +1 -1
  144. package/modules/turktelekomBidAdapter.md +0 -49
  145. package/yarn.lock +0 -13122
@@ -0,0 +1,637 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
+ import { deepAccess, isFn, isStr, isNumber, isArray, isEmpty, isPlainObject, generateUUID, logInfo, logWarn } from '../src/utils.js';
4
+ import { config } from '../src/config.js';
5
+ import { Renderer } from '../src/Renderer.js';
6
+
7
+ const INTEGRATION_METHOD = 'prebid.js';
8
+ const BIDDER_CODE = 'yahoossp';
9
+ const ADAPTER_VERSION = '1.0.1';
10
+ const PREBID_VERSION = '$prebid.version$';
11
+ const DEFAULT_BID_TTL = 300;
12
+ const TEST_MODE_DCN = '8a969516017a7a396ec539d97f540011';
13
+ const TEST_MODE_PUBID_DCN = '1234567';
14
+ const TEST_MODE_BANNER_POS = '8a969978017a7aaabab4ab0bc01a0009';
15
+ const TEST_MODE_VIDEO_POS = '8a96958a017a7a57ac375d50c0c700cc';
16
+ const DEFAULT_RENDERER_TIMEOUT = 700;
17
+ const DEFAULT_CURRENCY = 'USD';
18
+ const SSP_ENDPOINT_DCN_POS = 'https://c2shb.pubgw.yahoo.com/bidRequest';
19
+ const SSP_ENDPOINT_PUBID = 'https://c2shb.pubgw.yahoo.com/admax/bid/partners/PBJS';
20
+ const SUPPORTED_USER_ID_SOURCES = [
21
+ 'admixer.net',
22
+ 'adserver.org',
23
+ 'adtelligent.com',
24
+ 'akamai.com',
25
+ 'amxrtb.com',
26
+ 'audigent.com',
27
+ 'britepool.com',
28
+ 'criteo.com',
29
+ 'crwdcntrl.net',
30
+ 'deepintent.com',
31
+ 'hcn.health',
32
+ 'id5-sync.com',
33
+ 'idx.lat',
34
+ 'intentiq.com',
35
+ 'intimatemerger.com',
36
+ 'liveintent.com',
37
+ 'liveramp.com',
38
+ 'mediawallahscript.com',
39
+ 'merkleinc.com',
40
+ 'netid.de',
41
+ 'neustar.biz',
42
+ 'nextroll.com',
43
+ 'novatiq.com',
44
+ 'parrable.com',
45
+ 'pubcid.org',
46
+ 'quantcast.com',
47
+ 'quantcast.com',
48
+ 'tapad.com',
49
+ 'uidapi.com',
50
+ 'verizonmedia.com',
51
+ 'yahoo.com',
52
+ 'zeotap.com'
53
+ ];
54
+
55
+ /* Utility functions */
56
+ function hasPurpose1Consent(bidderRequest) {
57
+ if (bidderRequest && bidderRequest.gdprConsent) {
58
+ if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) {
59
+ return !!false;
60
+ }
61
+ }
62
+ return true;
63
+ }
64
+
65
+ function getSize(size) {
66
+ return {
67
+ w: parseInt(size[0]),
68
+ h: parseInt(size[1])
69
+ }
70
+ }
71
+
72
+ function transformSizes(sizes) {
73
+ if (isArray(sizes) && sizes.length === 2 && !isArray(sizes[0])) {
74
+ return [ getSize(sizes) ];
75
+ }
76
+ return sizes.map(getSize);
77
+ }
78
+
79
+ function extractUserSyncUrls(syncOptions, pixels) {
80
+ let itemsRegExp = /(img|iframe)[\s\S]*?src\s*=\s*("|')(.*?)\2/gi;
81
+ let tagNameRegExp = /\w*(?=\s)/;
82
+ let srcRegExp = /src=("|')(.*?)\1/;
83
+ let userSyncObjects = [];
84
+
85
+ if (pixels) {
86
+ let matchedItems = pixels.match(itemsRegExp);
87
+ if (matchedItems) {
88
+ matchedItems.forEach(item => {
89
+ let tagName = item.match(tagNameRegExp)[0];
90
+ let url = item.match(srcRegExp)[2];
91
+
92
+ if (tagName && url) {
93
+ let tagType = tagName.toLowerCase() === 'img' ? 'image' : 'iframe';
94
+ if ((!syncOptions.iframeEnabled && tagType === 'iframe') ||
95
+ (!syncOptions.pixelEnabled && tagType === 'image')) {
96
+ return;
97
+ }
98
+ userSyncObjects.push({
99
+ type: tagType,
100
+ url: url
101
+ });
102
+ }
103
+ });
104
+ }
105
+ }
106
+
107
+ return userSyncObjects;
108
+ }
109
+
110
+ function getSupportedEids(bid) {
111
+ if (isArray(deepAccess(bid, 'userIdAsEids'))) {
112
+ return bid.userIdAsEids.filter(eid => {
113
+ return SUPPORTED_USER_ID_SOURCES.indexOf(eid.source) !== -1;
114
+ });
115
+ }
116
+ return [];
117
+ }
118
+
119
+ function isSecure(bid) {
120
+ return deepAccess(bid, 'params.bidOverride.imp.secure') || (document.location.protocol === 'https:') ? 1 : 0;
121
+ };
122
+
123
+ function getPubIdMode(bid) {
124
+ let pubIdMode;
125
+ if (deepAccess(bid, 'params.pubId')) {
126
+ pubIdMode = true;
127
+ } else if (deepAccess(bid, 'params.dcn') && deepAccess(bid, 'params.pos')) {
128
+ pubIdMode = false;
129
+ };
130
+ return pubIdMode;
131
+ };
132
+
133
+ function getAdapterMode() {
134
+ let adapterMode = config.getConfig('yahoossp.mode');
135
+ adapterMode = adapterMode ? adapterMode.toLowerCase() : undefined;
136
+ if (typeof adapterMode === 'undefined' || adapterMode === BANNER) {
137
+ return BANNER;
138
+ } else if (adapterMode === VIDEO) {
139
+ return VIDEO;
140
+ } else if (adapterMode === 'all') {
141
+ return '*';
142
+ }
143
+ };
144
+
145
+ function getResponseFormat(bid) {
146
+ const adm = bid.adm;
147
+ if (adm.indexOf('o2playerSettings') !== -1 || adm.indexOf('YAHOO.VideoPlatform.VideoPlayer') !== -1 || adm.indexOf('AdPlacement') !== -1) {
148
+ return BANNER;
149
+ } else if (adm.indexOf('VAST') !== -1) {
150
+ return VIDEO;
151
+ }
152
+ };
153
+
154
+ function getFloorModuleData(bid) {
155
+ const adapterMode = getAdapterMode();
156
+ const getFloorRequestObject = {
157
+ currency: deepAccess(bid, 'params.bidOverride.cur') || DEFAULT_CURRENCY,
158
+ mediaType: adapterMode,
159
+ size: '*'
160
+ };
161
+ return (isFn(bid.getFloor)) ? bid.getFloor(getFloorRequestObject) : false;
162
+ };
163
+
164
+ function filterBidRequestByMode(validBidRequests) {
165
+ const mediaTypesMode = getAdapterMode();
166
+ let result = [];
167
+ if (mediaTypesMode === BANNER) {
168
+ result = validBidRequests.filter(bid => {
169
+ return Object.keys(bid.mediaTypes).some(item => item === BANNER);
170
+ });
171
+ } else if (mediaTypesMode === VIDEO) {
172
+ result = validBidRequests.filter(bid => {
173
+ return Object.keys(bid.mediaTypes).some(item => item === VIDEO);
174
+ });
175
+ } else if (mediaTypesMode === '*') {
176
+ result = validBidRequests.filter(bid => {
177
+ return Object.keys(bid.mediaTypes).some(item => item === BANNER || item === VIDEO);
178
+ });
179
+ };
180
+ return result;
181
+ };
182
+
183
+ function validateAppendObject(validationType, allowedKeys, inputObject, appendToObject) {
184
+ const outputObject = {
185
+ ...appendToObject
186
+ };
187
+
188
+ for (const objectKey in inputObject) {
189
+ switch (validationType) {
190
+ case 'string':
191
+ if (allowedKeys.indexOf(objectKey) !== -1 && isStr(inputObject[objectKey])) {
192
+ outputObject[objectKey] = inputObject[objectKey];
193
+ };
194
+ break;
195
+ case 'number':
196
+ if (allowedKeys.indexOf(objectKey) !== -1 && isNumber(inputObject[objectKey])) {
197
+ outputObject[objectKey] = inputObject[objectKey];
198
+ };
199
+ break;
200
+
201
+ case 'array':
202
+ if (allowedKeys.indexOf(objectKey) !== -1 && isArray(inputObject[objectKey])) {
203
+ outputObject[objectKey] = inputObject[objectKey];
204
+ };
205
+ break;
206
+ case 'object':
207
+ if (allowedKeys.indexOf(objectKey) !== -1 && isPlainObject(inputObject[objectKey])) {
208
+ outputObject[objectKey] = inputObject[objectKey];
209
+ };
210
+ break;
211
+ case 'objectAllKeys':
212
+ if (isPlainObject(inputObject)) {
213
+ outputObject[objectKey] = inputObject[objectKey];
214
+ };
215
+ break;
216
+ };
217
+ };
218
+ return outputObject;
219
+ };
220
+
221
+ function getTtl(bidderRequest) {
222
+ const globalTTL = config.getConfig('yahoossp.ttl');
223
+ return globalTTL ? validateTTL(globalTTL) : validateTTL(deepAccess(bidderRequest, 'params.ttl'));
224
+ };
225
+
226
+ function validateTTL(ttl) {
227
+ return (isNumber(ttl) && ttl > 0 && ttl < 3600) ? ttl : DEFAULT_BID_TTL
228
+ };
229
+
230
+ function isNotEmptyStr(value) {
231
+ return (isStr(value) && value.length > 0);
232
+ };
233
+
234
+ function generateOpenRtbObject(bidderRequest, bid) {
235
+ if (bidderRequest) {
236
+ let outBoundBidRequest = {
237
+ id: generateUUID(),
238
+ cur: [getFloorModuleData(bidderRequest).currency || deepAccess(bid, 'params.bidOverride.cur') || DEFAULT_CURRENCY],
239
+ imp: [],
240
+ site: {
241
+ page: deepAccess(bidderRequest, 'refererInfo.referer'),
242
+ },
243
+ device: {
244
+ dnt: 0,
245
+ ua: navigator.userAgent,
246
+ ip: deepAccess(bid, 'params.bidOverride.device.ip') || deepAccess(bid, 'params.ext.ip') || undefined
247
+ },
248
+ regs: {
249
+ ext: {
250
+ 'us_privacy': bidderRequest.uspConsent ? bidderRequest.uspConsent : '',
251
+ gdpr: bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies ? 1 : 0
252
+ }
253
+ },
254
+ source: {
255
+ ext: {
256
+ hb: 1,
257
+ adapterver: ADAPTER_VERSION,
258
+ prebidver: PREBID_VERSION,
259
+ integration: {
260
+ name: INTEGRATION_METHOD,
261
+ ver: PREBID_VERSION
262
+ }
263
+ },
264
+ fd: 1
265
+ },
266
+ user: {
267
+ ext: {
268
+ consent: bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies
269
+ ? bidderRequest.gdprConsent.consentString : '',
270
+ eids: getSupportedEids(bid)
271
+ }
272
+ }
273
+ };
274
+
275
+ if (getPubIdMode(bid) === true) {
276
+ outBoundBidRequest.site.publisher = {
277
+ id: bid.params.pubId
278
+ }
279
+ if (deepAccess(bid, 'params.bidOverride.site.id') || deepAccess(bid, 'params.siteId')) {
280
+ outBoundBidRequest.site.id = deepAccess(bid, 'params.bidOverride.site.id') || bid.params.siteId;
281
+ }
282
+ } else {
283
+ outBoundBidRequest.site.id = bid.params.dcn;
284
+ };
285
+
286
+ if (config.getConfig('ortb2')) {
287
+ outBoundBidRequest = appendFirstPartyData(outBoundBidRequest, bid);
288
+ };
289
+
290
+ if (deepAccess(bid, 'schain')) {
291
+ outBoundBidRequest.source.ext.schain = bid.schain;
292
+ outBoundBidRequest.source.ext.schain.nodes[0].rid = outBoundBidRequest.id;
293
+ };
294
+
295
+ return outBoundBidRequest;
296
+ };
297
+ };
298
+
299
+ function appendImpObject(bid, openRtbObject) {
300
+ const mediaTypeMode = getAdapterMode();
301
+
302
+ if (openRtbObject && bid) {
303
+ const impObject = {
304
+ id: bid.bidId,
305
+ secure: isSecure(bid),
306
+ bidfloor: getFloorModuleData(bid).floor || deepAccess(bid, 'params.bidOverride.imp.bidfloor')
307
+ };
308
+
309
+ if (bid.mediaTypes.banner && (typeof mediaTypeMode === 'undefined' || mediaTypeMode === BANNER || mediaTypeMode === '*')) {
310
+ impObject.banner = {
311
+ mimes: bid.mediaTypes.banner.mimes || ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
312
+ format: transformSizes(bid.sizes)
313
+ };
314
+ if (bid.mediaTypes.banner.pos) {
315
+ impObject.banner.pos = bid.mediaTypes.banner.pos;
316
+ };
317
+ };
318
+
319
+ if (bid.mediaTypes.video && (mediaTypeMode === VIDEO || mediaTypeMode === '*')) {
320
+ const playerSize = transformSizes(bid.mediaTypes.video.playerSize);
321
+ impObject.video = {
322
+ mimes: deepAccess(bid, 'params.bidOverride.imp.video.mimes') || bid.mediaTypes.video.mimes || ['video/mp4', 'application/javascript'],
323
+ w: deepAccess(bid, 'params.bidOverride.imp.video.w') || playerSize[0].w,
324
+ h: deepAccess(bid, 'params.bidOverride.imp.video.h') || playerSize[0].h,
325
+ maxbitrate: deepAccess(bid, 'params.bidOverride.imp.video.maxbitrate') || bid.mediaTypes.video.maxbitrate || undefined,
326
+ maxduration: deepAccess(bid, 'params.bidOverride.imp.video.maxduration') || bid.mediaTypes.video.maxduration || undefined,
327
+ minduration: deepAccess(bid, 'params.bidOverride.imp.video.minduration') || bid.mediaTypes.video.minduration || undefined,
328
+ api: deepAccess(bid, 'params.bidOverride.imp.video.api') || bid.mediaTypes.video.api || [2],
329
+ delivery: deepAccess(bid, 'params.bidOverride.imp.video.delivery') || bid.mediaTypes.video.delivery || undefined,
330
+ pos: deepAccess(bid, 'params.bidOverride.imp.video.pos') || bid.mediaTypes.video.pos || undefined,
331
+ playbackmethod: deepAccess(bid, 'params.bidOverride.imp.video.playbackmethod') || bid.mediaTypes.video.playbackmethod || undefined,
332
+ placement: deepAccess(bid, 'params.bidOverride.imp.video.placement') || bid.mediaTypes.video.placement || undefined,
333
+ linearity: deepAccess(bid, 'params.bidOverride.imp.video.linearity') || bid.mediaTypes.video.linearity || 1,
334
+ protocols: deepAccess(bid, 'params.bidOverride.imp.video.protocols') || bid.mediaTypes.video.protocols || [2, 5],
335
+ startdelay: deepAccess(bid, 'params.bidOverride.imp.video.startdelay') || bid.mediaTypes.video.startdelay || 0,
336
+ rewarded: deepAccess(bid, 'params.bidOverride.imp.video.rewarded') || undefined,
337
+ }
338
+ }
339
+
340
+ impObject.ext = {
341
+ dfp_ad_unit_code: bid.adUnitCode
342
+ };
343
+
344
+ if (deepAccess(bid, 'params.kvp') && isPlainObject(bid.params.kvp)) {
345
+ impObject.ext.kvs = {};
346
+ for (const key in bid.params.kvp) {
347
+ if (isStr(bid.params.kvp[key]) || isNumber(bid.params.kvp[key])) {
348
+ impObject.ext.kvs[key] = bid.params.kvp[key];
349
+ } else if (isArray(bid.params.kvp[key])) {
350
+ const array = bid.params.kvp[key];
351
+ if (array.every(value => isStr(value)) || array.every(value => isNumber(value))) {
352
+ impObject.ext.kvs[key] = bid.params.kvp[key];
353
+ }
354
+ }
355
+ }
356
+ };
357
+
358
+ if (deepAccess(bid, 'ortb2Imp.ext.data') && isPlainObject(bid.ortb2Imp.ext.data)) {
359
+ impObject.ext.data = bid.ortb2Imp.ext.data;
360
+ };
361
+
362
+ if (getPubIdMode(bid) === false) {
363
+ impObject.tagid = bid.params.pos;
364
+ impObject.ext.pos = bid.params.pos;
365
+ } else if (deepAccess(bid, 'params.placementId')) {
366
+ impObject.tagid = bid.params.placementId
367
+ };
368
+
369
+ openRtbObject.imp.push(impObject);
370
+ };
371
+ };
372
+
373
+ function appendFirstPartyData(outBoundBidRequest, bid) {
374
+ const ortb2Object = config.getConfig('ortb2');
375
+ const siteObject = deepAccess(ortb2Object, 'site') || undefined;
376
+ const siteContentObject = deepAccess(siteObject, 'content') || undefined;
377
+ const siteContentDataArray = deepAccess(siteObject, 'content.data') || undefined;
378
+ const appContentObject = deepAccess(ortb2Object, 'app.content') || undefined;
379
+ const appContentDataArray = deepAccess(ortb2Object, 'app.content.data') || undefined;
380
+ const userObject = deepAccess(ortb2Object, 'user') || undefined;
381
+
382
+ if (siteObject && isPlainObject(siteObject)) {
383
+ const allowedSiteStringKeys = ['name', 'domain', 'page', 'ref', 'keywords', 'search'];
384
+ const allowedSiteArrayKeys = ['cat', 'sectioncat', 'pagecat'];
385
+ const allowedSiteObjectKeys = ['ext'];
386
+ outBoundBidRequest.site = validateAppendObject('string', allowedSiteStringKeys, siteObject, outBoundBidRequest.site);
387
+ outBoundBidRequest.site = validateAppendObject('array', allowedSiteArrayKeys, siteObject, outBoundBidRequest.site);
388
+ outBoundBidRequest.site = validateAppendObject('object', allowedSiteObjectKeys, siteObject, outBoundBidRequest.site);
389
+ };
390
+
391
+ if (siteContentObject && isPlainObject(siteContentObject)) {
392
+ const allowedContentStringKeys = ['id', 'title', 'series', 'season', 'genre', 'contentrating', 'language'];
393
+ const allowedContentNumberkeys = ['episode', 'prodq', 'context', 'livestream', 'len'];
394
+ const allowedContentArrayKeys = ['cat'];
395
+ const allowedContentObjectKeys = ['ext'];
396
+ outBoundBidRequest.site.content = validateAppendObject('string', allowedContentStringKeys, siteContentObject, outBoundBidRequest.site.content);
397
+ outBoundBidRequest.site.content = validateAppendObject('number', allowedContentNumberkeys, siteContentObject, outBoundBidRequest.site.content);
398
+ outBoundBidRequest.site.content = validateAppendObject('array', allowedContentArrayKeys, siteContentObject, outBoundBidRequest.site.content);
399
+ outBoundBidRequest.site.content = validateAppendObject('object', allowedContentObjectKeys, siteContentObject, outBoundBidRequest.site.content);
400
+
401
+ if (siteContentDataArray && isArray(siteContentDataArray)) {
402
+ siteContentDataArray.every(dataObject => {
403
+ let newDataObject = {};
404
+ const allowedContentDataStringKeys = ['id', 'name'];
405
+ const allowedContentDataArrayKeys = ['segment'];
406
+ const allowedContentDataObjectKeys = ['ext'];
407
+ newDataObject = validateAppendObject('string', allowedContentDataStringKeys, dataObject, newDataObject);
408
+ newDataObject = validateAppendObject('array', allowedContentDataArrayKeys, dataObject, newDataObject);
409
+ newDataObject = validateAppendObject('object', allowedContentDataObjectKeys, dataObject, newDataObject);
410
+ outBoundBidRequest.site.content.data = [];
411
+ outBoundBidRequest.site.content.data.push(newDataObject);
412
+ })
413
+ };
414
+ };
415
+
416
+ if (appContentObject && isPlainObject(appContentObject)) {
417
+ if (appContentDataArray && isArray(appContentDataArray)) {
418
+ appContentDataArray.every(dataObject => {
419
+ let newDataObject = {};
420
+ const allowedContentDataStringKeys = ['id', 'name'];
421
+ const allowedContentDataArrayKeys = ['segment'];
422
+ const allowedContentDataObjectKeys = ['ext'];
423
+ newDataObject = validateAppendObject('string', allowedContentDataStringKeys, dataObject, newDataObject);
424
+ newDataObject = validateAppendObject('array', allowedContentDataArrayKeys, dataObject, newDataObject);
425
+ newDataObject = validateAppendObject('object', allowedContentDataObjectKeys, dataObject, newDataObject);
426
+ outBoundBidRequest.app = {
427
+ content: {
428
+ data: []
429
+ }
430
+ };
431
+ outBoundBidRequest.app.content.data.push(newDataObject);
432
+ })
433
+ };
434
+ };
435
+
436
+ if (userObject && isPlainObject(userObject)) {
437
+ const allowedUserStrings = ['id', 'buyeruid', 'gender', 'keywords', 'customdata'];
438
+ const allowedUserNumbers = ['yob'];
439
+ const allowedUserArrays = ['data'];
440
+ const allowedUserObjects = ['ext'];
441
+ outBoundBidRequest.user = validateAppendObject('string', allowedUserStrings, userObject, outBoundBidRequest.user);
442
+ outBoundBidRequest.user = validateAppendObject('number', allowedUserNumbers, userObject, outBoundBidRequest.user);
443
+ outBoundBidRequest.user = validateAppendObject('array', allowedUserArrays, userObject, outBoundBidRequest.user);
444
+ outBoundBidRequest.user.ext = validateAppendObject('object', allowedUserObjects, userObject, outBoundBidRequest.user.ext);
445
+ };
446
+
447
+ return outBoundBidRequest;
448
+ };
449
+
450
+ function generateServerRequest({payload, requestOptions, bidderRequest}) {
451
+ const pubIdMode = getPubIdMode(bidderRequest);
452
+ let sspEndpoint = config.getConfig('yahoossp.endpoint') || SSP_ENDPOINT_DCN_POS;
453
+
454
+ if (pubIdMode === true) {
455
+ sspEndpoint = config.getConfig('yahoossp.endpoint') || SSP_ENDPOINT_PUBID;
456
+ };
457
+
458
+ if (deepAccess(bidderRequest, 'params.testing.e2etest') === true) {
459
+ logInfo('yahoossp adapter e2etest mode is active');
460
+ requestOptions.withCredentials = false;
461
+
462
+ if (pubIdMode === true) {
463
+ payload.site.id = TEST_MODE_PUBID_DCN;
464
+ } else {
465
+ const mediaTypeMode = getAdapterMode();
466
+ payload.site.id = TEST_MODE_DCN;
467
+ payload.imp.forEach(impObject => {
468
+ impObject.ext.e2eTestMode = true;
469
+ if (mediaTypeMode === BANNER) {
470
+ impObject.tagid = TEST_MODE_BANNER_POS; // banner passback
471
+ } else if (mediaTypeMode === VIDEO) {
472
+ impObject.tagid = TEST_MODE_VIDEO_POS; // video passback
473
+ } else {
474
+ logWarn('yahoossp adapter e2etest mode does not support yahoossp.mode="all". \n Please specify either "banner" or "video"');
475
+ logWarn('yahoossp adapter e2etest mode: Please make sure your adUnit matches the yahoossp.mode video or banner');
476
+ }
477
+ });
478
+ }
479
+ };
480
+ logWarn('yahoossp adapter endpoint override enabled. Pointing requests to: ', sspEndpoint);
481
+
482
+ return {
483
+ url: sspEndpoint,
484
+ method: 'POST',
485
+ data: payload,
486
+ options: requestOptions,
487
+ bidderRequest: bidderRequest
488
+ };
489
+ };
490
+
491
+ function createRenderer(bidderRequest, bidResponse) {
492
+ const renderer = Renderer.install({
493
+ url: 'https://cdn.vidible.tv/prod/hb-outstream-renderer/renderer.js',
494
+ loaded: false,
495
+ adUnitCode: bidderRequest.adUnitCode
496
+ })
497
+
498
+ try {
499
+ renderer.setRender(function(bidResponse) {
500
+ setTimeout(function() {
501
+ // eslint-disable-next-line no-undef
502
+ o2PlayerRender(bidResponse);
503
+ }, deepAccess(bidderRequest, 'params.testing.renderer.setTimeout') || DEFAULT_RENDERER_TIMEOUT);
504
+ });
505
+ } catch (error) {
506
+ logWarn('yahoossp renderer error: setRender() failed', error);
507
+ }
508
+ return renderer;
509
+ }
510
+ /* Utility functions */
511
+
512
+ export const spec = {
513
+ code: BIDDER_CODE,
514
+ aliases: [],
515
+ supportedMediaTypes: [BANNER, VIDEO],
516
+
517
+ isBidRequestValid: function(bid) {
518
+ const params = bid.params;
519
+ if (deepAccess(params, 'testing.e2etest') === true) {
520
+ return true;
521
+ } else if (
522
+ isPlainObject(params) &&
523
+ (isNotEmptyStr(params.pubId) || (isNotEmptyStr(params.dcn) && isNotEmptyStr(params.pos)))
524
+ ) {
525
+ return true;
526
+ } else {
527
+ logWarn('yahoossp bidder params missing or incorrect, please pass object with either: dcn & pos OR pubId');
528
+ return false;
529
+ }
530
+ },
531
+
532
+ buildRequests: function(validBidRequests, bidderRequest) {
533
+ if (isEmpty(validBidRequests) || isEmpty(bidderRequest)) {
534
+ logWarn('yahoossp Adapter: buildRequests called with either empty "validBidRequests" or "bidderRequest"');
535
+ return undefined;
536
+ };
537
+
538
+ const requestOptions = {
539
+ contentType: 'application/json',
540
+ customHeaders: {
541
+ 'x-openrtb-version': '2.5'
542
+ }
543
+ };
544
+
545
+ requestOptions.withCredentials = hasPurpose1Consent(bidderRequest);
546
+
547
+ const filteredBidRequests = filterBidRequestByMode(validBidRequests);
548
+
549
+ if (config.getConfig('yahoossp.singleRequestMode') === true) {
550
+ const payload = generateOpenRtbObject(bidderRequest, filteredBidRequests[0]);
551
+ filteredBidRequests.forEach(bid => {
552
+ appendImpObject(bid, payload);
553
+ });
554
+
555
+ return generateServerRequest({payload, requestOptions, bidderRequest});
556
+ }
557
+
558
+ return filteredBidRequests.map(bid => {
559
+ const payloadClone = generateOpenRtbObject(bidderRequest, bid);
560
+ appendImpObject(bid, payloadClone);
561
+ return generateServerRequest({payload: payloadClone, requestOptions, bidderRequest: bid});
562
+ });
563
+ },
564
+
565
+ interpretResponse: function(serverResponse, { data, bidderRequest }) {
566
+ const response = [];
567
+ if (!serverResponse.body || !Array.isArray(serverResponse.body.seatbid)) {
568
+ return response;
569
+ }
570
+
571
+ let seatbids = serverResponse.body.seatbid;
572
+ seatbids.forEach(seatbid => {
573
+ let bid;
574
+
575
+ try {
576
+ bid = seatbid.bid[0];
577
+ } catch (e) {
578
+ return response;
579
+ }
580
+
581
+ let cpm = (bid.ext && bid.ext.encp) ? bid.ext.encp : bid.price;
582
+
583
+ let bidResponse = {
584
+ adId: deepAccess(bid, 'adId') ? bid.adId : bid.impid || bid.crid,
585
+ adUnitCode: bidderRequest.adUnitCode,
586
+ requestId: bid.impid,
587
+ bidderCode: spec.code,
588
+ cpm: cpm,
589
+ width: bid.w,
590
+ height: bid.h,
591
+ creativeId: bid.crid || 0,
592
+ currency: bid.cur || DEFAULT_CURRENCY,
593
+ dealId: bid.dealid ? bid.dealid : null,
594
+ netRevenue: true,
595
+ ttl: getTtl(bidderRequest),
596
+ meta: {
597
+ advertiserDomains: bid.adomain,
598
+ }
599
+ };
600
+
601
+ const responseAdmFormat = getResponseFormat(bid);
602
+ if (responseAdmFormat === BANNER) {
603
+ bidResponse.mediaType = BANNER;
604
+ bidResponse.ad = bid.adm;
605
+ bidResponse.meta.mediaType = BANNER;
606
+ } else if (responseAdmFormat === VIDEO) {
607
+ bidResponse.mediaType = VIDEO;
608
+ bidResponse.meta.mediaType = VIDEO;
609
+ bidResponse.vastXml = bid.adm;
610
+
611
+ if (bid.nurl) {
612
+ bidResponse.vastUrl = bid.nurl;
613
+ };
614
+ }
615
+
616
+ if (deepAccess(bidderRequest, 'mediaTypes.video.context') === 'outstream' && !bidderRequest.renderer) {
617
+ bidResponse.renderer = createRenderer(bidderRequest, bidResponse) || undefined;
618
+ }
619
+
620
+ response.push(bidResponse);
621
+ });
622
+
623
+ return response;
624
+ },
625
+
626
+ getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
627
+ const bidResponse = !isEmpty(serverResponses) && serverResponses[0].body;
628
+
629
+ if (bidResponse && bidResponse.ext && bidResponse.ext.pixels) {
630
+ return extractUserSyncUrls(syncOptions, bidResponse.ext.pixels);
631
+ }
632
+
633
+ return [];
634
+ }
635
+ };
636
+
637
+ registerBidder(spec);