prebid.js 7.2.0 → 7.5.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 (251) hide show
  1. package/.circleci/config.yml +11 -6
  2. package/.github/dependabot.yml +6 -0
  3. package/.github/workflows/issue_tracker.yml +5 -0
  4. package/.github/workflows/release-drafter.yml +6 -0
  5. package/README.md +35 -0
  6. package/dist/33acrossBidAdapter.js +1 -1
  7. package/dist/adagioBidAdapter.js +1 -1
  8. package/dist/adbookpspBidAdapter.js +1 -1
  9. package/dist/adgenerationBidAdapter.js +1 -1
  10. package/dist/adkernelBidAdapter.js +1 -1
  11. package/dist/adotBidAdapter.js +1 -1
  12. package/dist/adpod.js +1 -1
  13. package/dist/adqueryBidAdapter.js +1 -1
  14. package/dist/adrelevantisBidAdapter.js +1 -1
  15. package/dist/adxcgBidAdapter.js +1 -1
  16. package/dist/adyoulikeBidAdapter.js +1 -1
  17. package/dist/ajaBidAdapter.js +1 -1
  18. package/dist/amxBidAdapter.js +1 -1
  19. package/dist/amxIdSystem.js +1 -1
  20. package/dist/appierAnalyticsAdapter.js +1 -1
  21. package/dist/appnexusBidAdapter.js +1 -1
  22. package/dist/asoBidAdapter.js +1 -1
  23. package/dist/audiencerunBidAdapter.js +1 -1
  24. package/dist/axonixBidAdapter.js +1 -1
  25. package/dist/bidglassBidAdapter.js +1 -1
  26. package/dist/big-richmediaBidAdapter.js +1 -1
  27. package/dist/bluebillywigBidAdapter.js +1 -1
  28. package/dist/bridgewellBidAdapter.js +1 -1
  29. package/dist/brightMountainMediaBidAdapter.js +1 -1
  30. package/dist/concertBidAdapter.js +1 -1
  31. package/dist/connectadBidAdapter.js +1 -1
  32. package/dist/consumableBidAdapter.js +1 -1
  33. package/dist/conversantBidAdapter.js +1 -1
  34. package/dist/cpexIdSystem.js +1 -1
  35. package/dist/craftBidAdapter.js +1 -1
  36. package/dist/criteoBidAdapter.js +1 -1
  37. package/dist/debugging-standalone.js +1 -1
  38. package/dist/debugging.js +1 -1
  39. package/dist/dianomiBidAdapter.js +1 -0
  40. package/dist/dspxBidAdapter.js +1 -1
  41. package/dist/eplanningBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -0
  43. package/dist/fpdModule.js +1 -1
  44. package/dist/gdprEnforcement.js +1 -1
  45. package/dist/glimpseBidAdapter.js +1 -1
  46. package/dist/gmosspBidAdapter.js +1 -1
  47. package/dist/goldbachBidAdapter.js +1 -1
  48. package/dist/gridBidAdapter.js +1 -1
  49. package/dist/gridNMBidAdapter.js +1 -1
  50. package/dist/gumgumBidAdapter.js +1 -1
  51. package/dist/h12mediaBidAdapter.js +1 -1
  52. package/dist/hadronIdSystem.js +1 -1
  53. package/dist/hadronRtdProvider.js +1 -1
  54. package/dist/id5IdSystem.js +1 -1
  55. package/dist/impactifyBidAdapter.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/jixieBidAdapter.js +1 -1
  61. package/dist/justpremiumBidAdapter.js +1 -1
  62. package/dist/kargoAnalyticsAdapter.js +1 -1
  63. package/dist/kargoBidAdapter.js +1 -1
  64. package/dist/konduitAnalyticsAdapter.js +1 -1
  65. package/dist/kueezBidAdapter.js +1 -1
  66. package/dist/lassoBidAdapter.js +1 -0
  67. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  68. package/dist/logicadBidAdapter.js +1 -1
  69. package/dist/loglyliftBidAdapter.js +1 -1
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/mediakeysBidAdapter.js +1 -1
  74. package/dist/medianetBidAdapter.js +1 -1
  75. package/dist/mediasquareBidAdapter.js +1 -1
  76. package/dist/mgidBidAdapter.js +1 -1
  77. package/dist/minutemediaBidAdapter.js +1 -1
  78. package/dist/missenaBidAdapter.js +1 -1
  79. package/dist/nativoBidAdapter.js +1 -1
  80. package/dist/not-for-prod/prebid.js +137 -131
  81. package/dist/oguryBidAdapter.js +1 -1
  82. package/dist/onetagBidAdapter.js +1 -1
  83. package/dist/ooloAnalyticsAdapter.js +1 -1
  84. package/dist/openxOrtbBidAdapter.js +1 -0
  85. package/dist/outbrainBidAdapter.js +1 -1
  86. package/dist/parrableIdSystem.js +1 -1
  87. package/dist/pixfutureBidAdapter.js +1 -1
  88. package/dist/prebid-core.js +2 -2
  89. package/dist/pubCommonId.js +1 -1
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pxyzBidAdapter.js +1 -1
  94. package/dist/quantcastBidAdapter.js +1 -1
  95. package/dist/readpeakBidAdapter.js +1 -1
  96. package/dist/relaidoBidAdapter.js +1 -1
  97. package/dist/rhythmoneBidAdapter.js +1 -1
  98. package/dist/riseBidAdapter.js +1 -1
  99. package/dist/rubiconAnalyticsAdapter.js +1 -1
  100. package/dist/rubiconBidAdapter.js +1 -1
  101. package/dist/seedingAllianceBidAdapter.js +1 -1
  102. package/dist/seedtagBidAdapter.js +1 -1
  103. package/dist/sharedIdSystem.js +1 -1
  104. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  105. package/dist/sharethroughBidAdapter.js +1 -1
  106. package/dist/shinezBidAdapter.js +1 -0
  107. package/dist/sizeMappingV2.js +1 -1
  108. package/dist/smaatoBidAdapter.js +1 -1
  109. package/dist/smartadserverBidAdapter.js +1 -1
  110. package/dist/smartxBidAdapter.js +1 -1
  111. package/dist/smilewantedBidAdapter.js +1 -1
  112. package/dist/sonobiBidAdapter.js +1 -1
  113. package/dist/sovrnAnalyticsAdapter.js +1 -1
  114. package/dist/sovrnBidAdapter.js +1 -1
  115. package/dist/sspBCBidAdapter.js +1 -1
  116. package/dist/sublimeBidAdapter.js +1 -1
  117. package/dist/synacormediaBidAdapter.js +1 -1
  118. package/dist/taboolaBidAdapter.js +1 -1
  119. package/dist/targetVideoBidAdapter.js +1 -1
  120. package/dist/teadsBidAdapter.js +1 -1
  121. package/dist/tncIdSystem.js +1 -0
  122. package/dist/trionBidAdapter.js +1 -1
  123. package/dist/tripleliftBidAdapter.js +1 -1
  124. package/dist/ttdBidAdapter.js +1 -1
  125. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  126. package/dist/underdogmediaBidAdapter.js +1 -1
  127. package/dist/undertoneBidAdapter.js +1 -1
  128. package/dist/userId.js +1 -1
  129. package/dist/ventesBidAdapter.js +1 -1
  130. package/dist/vidazooBidAdapter.js +1 -1
  131. package/dist/videobyteBidAdapter.js +1 -1
  132. package/dist/visxBidAdapter.js +1 -1
  133. package/dist/vrtcalBidAdapter.js +1 -1
  134. package/dist/vuukleBidAdapter.js +1 -1
  135. package/dist/widespaceBidAdapter.js +1 -1
  136. package/dist/winrBidAdapter.js +1 -1
  137. package/dist/yahoosspBidAdapter.js +1 -1
  138. package/dist/yieldlabBidAdapter.js +1 -1
  139. package/dist/yieldmoBidAdapter.js +1 -1
  140. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  141. package/dist/yieldoneBidAdapter.js +1 -1
  142. package/governance.md +5 -11
  143. package/gulpHelpers.js +1 -1
  144. package/gulpfile.js +1 -1
  145. package/karma.conf.maker.js +3 -1
  146. package/modules/.submodules.json +1 -0
  147. package/modules/33acrossBidAdapter.js +5 -1
  148. package/modules/adkernelBidAdapter.js +2 -1
  149. package/modules/adotBidAdapter.js +3 -3
  150. package/modules/adqueryBidAdapter.js +5 -1
  151. package/modules/appnexusBidAdapter.js +3 -3
  152. package/modules/cpexIdSystem.js +7 -8
  153. package/modules/criteoBidAdapter.js +7 -1
  154. package/modules/cwireBidAdapter.md +1 -1
  155. package/modules/debugging/bidInterceptor.js +1 -1
  156. package/modules/debugging/index.js +2 -1
  157. package/modules/dianomiBidAdapter.js +369 -0
  158. package/modules/dianomiBidAdapter.md +73 -0
  159. package/modules/finativeBidAdapter.js +235 -0
  160. package/modules/finativeBidAdapter.md +45 -0
  161. package/modules/fpdModule/index.js +6 -5
  162. package/modules/gdprEnforcement.js +8 -14
  163. package/modules/gumgumBidAdapter.js +2 -0
  164. package/modules/gumgumBidAdapter.md +19 -1
  165. package/modules/hadronAnalyticsAdapter.md +5 -5
  166. package/modules/hadronIdSystem.js +18 -5
  167. package/modules/hadronIdSystem.md +15 -11
  168. package/modules/hadronRtdProvider.js +14 -1
  169. package/modules/hadronRtdProvider.md +17 -13
  170. package/modules/insticatorBidAdapter.js +9 -0
  171. package/modules/ixBidAdapter.js +457 -57
  172. package/modules/ixBidAdapter.md +95 -5
  173. package/modules/kargoAnalyticsAdapter.js +88 -6
  174. package/modules/kargoAnalyticsAdapter.md +33 -0
  175. package/modules/kargoBidAdapter.js +1 -2
  176. package/modules/lassoBidAdapter.js +133 -0
  177. package/modules/lassoBidAdapter.md +29 -0
  178. package/modules/medianetBidAdapter.js +9 -5
  179. package/modules/missenaBidAdapter.js +20 -2
  180. package/modules/nativoBidAdapter.js +19 -7
  181. package/modules/openxBidAdapter.md +3 -1
  182. package/modules/openxOrtbBidAdapter.js +349 -0
  183. package/modules/openxOrtbBidAdapter.md +105 -0
  184. package/modules/pubCommonId.js +1 -2
  185. package/modules/readpeakBidAdapter.js +15 -6
  186. package/modules/relaidoBidAdapter.js +19 -4
  187. package/modules/riseBidAdapter.js +1 -0
  188. package/modules/seedtagBidAdapter.js +33 -1
  189. package/modules/sharedIdSystem.js +11 -5
  190. package/modules/sharethroughBidAdapter.js +9 -24
  191. package/modules/shinezBidAdapter.js +435 -0
  192. package/modules/shinezBidAdapter.md +76 -0
  193. package/modules/sonobiBidAdapter.js +28 -9
  194. package/modules/sovrnBidAdapter.js +16 -10
  195. package/modules/taboolaBidAdapter.js +1 -1
  196. package/modules/taboolaBidAdapter.md +3 -3
  197. package/modules/tncIdSystem.js +63 -0
  198. package/modules/tncIdSystem.md +33 -0
  199. package/modules/userId/eids.js +12 -0
  200. package/modules/userId/eids.md +7 -0
  201. package/modules/userId/userId.md +17 -0
  202. package/modules/ventesBidAdapter.js +1 -1
  203. package/modules/ventesBidAdapter.md +1 -1
  204. package/modules/vrtcalBidAdapter.js +35 -0
  205. package/modules/yieldlabBidAdapter.js +4 -0
  206. package/modules/yieldmoBidAdapter.js +20 -2
  207. package/modules/yieldoneBidAdapter.js +12 -1
  208. package/package.json +1 -1
  209. package/plugins/pbjsGlobals.js +2 -1
  210. package/src/adloader.js +1 -0
  211. package/src/prebid.js +4 -1
  212. package/src/storageManager.js +4 -5
  213. package/test/spec/modules/33acrossBidAdapter_spec.js +39 -0
  214. package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
  215. package/test/spec/modules/cpexIdSystem_spec.js +5 -5
  216. package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
  217. package/test/spec/modules/debugging_mod_spec.js +7 -0
  218. package/test/spec/modules/dianomiBidAdapter_spec.js +1223 -0
  219. package/test/spec/modules/eids_spec.js +26 -1
  220. package/test/spec/modules/finativeBidAdapter_spec.js +186 -0
  221. package/test/spec/modules/fpdModule_spec.js +28 -1
  222. package/test/spec/modules/gdprEnforcement_spec.js +53 -100
  223. package/test/spec/modules/gumgumBidAdapter_spec.js +5 -0
  224. package/test/spec/modules/hadronIdSystem_spec.js +2 -2
  225. package/test/spec/modules/insticatorBidAdapter_spec.js +22 -1
  226. package/test/spec/modules/ixBidAdapter_spec.js +429 -10
  227. package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
  228. package/test/spec/modules/kargoBidAdapter_spec.js +1 -0
  229. package/test/spec/modules/lassoBidAdapter_spec.js +177 -0
  230. package/test/spec/modules/medianetBidAdapter_spec.js +24 -1
  231. package/test/spec/modules/missenaBidAdapter_spec.js +36 -14
  232. package/test/spec/modules/nativoBidAdapter_spec.js +67 -17
  233. package/test/spec/modules/openxOrtbBidAdapter_spec.js +1303 -0
  234. package/test/spec/modules/readpeakBidAdapter_spec.js +1 -0
  235. package/test/spec/modules/relaidoBidAdapter_spec.js +29 -2
  236. package/test/spec/modules/riseBidAdapter_spec.js +3 -0
  237. package/test/spec/modules/seedtagBidAdapter_spec.js +4 -0
  238. package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
  239. package/test/spec/modules/shinezBidAdapter_spec.js +479 -0
  240. package/test/spec/modules/sonobiBidAdapter_spec.js +38 -23
  241. package/test/spec/modules/sovrnBidAdapter_spec.js +39 -5
  242. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  243. package/test/spec/modules/tncIdSystem_spec.js +109 -0
  244. package/test/spec/modules/userId_spec.js +6 -3
  245. package/test/spec/modules/ventesBidAdapter_spec.js +2 -2
  246. package/test/spec/modules/vrtcalBidAdapter_spec.js +17 -0
  247. package/test/spec/modules/yieldlabBidAdapter_spec.js +4 -0
  248. package/test/spec/modules/yieldmoBidAdapter_spec.js +15 -2
  249. package/test/spec/modules/yieldoneBidAdapter_spec.js +43 -2
  250. package/test/spec/unit/pbjs_api_spec.js +23 -0
  251. package/webpack.conf.js +1 -1
@@ -4,7 +4,7 @@ import { config } from '../src/config.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
5
5
  import { createEidsArray } from './userId/eids.js';
6
6
 
7
- const VERSION = '4.1.0';
7
+ const VERSION = '4.1.1';
8
8
  const BIDDER_CODE = 'sharethrough';
9
9
  const SUPPLY_ID = 'WYu2BXv1';
10
10
 
@@ -34,9 +34,8 @@ export const sharethroughAdapterSpec = {
34
34
  cur: ['USD'],
35
35
  tmax: timeout,
36
36
  site: {
37
- // TODO: do the fallbacks make sense here?
38
- domain: deepAccess(bidderRequest, 'refererInfo.domain') || window.location.hostname,
39
- page: deepAccess(bidderRequest, 'refererInfo.page') || window.location.href,
37
+ domain: deepAccess(bidderRequest, 'refererInfo.domain', window.location.hostname),
38
+ page: deepAccess(bidderRequest, 'refererInfo.page', window.location.href),
40
39
  ref: deepAccess(bidderRequest, 'refererInfo.ref'),
41
40
  ...firstPartyData.site,
42
41
  },
@@ -66,7 +65,7 @@ export const sharethroughAdapterSpec = {
66
65
 
67
66
  req.user = nullish(firstPartyData.user, {});
68
67
  if (!req.user.ext) req.user.ext = {};
69
- req.user.ext.eids = userIdAsEids(bidRequests[0]);
68
+ req.user.ext.eids = createEidsArray(deepAccess(bidRequests[0], 'userId')) || [];
70
69
 
71
70
  if (bidderRequest.gdprConsent) {
72
71
  const gdprApplies = bidderRequest.gdprConsent.gdprApplies === true;
@@ -181,21 +180,12 @@ export const sharethroughAdapterSpec = {
181
180
  });
182
181
  },
183
182
 
184
- getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
185
- const syncParams = uspConsent ? `&us_privacy=${uspConsent}` : '';
186
- const syncs = [];
187
- const shouldCookieSync = syncOptions.pixelEnabled &&
188
- serverResponses.length > 0 &&
189
- serverResponses[0].body &&
190
- serverResponses[0].body.cookieSyncUrls;
191
-
192
- if (shouldCookieSync) {
193
- serverResponses[0].body.cookieSyncUrls.forEach(url => {
194
- syncs.push({ type: 'image', url: url + syncParams });
195
- });
196
- }
183
+ getUserSyncs: (syncOptions, serverResponses) => {
184
+ const shouldCookieSync = syncOptions.pixelEnabled && deepAccess(serverResponses, '0.body.cookieSyncUrls') !== undefined;
197
185
 
198
- return syncs;
186
+ return shouldCookieSync
187
+ ? serverResponses[0].body.cookieSyncUrls.map(url => ({ type: 'image', url: url }))
188
+ : [];
199
189
  },
200
190
 
201
191
  // Empty implementation for prebid core to be able to find it
@@ -244,11 +234,6 @@ function getBidRequestFloor(bid) {
244
234
  return floor !== null ? floor : bid.params.floor;
245
235
  }
246
236
 
247
- function userIdAsEids(bidRequest) {
248
- const eids = createEidsArray(deepAccess(bidRequest, 'userId')) || [];
249
- return eids;
250
- }
251
-
252
237
  function getProtocol() {
253
238
  return window.location.protocol;
254
239
  }
@@ -0,0 +1,435 @@
1
+ import { logWarn, logInfo, isArray, isFn, deepAccess, isEmpty, contains, timestamp, getBidIdParameter, triggerPixel, isInteger } from '../src/utils.js';
2
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
3
+ import {BANNER, VIDEO} from '../src/mediaTypes.js';
4
+ import {config} from '../src/config.js';
5
+
6
+ const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
7
+ const BIDDER_CODE = 'shinez';
8
+ const ADAPTER_VERSION = '1.0.0';
9
+ const TTL = 360;
10
+ const CURRENCY = 'USD';
11
+ const SELLER_ENDPOINT = 'https://hb.sweetgum.io/';
12
+ const MODES = {
13
+ PRODUCTION: 'hb-sz-multi',
14
+ TEST: 'hb-multi-sz-test'
15
+ }
16
+ const SUPPORTED_SYNC_METHODS = {
17
+ IFRAME: 'iframe',
18
+ PIXEL: 'pixel'
19
+ }
20
+
21
+ export const spec = {
22
+ code: BIDDER_CODE,
23
+ version: ADAPTER_VERSION,
24
+ supportedMediaTypes: SUPPORTED_AD_TYPES,
25
+ isBidRequestValid: function (bidRequest) {
26
+ if (!bidRequest.params) {
27
+ logWarn('no params have been set to Shinez adapter');
28
+ return false;
29
+ }
30
+
31
+ if (!bidRequest.params.org) {
32
+ logWarn('org is a mandatory param for Shinez adapter');
33
+ return false;
34
+ }
35
+
36
+ return true;
37
+ },
38
+ buildRequests: function (validBidRequests, bidderRequest) {
39
+ const combinedRequestsObject = {};
40
+
41
+ // use data from the first bid, to create the general params for all bids
42
+ const generalObject = validBidRequests[0];
43
+ const testMode = generalObject.params.testMode;
44
+
45
+ combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest);
46
+ combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest);
47
+
48
+ return {
49
+ method: 'POST',
50
+ url: getEndpoint(testMode),
51
+ data: combinedRequestsObject
52
+ }
53
+ },
54
+ interpretResponse: function ({body}) {
55
+ const bidResponses = [];
56
+
57
+ if (body.bids) {
58
+ body.bids.forEach(adUnit => {
59
+ const bidResponse = {
60
+ requestId: adUnit.requestId,
61
+ cpm: adUnit.cpm,
62
+ currency: adUnit.currency || CURRENCY,
63
+ width: adUnit.width,
64
+ height: adUnit.height,
65
+ ttl: adUnit.ttl || TTL,
66
+ creativeId: adUnit.requestId,
67
+ netRevenue: adUnit.netRevenue || true,
68
+ nurl: adUnit.nurl,
69
+ mediaType: adUnit.mediaType,
70
+ meta: {
71
+ mediaType: adUnit.mediaType
72
+ }
73
+ };
74
+
75
+ if (adUnit.mediaType === VIDEO) {
76
+ bidResponse.vastXml = adUnit.vastXml;
77
+ } else if (adUnit.mediaType === BANNER) {
78
+ bidResponse.ad = adUnit.ad;
79
+ }
80
+
81
+ if (adUnit.adomain && adUnit.adomain.length) {
82
+ bidResponse.meta.advertiserDomains = adUnit.adomain;
83
+ }
84
+
85
+ bidResponses.push(bidResponse);
86
+ });
87
+ }
88
+
89
+ return bidResponses;
90
+ },
91
+ getUserSyncs: function (syncOptions, serverResponses) {
92
+ const syncs = [];
93
+ for (const response of serverResponses) {
94
+ if (syncOptions.iframeEnabled && response.body.params.userSyncURL) {
95
+ syncs.push({
96
+ type: 'iframe',
97
+ url: response.body.params.userSyncURL
98
+ });
99
+ }
100
+ if (syncOptions.pixelEnabled && isArray(response.body.params.userSyncPixels)) {
101
+ const pixels = response.body.params.userSyncPixels.map(pixel => {
102
+ return {
103
+ type: 'image',
104
+ url: pixel
105
+ }
106
+ })
107
+ syncs.push(...pixels)
108
+ }
109
+ }
110
+ return syncs;
111
+ },
112
+ onBidWon: function (bid) {
113
+ if (bid == null) {
114
+ return;
115
+ }
116
+
117
+ logInfo('onBidWon:', bid);
118
+ if (bid.hasOwnProperty('nurl') && bid.nurl.length > 0) {
119
+ triggerPixel(bid.nurl);
120
+ }
121
+ }
122
+ };
123
+
124
+ registerBidder(spec);
125
+
126
+ /**
127
+ * Get floor price
128
+ * @param bid {bid}
129
+ * @returns {Number}
130
+ */
131
+ function getFloor(bid, mediaType) {
132
+ if (!isFn(bid.getFloor)) {
133
+ return 0;
134
+ }
135
+ let floorResult = bid.getFloor({
136
+ currency: CURRENCY,
137
+ mediaType: mediaType,
138
+ size: '*'
139
+ });
140
+ return floorResult.currency === CURRENCY && floorResult.floor ? floorResult.floor : 0;
141
+ }
142
+
143
+ /**
144
+ * Get the the ad sizes array from the bid
145
+ * @param bid {bid}
146
+ * @returns {Array}
147
+ */
148
+ function getSizesArray(bid, mediaType) {
149
+ let sizesArray = []
150
+
151
+ if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) {
152
+ sizesArray = bid.mediaTypes[mediaType].sizes;
153
+ } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
154
+ sizesArray = bid.sizes;
155
+ }
156
+
157
+ return sizesArray;
158
+ }
159
+
160
+ /**
161
+ * Get schain string value
162
+ * @param schainObject {Object}
163
+ * @returns {string}
164
+ */
165
+ function getSupplyChain(schainObject) {
166
+ if (isEmpty(schainObject)) {
167
+ return '';
168
+ }
169
+ let scStr = `${schainObject.ver},${schainObject.complete}`;
170
+ schainObject.nodes.forEach((node) => {
171
+ scStr += '!';
172
+ scStr += `${getEncodedValIfNotEmpty(node.asi)},`;
173
+ scStr += `${getEncodedValIfNotEmpty(node.sid)},`;
174
+ scStr += `${node.hp ? encodeURIComponent(node.hp) : ''},`;
175
+ scStr += `${getEncodedValIfNotEmpty(node.rid)},`;
176
+ scStr += `${getEncodedValIfNotEmpty(node.name)},`;
177
+ scStr += `${getEncodedValIfNotEmpty(node.domain)}`;
178
+ });
179
+ return scStr;
180
+ }
181
+
182
+ /**
183
+ * Get encoded node value
184
+ * @param val {string}
185
+ * @returns {string}
186
+ */
187
+ function getEncodedValIfNotEmpty(val) {
188
+ return !isEmpty(val) ? encodeURIComponent(val) : '';
189
+ }
190
+
191
+ /**
192
+ * Get preferred user-sync method based on publisher configuration
193
+ * @param bidderCode {string}
194
+ * @returns {string}
195
+ */
196
+ function getAllowedSyncMethod(filterSettings, bidderCode) {
197
+ const iframeConfigsToCheck = ['all', 'iframe'];
198
+ const pixelConfigToCheck = 'image';
199
+ if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) {
200
+ return SUPPORTED_SYNC_METHODS.IFRAME;
201
+ }
202
+ if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) {
203
+ return SUPPORTED_SYNC_METHODS.PIXEL;
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Check if sync rule is supported
209
+ * @param syncRule {Object}
210
+ * @param bidderCode {string}
211
+ * @returns {boolean}
212
+ */
213
+ function isSyncMethodAllowed(syncRule, bidderCode) {
214
+ if (!syncRule) {
215
+ return false;
216
+ }
217
+ const isInclude = syncRule.filter === 'include';
218
+ const bidders = isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode];
219
+ return isInclude && contains(bidders, bidderCode);
220
+ }
221
+
222
+ /**
223
+ * Get the seller endpoint
224
+ * @param testMode {boolean}
225
+ * @returns {string}
226
+ */
227
+ function getEndpoint(testMode) {
228
+ return testMode
229
+ ? SELLER_ENDPOINT + MODES.TEST
230
+ : SELLER_ENDPOINT + MODES.PRODUCTION;
231
+ }
232
+
233
+ /**
234
+ * get device type
235
+ * @param uad {ua}
236
+ * @returns {string}
237
+ */
238
+ function getDeviceType(ua) {
239
+ if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i
240
+ .test(ua.toLowerCase())) {
241
+ return '5';
242
+ }
243
+ if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i
244
+ .test(ua.toLowerCase())) {
245
+ return '4';
246
+ }
247
+ if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i
248
+ .test(ua.toLowerCase())) {
249
+ return '3';
250
+ }
251
+ return '1';
252
+ }
253
+
254
+ function generateBidsParams(validBidRequests, bidderRequest) {
255
+ const bidsArray = [];
256
+
257
+ if (validBidRequests.length) {
258
+ validBidRequests.forEach(bid => {
259
+ bidsArray.push(generateBidParameters(bid, bidderRequest));
260
+ });
261
+ }
262
+
263
+ return bidsArray;
264
+ }
265
+
266
+ /**
267
+ * Generate bid specific parameters
268
+ * @param {bid} bid
269
+ * @param {bidderRequest} bidderRequest
270
+ * @returns {Object} bid specific params object
271
+ */
272
+ function generateBidParameters(bid, bidderRequest) {
273
+ const {params} = bid;
274
+ const mediaType = isBanner(bid) ? BANNER : VIDEO;
275
+ const sizesArray = getSizesArray(bid, mediaType);
276
+
277
+ // fix floor price in case of NAN
278
+ if (isNaN(params.floorPrice)) {
279
+ params.floorPrice = 0;
280
+ }
281
+
282
+ const bidObject = {
283
+ mediaType,
284
+ adUnitCode: getBidIdParameter('adUnitCode', bid),
285
+ sizes: sizesArray,
286
+ floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice),
287
+ bidId: getBidIdParameter('bidId', bid),
288
+ bidderRequestId: getBidIdParameter('bidderRequestId', bid),
289
+ transactionId: getBidIdParameter('transactionId', bid),
290
+ };
291
+
292
+ const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
293
+ if (pos) {
294
+ bidObject.pos = pos;
295
+ }
296
+
297
+ const gpid = deepAccess(bid, `ortb2Imp.ext.gpid`);
298
+ if (gpid) {
299
+ bidObject.gpid = gpid;
300
+ }
301
+
302
+ const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`);
303
+ if (placementId) {
304
+ bidObject.placementId = placementId;
305
+ }
306
+
307
+ if (mediaType === VIDEO) {
308
+ const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`);
309
+ let playbackMethodValue;
310
+
311
+ // verify playbackMethod is of type integer array, or integer only.
312
+ if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) {
313
+ // only the first playbackMethod in the array will be used, according to OpenRTB 2.5 recommendation
314
+ playbackMethodValue = playbackMethod[0];
315
+ } else if (isInteger(playbackMethod)) {
316
+ playbackMethodValue = playbackMethod;
317
+ }
318
+
319
+ if (playbackMethodValue) {
320
+ bidObject.playbackMethod = playbackMethodValue;
321
+ }
322
+
323
+ const placement = deepAccess(bid, `mediaTypes.video.placement`);
324
+ if (placement) {
325
+ bidObject.placement = placement;
326
+ }
327
+
328
+ const minDuration = deepAccess(bid, `mediaTypes.video.minduration`);
329
+ if (minDuration) {
330
+ bidObject.minDuration = minDuration;
331
+ }
332
+
333
+ const maxDuration = deepAccess(bid, `mediaTypes.video.maxduration`);
334
+ if (maxDuration) {
335
+ bidObject.maxDuration = maxDuration;
336
+ }
337
+
338
+ const skip = deepAccess(bid, `mediaTypes.video.skip`);
339
+ if (skip) {
340
+ bidObject.skip = skip;
341
+ }
342
+
343
+ const linearity = deepAccess(bid, `mediaTypes.video.linearity`);
344
+ if (linearity) {
345
+ bidObject.linearity = linearity;
346
+ }
347
+ }
348
+
349
+ return bidObject;
350
+ }
351
+
352
+ function isBanner(bid) {
353
+ return bid.mediaTypes && bid.mediaTypes.banner;
354
+ }
355
+
356
+ /**
357
+ * Generate params that are common between all bids
358
+ * @param {single bid object} generalObject
359
+ * @param {bidderRequest} bidderRequest
360
+ * @returns {object} the common params object
361
+ */
362
+ function generateGeneralParams(generalObject, bidderRequest) {
363
+ const domain = window.location.hostname;
364
+ const {syncEnabled, filterSettings} = config.getConfig('userSync') || {};
365
+ const {bidderCode} = bidderRequest;
366
+ const generalBidParams = generalObject.params;
367
+ const timeout = config.getConfig('bidderTimeout');
368
+
369
+ // these params are snake_case instead of camelCase to allow backwards compatability on the server.
370
+ // in the future, these will be converted to camelCase to match our convention.
371
+ const generalParams = {
372
+ wrapper_type: 'prebidjs',
373
+ wrapper_vendor: '$$PREBID_GLOBAL$$',
374
+ wrapper_version: '$prebid.version$',
375
+ adapter_version: ADAPTER_VERSION,
376
+ auction_start: timestamp(),
377
+ publisher_id: generalBidParams.org,
378
+ publisher_name: domain,
379
+ site_domain: domain,
380
+ dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0,
381
+ device_type: getDeviceType(navigator.userAgent),
382
+ ua: navigator.userAgent,
383
+ session_id: getBidIdParameter('auctionId', generalObject),
384
+ tmax: timeout
385
+ }
386
+
387
+ const userIdsParam = getBidIdParameter('userId', generalObject);
388
+ if (userIdsParam) {
389
+ generalParams.userIds = JSON.stringify(userIdsParam);
390
+ }
391
+
392
+ const ortb2Metadata = bidderRequest.ortb2 || {};
393
+ if (ortb2Metadata.site) {
394
+ generalParams.site_metadata = JSON.stringify(ortb2Metadata.site);
395
+ }
396
+ if (ortb2Metadata.user) {
397
+ generalParams.user_metadata = JSON.stringify(ortb2Metadata.user);
398
+ }
399
+
400
+ if (syncEnabled) {
401
+ const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode);
402
+ if (allowedSyncMethod) {
403
+ generalParams.cs_method = allowedSyncMethod;
404
+ }
405
+ }
406
+
407
+ if (bidderRequest.uspConsent) {
408
+ generalParams.us_privacy = bidderRequest.uspConsent;
409
+ }
410
+
411
+ if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) {
412
+ generalParams.gdpr = bidderRequest.gdprConsent.gdprApplies;
413
+ generalParams.gdpr_consent = bidderRequest.gdprConsent.consentString;
414
+ }
415
+
416
+ if (generalBidParams.ifa) {
417
+ generalParams.ifa = generalBidParams.ifa;
418
+ }
419
+
420
+ if (generalObject.schain) {
421
+ generalParams.schain = getSupplyChain(generalObject.schain);
422
+ }
423
+
424
+ if (bidderRequest.ortb2 && bidderRequest.ortb2.site) {
425
+ generalParams.referrer = bidderRequest.ortb2.site.ref;
426
+ generalParams.page_url = bidderRequest.ortb2.site.page;
427
+ }
428
+
429
+ if (bidderRequest && bidderRequest.refererInfo) {
430
+ generalParams.referrer = generalParams.referrer || deepAccess(bidderRequest, 'refererInfo.referer');
431
+ generalParams.page_url = generalParams.page_url || config.getConfig('pageUrl') || deepAccess(window, 'location.href');
432
+ }
433
+
434
+ return generalParams
435
+ }
@@ -0,0 +1,76 @@
1
+ #Overview
2
+
3
+ Module Name: Shinez Bidder Adapter
4
+
5
+ Module Type: Bidder Adapter
6
+
7
+ Maintainer: tech-team@shinez.io
8
+
9
+
10
+ # Description
11
+
12
+ Module that connects to Shinez's demand sources.
13
+
14
+ The Shinez adapter requires setup and approval from the Shinez. Please reach out to tech-team@shinez.io to create an Shinez account.
15
+
16
+ The adapter supports Video(instream) & Banner.
17
+
18
+ # Bid Parameters
19
+ ## Video
20
+
21
+ | Name | Scope | Type | Description | Example
22
+ | ---- | ----- | ---- | ----------- | -------
23
+ | `org` | required | String | Shinez publisher Id provided by your Shinez representative | "56f91cd4d3e3660002000033"
24
+ | `floorPrice` | optional | Number | Minimum price in USD. Misuse of this parameter can impact revenue | 2.00
25
+ | `placementId` | optional | String | A unique placement identifier | "12345678"
26
+ | `testMode` | optional | Boolean | This activates the test mode | false
27
+
28
+ # Test Parameters
29
+ ```javascript
30
+ var adUnits = [{
31
+ code: 'dfp-video-div',
32
+ sizes: [
33
+ [640, 480]
34
+ ],
35
+ mediaTypes: {
36
+ video: {
37
+ playerSize: [
38
+ [640, 480]
39
+ ],
40
+ context: 'instream'
41
+ }
42
+ },
43
+ bids: [{
44
+ bidder: 'shinez',
45
+ params: {
46
+ org: '56f91cd4d3e3660002000033', // Required
47
+ floorPrice: 2.00, // Optional
48
+ placementId: 'shinez-video-test', // Optional
49
+ testMode: true // Optional
50
+ }
51
+ }]
52
+ },
53
+ {
54
+ code: 'dfp-banner-div',
55
+ sizes: [
56
+ [640, 480]
57
+ ],
58
+ mediaTypes: {
59
+ banner: {
60
+ sizes: [
61
+ [640, 480]
62
+ ]
63
+ }
64
+ },
65
+ bids: [{
66
+ bidder: 'shinez',
67
+ params: {
68
+ org: '56f91cd4d3e3660002000033', // Required
69
+ floorPrice: 2.00, // Optional
70
+ placementId: 'shinez-banner-test', // Optional
71
+ testMode: true // Optional
72
+ }
73
+ }]
74
+ }
75
+ ];
76
+ ```
@@ -56,15 +56,23 @@ export const spec = {
56
56
  */
57
57
  buildRequests: (validBidRequests, bidderRequest) => {
58
58
  const bids = validBidRequests.map(bid => {
59
+ let mediaType;
60
+
61
+ if (deepAccess(bid, 'mediaTypes.video')) {
62
+ mediaType = 'video';
63
+ } else if (deepAccess(bid, 'mediaTypes.banner')) {
64
+ mediaType = 'display';
65
+ }
66
+
59
67
  let slotIdentifier = _validateSlot(bid);
60
68
  if (/^[\/]?[\d]+[[\/].+[\/]?]?$/.test(slotIdentifier)) {
61
69
  slotIdentifier = slotIdentifier.charAt(0) === '/' ? slotIdentifier : '/' + slotIdentifier;
62
70
  return {
63
- [`${slotIdentifier}|${bid.bidId}`]: `${_validateSize(bid)}${_validateFloor(bid)}${_validateGPID(bid)}`
71
+ [`${slotIdentifier}|${bid.bidId}`]: `${_validateSize(bid)}|${_validateFloor(bid)}${_validateGPID(bid)}${_validateMediaType(mediaType)}`
64
72
  }
65
73
  } else if (/^[0-9a-fA-F]{20}$/.test(slotIdentifier) && slotIdentifier.length === 20) {
66
74
  return {
67
- [bid.bidId]: `${slotIdentifier}|${_validateSize(bid)}${_validateFloor(bid)}${_validateGPID(bid)}`
75
+ [bid.bidId]: `${slotIdentifier}|${_validateSize(bid)}|${_validateFloor(bid)}${_validateGPID(bid)}${_validateMediaType(mediaType)}`
68
76
  }
69
77
  } else {
70
78
  logError(`The ad unit code or Sonobi Placement id for slot ${bid.bidId} is invalid`);
@@ -273,7 +281,7 @@ export const spec = {
273
281
  });
274
282
  });
275
283
  }
276
- } catch (e) {}
284
+ } catch (e) { }
277
285
  return syncs;
278
286
  }
279
287
  };
@@ -286,7 +294,7 @@ function _findBidderRequest(bidderRequests, bidId) {
286
294
  }
287
295
  }
288
296
 
289
- function _validateSize (bid) {
297
+ function _validateSize(bid) {
290
298
  if (deepAccess(bid, 'mediaTypes.video')) {
291
299
  return ''; // Video bids arent allowed to override sizes via the trinity request
292
300
  }
@@ -304,18 +312,18 @@ function _validateSize (bid) {
304
312
  }
305
313
  }
306
314
 
307
- function _validateSlot (bid) {
315
+ function _validateSlot(bid) {
308
316
  if (bid.params.ad_unit) {
309
317
  return bid.params.ad_unit;
310
318
  }
311
319
  return bid.params.placement_id;
312
320
  }
313
321
 
314
- function _validateFloor (bid) {
322
+ function _validateFloor(bid) {
315
323
  const floor = getBidFloor(bid);
316
324
 
317
325
  if (floor) {
318
- return `|f=${floor}`;
326
+ return `f=${floor},`;
319
327
  }
320
328
  return '';
321
329
  }
@@ -324,11 +332,22 @@ function _validateGPID(bid) {
324
332
  const gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot') || deepAccess(getGptSlotInfoForAdUnitCode(bid.adUnitCode), 'gptSlot') || bid.params.ad_unit;
325
333
 
326
334
  if (gpid) {
327
- return `|gpid=${gpid}`
335
+ return `gpid=${gpid},`
328
336
  }
329
337
  return ''
330
338
  }
331
339
 
340
+ function _validateMediaType(mediaType) {
341
+ let mediaTypeValidation = '';
342
+ if (mediaType === 'video') {
343
+ mediaTypeValidation = 'c=v,';
344
+ } else if (mediaType === 'display') {
345
+ mediaTypeValidation = 'c=d,';
346
+ }
347
+
348
+ return mediaTypeValidation;
349
+ }
350
+
332
351
  const _creative = (mediaType, referer) => (sbiDc, sbiAid) => {
333
352
  if (mediaType === 'video' || mediaType === 'outstream') {
334
353
  return _videoCreative(sbiDc, sbiAid, referer)
@@ -341,7 +360,7 @@ function _videoCreative(sbiDc, sbiAid, referer) {
341
360
  return `https://${sbiDc}apex.go.sonobi.com/vast.xml?vid=${sbiAid}&ref=${encodeURIComponent(referer)}`
342
361
  }
343
362
 
344
- function _getBidIdFromTrinityKey (key) {
363
+ function _getBidIdFromTrinityKey(key) {
345
364
  return key.split('|').slice(-1)[0]
346
365
  }
347
366