prebid.js 7.22.0 → 7.24.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 (314) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/aaxBlockmeterRtdProvider.js +1 -0
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/admaticBidAdapter.js +1 -0
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/adyoulikeBidAdapter.js +1 -1
  11. package/dist/ajaBidAdapter.js +1 -1
  12. package/dist/amxBidAdapter.js +1 -1
  13. package/dist/amxIdSystem.js +1 -1
  14. package/dist/analyticsAdapter.js +1 -1
  15. package/dist/appierAnalyticsAdapter.js +1 -1
  16. package/dist/appnexusBidAdapter.js +1 -1
  17. package/dist/asoBidAdapter.js +1 -1
  18. package/dist/audiencerunBidAdapter.js +1 -1
  19. package/dist/axonixBidAdapter.js +1 -1
  20. package/dist/bidViewability.js +1 -1
  21. package/dist/bidViewabilityIO.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bluebillywigBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/browsiRtdProvider.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -0
  30. package/dist/cleanioRtdProvider.js +1 -1
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectIdSystem.js +1 -1
  33. package/dist/connectadBidAdapter.js +1 -1
  34. package/dist/consentManagement.js +1 -1
  35. package/dist/consentManagementUsp.js +1 -1
  36. package/dist/consumableBidAdapter.js +1 -1
  37. package/dist/conversantBidAdapter.js +1 -1
  38. package/dist/craftBidAdapter.js +1 -1
  39. package/dist/criteoBidAdapter.js +1 -1
  40. package/dist/currency.js +1 -1
  41. package/dist/dependencies.json +19 -0
  42. package/dist/dfpAdServerVideo.js +1 -1
  43. package/dist/dgkeywordRtdProvider.js +1 -1
  44. package/dist/dspxBidAdapter.js +1 -1
  45. package/dist/eplanningBidAdapter.js +1 -1
  46. package/dist/finativeBidAdapter.js +1 -1
  47. package/dist/gdprEnforcement.js +1 -1
  48. package/dist/glimpseBidAdapter.js +1 -1
  49. package/dist/gmosspBidAdapter.js +1 -1
  50. package/dist/goldbachBidAdapter.js +1 -1
  51. package/dist/googleAnalyticsAdapter.js +1 -1
  52. package/dist/gridBidAdapter.js +1 -1
  53. package/dist/gridNMBidAdapter.js +1 -1
  54. package/dist/growthCodeIdSystem.js +1 -1
  55. package/dist/gumgumBidAdapter.js +1 -1
  56. package/dist/h12mediaBidAdapter.js +1 -1
  57. package/dist/id5AnalyticsAdapter.js +1 -1
  58. package/dist/id5IdSystem.js +1 -1
  59. package/dist/impactifyBidAdapter.js +1 -1
  60. package/dist/improvedigitalBidAdapter.js +1 -1
  61. package/dist/inmarBidAdapter.js +1 -1
  62. package/dist/insticatorBidAdapter.js +1 -1
  63. package/dist/instreamTracking.js +1 -1
  64. package/dist/ixBidAdapter.js +1 -1
  65. package/dist/jixieBidAdapter.js +1 -1
  66. package/dist/justpremiumBidAdapter.js +1 -1
  67. package/dist/jwplayerVideoProvider.js +1 -0
  68. package/dist/kargoBidAdapter.js +1 -1
  69. package/dist/konduitAnalyticsAdapter.js +1 -1
  70. package/dist/kueezBidAdapter.js +1 -1
  71. package/dist/kueezRtbBidAdapter.js +1 -0
  72. package/dist/lassoBidAdapter.js +1 -1
  73. package/dist/lifestreetBidAdapter.js +1 -1
  74. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  75. package/dist/logicadBidAdapter.js +1 -1
  76. package/dist/loglyliftBidAdapter.js +1 -1
  77. package/dist/magniteAnalyticsAdapter.js +1 -1
  78. package/dist/malltvAnalyticsAdapter.js +1 -1
  79. package/dist/marsmediaBidAdapter.js +1 -1
  80. package/dist/mediafuseBidAdapter.js +1 -1
  81. package/dist/mediakeysBidAdapter.js +1 -1
  82. package/dist/mediasquareBidAdapter.js +1 -1
  83. package/dist/mgidBidAdapter.js +1 -1
  84. package/dist/mgidRtdProvider.js +1 -0
  85. package/dist/minutemediaBidAdapter.js +1 -1
  86. package/dist/multibid.js +1 -1
  87. package/dist/not-for-prod/prebid.js +153 -141
  88. package/dist/oguryBidAdapter.js +1 -1
  89. package/dist/onetagBidAdapter.js +1 -1
  90. package/dist/ooloAnalyticsAdapter.js +1 -1
  91. package/dist/openxOrtbBidAdapter.js +1 -1
  92. package/dist/ortbConverter.js +1 -0
  93. package/dist/outbrainBidAdapter.js +1 -1
  94. package/dist/oxxionRtdProvider.js +1 -0
  95. package/dist/parrableIdSystem.js +1 -1
  96. package/dist/pbsExtensions.js +1 -0
  97. package/dist/permutiveRtdProvider.js +1 -1
  98. package/dist/pixfutureBidAdapter.js +1 -1
  99. package/dist/prebid-core.js +1 -1
  100. package/dist/prebidServerBidAdapter.js +1 -1
  101. package/dist/priceFloors.js +1 -1
  102. package/dist/pubCommonId.js +1 -1
  103. package/dist/publinkIdSystem.js +1 -1
  104. package/dist/pubmaticBidAdapter.js +1 -1
  105. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  106. package/dist/pxyzBidAdapter.js +1 -1
  107. package/dist/quantcastBidAdapter.js +1 -1
  108. package/dist/readpeakBidAdapter.js +1 -1
  109. package/dist/relaidoBidAdapter.js +1 -1
  110. package/dist/rhythmoneBidAdapter.js +1 -1
  111. package/dist/riseBidAdapter.js +1 -1
  112. package/dist/rtdModule.js +1 -1
  113. package/dist/rubiconAnalyticsAdapter.js +1 -1
  114. package/dist/rubiconBidAdapter.js +1 -1
  115. package/dist/schain.js +1 -1
  116. package/dist/seedingAllianceBidAdapter.js +1 -1
  117. package/dist/seedtagBidAdapter.js +1 -1
  118. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  119. package/dist/sharethroughBidAdapter.js +1 -1
  120. package/dist/shinezBidAdapter.js +1 -1
  121. package/dist/smaatoBidAdapter.js +1 -1
  122. package/dist/smartadserverBidAdapter.js +1 -1
  123. package/dist/smartxBidAdapter.js +1 -1
  124. package/dist/smilewantedBidAdapter.js +1 -1
  125. package/dist/sonobiBidAdapter.js +1 -1
  126. package/dist/sovrnAnalyticsAdapter.js +1 -1
  127. package/dist/sovrnBidAdapter.js +1 -1
  128. package/dist/spotxBidAdapter.js +1 -1
  129. package/dist/sspBCBidAdapter.js +1 -1
  130. package/dist/sublimeBidAdapter.js +1 -1
  131. package/dist/synacormediaBidAdapter.js +1 -1
  132. package/dist/targetVideoBidAdapter.js +1 -1
  133. package/dist/teadsBidAdapter.js +1 -1
  134. package/dist/teadsIdSystem.js +1 -1
  135. package/dist/trionBidAdapter.js +1 -1
  136. package/dist/tripleliftBidAdapter.js +1 -1
  137. package/dist/ttdBidAdapter.js +1 -1
  138. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  139. package/dist/underdogmediaBidAdapter.js +1 -1
  140. package/dist/undertoneBidAdapter.js +1 -1
  141. package/dist/userId.js +1 -1
  142. package/dist/vidazooBidAdapter.js +1 -1
  143. package/dist/video.js +1 -0
  144. package/dist/videoModule.js +1 -0
  145. package/dist/videobyteBidAdapter.js +1 -1
  146. package/dist/videojsVideoProvider.js +1 -0
  147. package/dist/visxBidAdapter.js +1 -1
  148. package/dist/vuukleBidAdapter.js +1 -1
  149. package/dist/widespaceBidAdapter.js +1 -1
  150. package/dist/winrBidAdapter.js +1 -1
  151. package/dist/yahoosspBidAdapter.js +1 -1
  152. package/dist/yieldmoBidAdapter.js +1 -1
  153. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  154. package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
  155. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +98 -0
  156. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +89 -0
  157. package/integrationExamples/videoModule/jwplayer/eventListeners.html +244 -0
  158. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +122 -0
  159. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +80 -0
  160. package/integrationExamples/videoModule/jwplayer/playlist.html +122 -0
  161. package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +126 -0
  162. package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +132 -0
  163. package/integrationExamples/videoModule/videojs/eventListeners.html +238 -0
  164. package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +138 -0
  165. package/integrationExamples/videoModule/videojs/mediaMetadata.html +103 -0
  166. package/integrationExamples/videoModule/videojs/playlist.html +151 -0
  167. package/libraries/ortbConverter/README.md +378 -0
  168. package/libraries/ortbConverter/converter.js +135 -0
  169. package/libraries/ortbConverter/lib/composer.js +43 -0
  170. package/libraries/ortbConverter/lib/mergeProcessors.js +9 -0
  171. package/libraries/ortbConverter/lib/sizes.js +14 -0
  172. package/libraries/ortbConverter/processors/banner.js +40 -0
  173. package/libraries/ortbConverter/processors/default.js +167 -0
  174. package/libraries/ortbConverter/processors/mediaType.js +21 -0
  175. package/libraries/ortbConverter/processors/native.js +37 -0
  176. package/libraries/ortbConverter/processors/video.js +66 -0
  177. package/libraries/pbsExtensions/pbsExtensions.js +12 -0
  178. package/libraries/pbsExtensions/processors/aliases.js +17 -0
  179. package/libraries/pbsExtensions/processors/mediaType.js +23 -0
  180. package/libraries/pbsExtensions/processors/params.js +22 -0
  181. package/libraries/pbsExtensions/processors/pbs.js +99 -0
  182. package/libraries/pbsExtensions/processors/requestExtPrebid.js +30 -0
  183. package/libraries/pbsExtensions/processors/video.js +23 -0
  184. package/libraries/video/constants/enums.js +5 -0
  185. package/libraries/video/constants/events.js +97 -0
  186. package/libraries/video/constants/ortb.js +169 -0
  187. package/libraries/video/constants/vendorCodes.js +6 -0
  188. package/libraries/video/shared/eventHandler.js +18 -0
  189. package/libraries/video/shared/parentModule.js +82 -0
  190. package/libraries/video/shared/state.js +47 -0
  191. package/libraries/video/shared/vastXmlBuilder.js +77 -0
  192. package/libraries/video/shared/vastXmlEditor.js +115 -0
  193. package/modules/.submodules.json +7 -1
  194. package/modules/aaxBlockmeterRtdProvider.js +59 -0
  195. package/modules/aaxBlockmeterRtdProvider.md +48 -0
  196. package/modules/admaticBidAdapter.js +147 -0
  197. package/modules/admaticBidAdapter.md +48 -0
  198. package/modules/amxBidAdapter.js +1 -0
  199. package/modules/appnexusBidAdapter.js +38 -1
  200. package/modules/chtnwBidAdapter.js +110 -0
  201. package/modules/chtnwBidAdapter.md +31 -0
  202. package/modules/concertBidAdapter.js +44 -2
  203. package/modules/connectIdSystem.js +36 -23
  204. package/modules/connectIdSystem.md +3 -2
  205. package/modules/consentManagement.js +22 -1
  206. package/modules/consentManagementUsp.js +29 -7
  207. package/modules/criteoBidAdapter.js +25 -5
  208. package/modules/currency.js +9 -0
  209. package/modules/dgkeywordRtdProvider.js +3 -3
  210. package/modules/gridNMBidAdapter.js +10 -14
  211. package/modules/growthCodeIdSystem.js +9 -5
  212. package/modules/gumgumBidAdapter.js +4 -0
  213. package/modules/improvedigitalBidAdapter.js +191 -470
  214. package/modules/ixBidAdapter.js +54 -71
  215. package/modules/jwplayerVideoProvider.js +929 -0
  216. package/modules/jwplayerVideoProvider.md +25 -0
  217. package/modules/kargoBidAdapter.js +1 -1
  218. package/modules/kueezRtbBidAdapter.js +278 -0
  219. package/modules/kueezRtbBidAdapter.md +35 -0
  220. package/modules/magniteAnalyticsAdapter.js +6 -1
  221. package/modules/mgidRtdProvider.js +190 -0
  222. package/modules/mgidRtdProvider.md +51 -0
  223. package/modules/multibid/index.js +12 -0
  224. package/modules/openxOrtbBidAdapter.js +120 -275
  225. package/modules/oxxionRtdProvider.js +119 -0
  226. package/modules/oxxionRtdProvider.md +48 -0
  227. package/modules/permutiveRtdProvider.js +2 -1
  228. package/modules/permutiveRtdProvider.md +36 -1
  229. package/modules/prebidServerBidAdapter/index.js +19 -716
  230. package/modules/prebidServerBidAdapter/ortbConverter.js +274 -0
  231. package/modules/priceFloors.js +73 -1
  232. package/modules/pubmaticBidAdapter.js +21 -29
  233. package/modules/rtdModule/index.js +22 -1
  234. package/modules/schain.js +24 -1
  235. package/modules/spotxBidAdapter.js +16 -15
  236. package/modules/synacormediaBidAdapter.js +1 -1
  237. package/modules/teadsIdSystem.js +5 -0
  238. package/modules/tripleliftBidAdapter.js +1 -1
  239. package/modules/userId/eids.js +3 -10
  240. package/modules/userId/index.js +64 -6
  241. package/modules/videoModule/addingSubmodule.md +521 -0
  242. package/modules/videoModule/coreVideo.js +234 -0
  243. package/modules/videoModule/gamAdServerSubmodule.js +27 -0
  244. package/modules/videoModule/index.js +244 -0
  245. package/modules/videoModule/videoImpressionVerifier.js +206 -0
  246. package/modules/videojsVideoProvider.js +854 -0
  247. package/modules/videojsVideoProvider.md +17 -0
  248. package/package.json +12 -8
  249. package/src/adRendering.js +1 -1
  250. package/src/adapterManager.js +56 -7
  251. package/src/adloader.js +3 -1
  252. package/src/auction.js +6 -1
  253. package/src/events.js +5 -1
  254. package/src/pbjsORTB.js +35 -0
  255. package/src/prebid.js +137 -112
  256. package/src/targeting.js +10 -2
  257. package/src/utils/currency.js +16 -0
  258. package/src/utils.js +21 -0
  259. package/test/spec/auctionmanager_spec.js +15 -0
  260. package/test/spec/modules/aaxBlockmeter_spec.js +58 -0
  261. package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
  262. package/test/spec/modules/chtnwBidAdapter_spec.js +105 -0
  263. package/test/spec/modules/concertBidAdapter_spec.js +56 -0
  264. package/test/spec/modules/connectIdSystem_spec.js +175 -5
  265. package/test/spec/modules/consentManagementUsp_spec.js +64 -18
  266. package/test/spec/modules/criteoBidAdapter_spec.js +28 -0
  267. package/test/spec/modules/dgkeywordRtdProvider_spec.js +3 -3
  268. package/test/spec/modules/eids_spec.js +10 -7
  269. package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
  270. package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
  271. package/test/spec/modules/improvedigitalBidAdapter_spec.js +231 -211
  272. package/test/spec/modules/ixBidAdapter_spec.js +412 -350
  273. package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
  274. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
  275. package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
  276. package/test/spec/modules/openxOrtbBidAdapter_spec.js +77 -49
  277. package/test/spec/modules/oxxionRtdProvider_spec.js +142 -0
  278. package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
  279. package/test/spec/modules/prebidServerBidAdapter_spec.js +139 -137
  280. package/test/spec/modules/realTimeDataModule_spec.js +65 -0
  281. package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
  282. package/test/spec/modules/userId_spec.js +67 -1
  283. package/test/spec/modules/videoModule/coreVideo_spec.js +98 -0
  284. package/test/spec/modules/videoModule/pbVideo_spec.js +362 -0
  285. package/test/spec/modules/videoModule/shared/parentModule_spec.js +73 -0
  286. package/test/spec/modules/videoModule/shared/state_spec.js +26 -0
  287. package/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js +103 -0
  288. package/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js +209 -0
  289. package/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +846 -0
  290. package/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js +391 -0
  291. package/test/spec/modules/videoModule/videoImpressionVerifier_spec.js +112 -0
  292. package/test/spec/ortbConverter/banner_spec.js +203 -0
  293. package/test/spec/ortbConverter/composer_spec.js +69 -0
  294. package/test/spec/ortbConverter/converter_spec.js +283 -0
  295. package/test/spec/ortbConverter/currency_spec.js +40 -0
  296. package/test/spec/ortbConverter/default_processors_spec.js +61 -0
  297. package/test/spec/ortbConverter/gdpr_spec.js +38 -0
  298. package/test/spec/ortbConverter/mediaTypes_spec.js +67 -0
  299. package/test/spec/ortbConverter/mergeProcessors_spec.js +59 -0
  300. package/test/spec/ortbConverter/multibid_spec.js +35 -0
  301. package/test/spec/ortbConverter/native_spec.js +95 -0
  302. package/test/spec/ortbConverter/pbjsORTB_spec.js +67 -0
  303. package/test/spec/ortbConverter/pbsExtensions/aliases_spec.js +57 -0
  304. package/test/spec/ortbConverter/pbsExtensions/params_spec.js +96 -0
  305. package/test/spec/ortbConverter/pbsExtensions/video_spec.js +52 -0
  306. package/test/spec/ortbConverter/priceFloors_spec.js +143 -0
  307. package/test/spec/ortbConverter/schain_spec.js +33 -0
  308. package/test/spec/ortbConverter/userId_spec.js +21 -0
  309. package/test/spec/ortbConverter/usp_spec.js +15 -0
  310. package/test/spec/ortbConverter/video_spec.js +189 -0
  311. package/test/spec/unit/core/adapterManager_spec.js +102 -0
  312. package/test/spec/unit/core/targeting_spec.js +34 -0
  313. package/test/spec/unit/pbjs_api_spec.js +124 -45
  314. package/test/spec/utils_spec.js +45 -1
@@ -0,0 +1,17 @@
1
+ # Overview
2
+
3
+ Module Name: Video.js Video Provider
4
+ Module Type: Video Submodule
5
+ Video Player: video.js
6
+ Player website: https://videojs.com/
7
+ Maintainer: Prebid Video Task Force
8
+
9
+ # Description
10
+
11
+ Video provider to connect the Prebid Video Module to video.js.
12
+
13
+ # Requirements
14
+
15
+ - Your page must include a build of video.js. For instructions see https://videojs.com/getting-started .
16
+ - Your video.js instance must include the Google IMA plugin.
17
+ - The Google IMA plugin must be accessible publicly in order for the Video.js Video Provider to reference it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "7.22.0",
3
+ "version": "7.24.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -35,13 +35,13 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@babel/eslint-parser": "^7.16.5",
38
- "@wdio/browserstack-service": "^7.16.0",
39
- "@wdio/cli": "^7.5.2",
40
- "@wdio/concise-reporter": "^7.5.2",
41
- "@wdio/local-runner": "^7.5.2",
42
- "@wdio/mocha-framework": "^7.5.2",
43
- "@wdio/spec-reporter": "^7.19.0",
44
- "@wdio/sync": "^7.5.2",
38
+ "@wdio/browserstack-service": "~7.16.0",
39
+ "@wdio/cli": "~7.5.2",
40
+ "@wdio/concise-reporter": "~7.5.2",
41
+ "@wdio/local-runner": "~7.5.2",
42
+ "@wdio/mocha-framework": "~7.5.2",
43
+ "@wdio/spec-reporter": "~7.19.0",
44
+ "@wdio/sync": "~7.5.2",
45
45
  "ajv": "6.12.3",
46
46
  "assert": "^2.0.0",
47
47
  "babel-loader": "^8.0.5",
@@ -105,6 +105,10 @@
105
105
  "through2": "^4.0.2",
106
106
  "url": "^0.11.0",
107
107
  "url-parse": "^1.0.5",
108
+ "video.js": "^7.17.0",
109
+ "videojs-contrib-ads": "^6.9.0",
110
+ "videojs-ima": "^1.11.0",
111
+ "videojs-playlist": "^5.0.0",
108
112
  "webdriverio": "^7.6.1",
109
113
  "webpack": "^5.70.0",
110
114
  "webpack-bundle-analyzer": "^4.5.0",
@@ -23,7 +23,7 @@ export function emitAdRenderFail({ reason, message, bid, id }) {
23
23
 
24
24
  /**
25
25
  * Emit the AD_RENDER_SUCCEEDED event.
26
- *
26
+ * (Note: Invocation of this function indicates that the render function did not generate an error, it does not guarantee that tracking for this event has occurred yet.)
27
27
  * @param doc document object that was used to `.write` the ad. Should be `null` if unavailable (e.g. for documents in
28
28
  * a cross-origin frame).
29
29
  * @param bid bid response object for the ad that was rendered
@@ -35,6 +35,7 @@ import {GdprConsentHandler, UspConsentHandler} from './consentHandler.js';
35
35
  import * as events from './events.js';
36
36
  import CONSTANTS from './constants.json';
37
37
  import {useMetrics} from './utils/perfMetrics.js';
38
+ import {auctionManager} from './auctionManager.js';
38
39
 
39
40
  export const PARTITIONS = {
40
41
  CLIENT: 'client',
@@ -553,19 +554,30 @@ adapterManager.getAnalyticsAdapter = function(code) {
553
554
  return _analyticsRegistry[code];
554
555
  }
555
556
 
556
- function tryCallBidderMethod(bidder, method, param) {
557
+ function getBidderMethod(bidder, method) {
558
+ const adapter = _bidderRegistry[bidder];
559
+ const spec = adapter?.getSpec && adapter.getSpec();
560
+ if (spec && spec[method] && typeof spec[method] === 'function') {
561
+ return [spec, spec[method]]
562
+ }
563
+ }
564
+
565
+ function invokeBidderMethod(bidder, method, spec, fn, ...params) {
557
566
  try {
558
- const adapter = _bidderRegistry[bidder];
559
- const spec = adapter.getSpec();
560
- if (spec && spec[method] && typeof spec[method] === 'function') {
561
- logInfo(`Invoking ${bidder}.${method}`);
562
- config.runWithBidder(bidder, bind.call(spec[method], spec, param));
563
- }
567
+ logInfo(`Invoking ${bidder}.${method}`);
568
+ config.runWithBidder(bidder, fn.bind(spec, ...params));
564
569
  } catch (e) {
565
570
  logWarn(`Error calling ${method} of ${bidder}`);
566
571
  }
567
572
  }
568
573
 
574
+ function tryCallBidderMethod(bidder, method, param) {
575
+ const target = getBidderMethod(bidder, method);
576
+ if (target != null) {
577
+ invokeBidderMethod(bidder, method, ...target, param);
578
+ }
579
+ }
580
+
569
581
  adapterManager.callTimedOutBidders = function(adUnits, timedOutBidders, cbTimeout) {
570
582
  timedOutBidders = timedOutBidders.map((timedOutBidder) => {
571
583
  // Adding user configured params & timeout to timeout event data
@@ -600,4 +612,41 @@ adapterManager.callBidderError = function(bidder, error, bidderRequest) {
600
612
  tryCallBidderMethod(bidder, 'onBidderError', param);
601
613
  };
602
614
 
615
+ function resolveAlias(alias) {
616
+ const seen = new Set();
617
+ while (_aliasRegistry.hasOwnProperty(alias) && !seen.has(alias)) {
618
+ seen.add(alias);
619
+ alias = _aliasRegistry[alias];
620
+ }
621
+ return alias;
622
+ }
623
+ /**
624
+ * Ask every adapter to delete PII.
625
+ * See https://github.com/prebid/Prebid.js/issues/9081
626
+ */
627
+ adapterManager.callDataDeletionRequest = hook('sync', function (...args) {
628
+ const method = 'onDataDeletionRequest';
629
+ Object.keys(_bidderRegistry)
630
+ .filter((bidder) => !_aliasRegistry.hasOwnProperty(bidder))
631
+ .forEach(bidder => {
632
+ const target = getBidderMethod(bidder, method);
633
+ if (target != null) {
634
+ const bidderRequests = auctionManager.getBidsRequested().filter((br) =>
635
+ resolveAlias(br.bidderCode) === bidder
636
+ );
637
+ invokeBidderMethod(bidder, method, ...target, bidderRequests, ...args);
638
+ }
639
+ });
640
+ Object.entries(_analyticsRegistry).forEach(([name, entry]) => {
641
+ const fn = entry?.adapter?.[method];
642
+ if (typeof fn === 'function') {
643
+ try {
644
+ fn.apply(entry.adapter, args);
645
+ } catch (e) {
646
+ logError(`error calling ${method} of ${name}`, e);
647
+ }
648
+ }
649
+ });
650
+ });
651
+
603
652
  export default adapterManager;
package/src/adloader.js CHANGED
@@ -6,6 +6,7 @@ const _requestCache = new WeakMap();
6
6
  const _approvedLoadExternalJSList = [
7
7
  'debugging',
8
8
  'adloox',
9
+ 'admatic',
9
10
  'criteo',
10
11
  'outstream',
11
12
  'adagio',
@@ -19,7 +20,8 @@ const _approvedLoadExternalJSList = [
19
20
  'inskin',
20
21
  'hadron',
21
22
  'medianet',
22
- 'improvedigital'
23
+ 'improvedigital',
24
+ 'aaxBlockmeter'
23
25
  ]
24
26
 
25
27
  /**
package/src/auction.js CHANGED
@@ -475,7 +475,7 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
475
475
  return handleBidResponse(adUnitCode, bid, (done) => {
476
476
  // return a "NO_BID" replacement that the caller can decide to continue with
477
477
  // TODO: remove this in v8; see https://github.com/prebid/Prebid.js/issues/8956
478
- const noBid = createBid(CONSTANTS.STATUS.NO_BID, bid.getIdentifiers());
478
+ const noBid = createBid(CONSTANTS.STATUS.NO_BID, bid.getIdentifiers?.());
479
479
  Object.assign(noBid, Object.fromEntries(Object.entries(bid).filter(([k]) => !noBid.hasOwnProperty(k) && ![
480
480
  'ad',
481
481
  'adUrl',
@@ -666,6 +666,7 @@ export const callPrebidCache = hook('async', function(auctionInstance, bidRespon
666
666
  */
667
667
  function addCommonResponseProperties(bidResponse, adUnitCode, {index = auctionManager.index} = {}) {
668
668
  const bidderRequest = index.getBidderRequest(bidResponse);
669
+ const adUnit = index.getAdUnit(bidResponse);
669
670
  const start = (bidderRequest && bidderRequest.start) || bidResponse.requestTimestamp;
670
671
 
671
672
  Object.assign(bidResponse, {
@@ -676,6 +677,10 @@ function addCommonResponseProperties(bidResponse, adUnitCode, {index = auctionMa
676
677
  adUnitCode
677
678
  });
678
679
 
680
+ if (adUnit?.ttlBuffer != null) {
681
+ bidResponse.ttlBuffer = adUnit.ttlBuffer;
682
+ }
683
+
679
684
  bidResponse.timeToRespond = bidResponse.responseTimestamp - bidResponse.requestTimestamp;
680
685
  }
681
686
 
package/src/events.js CHANGED
@@ -133,6 +133,10 @@ const _public = (function () {
133
133
  return _handlers;
134
134
  };
135
135
 
136
+ _public.addEvents = function (events) {
137
+ allEvents = allEvents.concat(events);
138
+ }
139
+
136
140
  /**
137
141
  * This method can return a copy of all the events fired
138
142
  * @return {Array} array of events fired
@@ -152,4 +156,4 @@ const _public = (function () {
152
156
 
153
157
  utils._setEventEmitter(_public.emit.bind(_public));
154
158
 
155
- export const {on, off, get, getEvents, emit} = _public;
159
+ export const {on, off, get, getEvents, emit, addEvents} = _public;
@@ -0,0 +1,35 @@
1
+ export const PROCESSOR_TYPES = ['request', 'imp', 'bidResponse', 'response'];
2
+ export const PROCESSOR_DIALECTS = ['default', 'pbs'];
3
+ export const [REQUEST, IMP, BID_RESPONSE, RESPONSE] = PROCESSOR_TYPES;
4
+ export const [DEFAULT, PBS] = PROCESSOR_DIALECTS;
5
+
6
+ const types = new Set(PROCESSOR_TYPES);
7
+
8
+ export function processorRegistry() {
9
+ const processors = {};
10
+
11
+ return {
12
+ registerOrtbProcessor({type, name, fn, priority = 0, dialects = [DEFAULT]}) {
13
+ if (!types.has(type)) {
14
+ throw new Error(`ORTB processor type must be one of: ${PROCESSOR_TYPES.join(', ')}`)
15
+ }
16
+ dialects.forEach(dialect => {
17
+ if (!processors.hasOwnProperty(dialect)) {
18
+ processors[dialect] = {};
19
+ }
20
+ if (!processors[dialect].hasOwnProperty(type)) {
21
+ processors[dialect][type] = {};
22
+ }
23
+ processors[dialect][type][name] = {
24
+ priority,
25
+ fn
26
+ }
27
+ })
28
+ },
29
+ getProcessors(dialect) {
30
+ return processors[dialect] || {};
31
+ }
32
+ }
33
+ }
34
+
35
+ export const {registerOrtbProcessor, getProcessors} = processorRegistry();
package/src/prebid.js CHANGED
@@ -49,6 +49,7 @@ import {default as adapterManager, gdprDataHandler, getS2SBidderSet, uspDataHand
49
49
  import CONSTANTS from './constants.json';
50
50
  import * as events from './events.js';
51
51
  import {newMetrics, useMetrics} from './utils/perfMetrics.js';
52
+ import {defer} from './utils/promise.js';
52
53
 
53
54
  const $$PREBID_GLOBAL$$ = getGlobal();
54
55
  const { triggerUserSyncs } = userSync;
@@ -485,86 +486,99 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
485
486
  logInfo('Invoking $$PREBID_GLOBAL$$.renderAd', arguments);
486
487
  logMessage('Calling renderAd with adId :' + id);
487
488
 
488
- if (doc && id) {
489
- try {
490
- // lookup ad by ad Id
491
- const bid = auctionManager.findBidByAdId(id);
492
-
493
- if (bid) {
494
- let shouldRender = true;
495
- if (bid && bid.status === CONSTANTS.BID_STATUS.RENDERED) {
496
- logWarn(`Ad id ${bid.adId} has been rendered before`);
497
- events.emit(STALE_RENDER, bid);
498
- if (deepAccess(config.getConfig('auctionOptions'), 'suppressStaleRender')) {
499
- shouldRender = false;
500
- }
501
- }
502
-
503
- if (shouldRender) {
504
- // replace macros according to openRTB with price paid = bid.cpm
505
- bid.ad = replaceAuctionPrice(bid.ad, bid.originalCpm || bid.cpm);
506
- bid.adUrl = replaceAuctionPrice(bid.adUrl, bid.originalCpm || bid.cpm);
507
- // replacing clickthrough if submitted
508
- if (options && options.clickThrough) {
509
- const {clickThrough} = options;
510
- bid.ad = replaceClickThrough(bid.ad, clickThrough);
511
- bid.adUrl = replaceClickThrough(bid.adUrl, clickThrough);
512
- }
513
-
514
- // save winning bids
515
- auctionManager.addWinningBid(bid);
516
-
517
- // emit 'bid won' event here
518
- events.emit(BID_WON, bid);
519
-
520
- const {height, width, ad, mediaType, adUrl, renderer} = bid;
521
-
522
- const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`);
523
- insertElement(creativeComment, doc, 'html');
524
-
525
- if (isRendererRequired(renderer)) {
526
- executeRenderer(renderer, bid, doc);
527
- reinjectNodeIfRemoved(creativeComment, doc, 'html');
528
- emitAdRenderSucceeded({ doc, bid, id });
529
- } else if ((doc === document && !inIframe()) || mediaType === 'video') {
530
- const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
531
- emitAdRenderFail({reason: PREVENT_WRITING_ON_MAIN_DOCUMENT, message, bid, id});
532
- } else if (ad) {
533
- doc.write(ad);
534
- doc.close();
535
- setRenderSize(doc, width, height);
536
- reinjectNodeIfRemoved(creativeComment, doc, 'html');
537
- callBurl(bid);
538
- emitAdRenderSucceeded({ doc, bid, id });
539
- } else if (adUrl) {
540
- const iframe = createInvisibleIframe();
541
- iframe.height = height;
542
- iframe.width = width;
543
- iframe.style.display = 'inline';
544
- iframe.style.overflow = 'hidden';
545
- iframe.src = adUrl;
546
-
547
- insertElement(iframe, doc, 'body');
548
- setRenderSize(doc, width, height);
549
- reinjectNodeIfRemoved(creativeComment, doc, 'html');
550
- callBurl(bid);
551
- emitAdRenderSucceeded({ doc, bid, id });
552
- } else {
553
- const message = `Error trying to write ad. No ad for bid response id: ${id}`;
554
- emitAdRenderFail({reason: NO_AD, message, bid, id});
555
- }
556
- }
557
- } else {
558
- const message = `Error trying to write ad. Cannot find ad by given id : ${id}`;
559
- emitAdRenderFail({ reason: CANNOT_FIND_AD, message, id });
489
+ if (!id) {
490
+ const message = `Error trying to write ad Id :${id} to the page. Missing adId`;
491
+ emitAdRenderFail({ reason: MISSING_DOC_OR_ADID, message, id });
492
+ return;
493
+ }
494
+
495
+ try {
496
+ // lookup ad by ad Id
497
+ const bid = auctionManager.findBidByAdId(id);
498
+ if (!bid) {
499
+ const message = `Error trying to write ad. Cannot find ad by given id : ${id}`;
500
+ emitAdRenderFail({ reason: CANNOT_FIND_AD, message, id });
501
+ return;
502
+ }
503
+
504
+ if (bid.status === CONSTANTS.BID_STATUS.RENDERED) {
505
+ logWarn(`Ad id ${bid.adId} has been rendered before`);
506
+ events.emit(STALE_RENDER, bid);
507
+ if (deepAccess(config.getConfig('auctionOptions'), 'suppressStaleRender')) {
508
+ return;
560
509
  }
561
- } catch (e) {
562
- const message = `Error trying to write ad Id :${id} to the page:${e.message}`;
563
- emitAdRenderFail({ reason: EXCEPTION, message, id });
564
510
  }
565
- } else {
566
- const message = `Error trying to write ad Id :${id} to the page. Missing document or adId`;
567
- emitAdRenderFail({ reason: MISSING_DOC_OR_ADID, message, id });
511
+
512
+ // replace macros according to openRTB with price paid = bid.cpm
513
+ bid.ad = replaceAuctionPrice(bid.ad, bid.originalCpm || bid.cpm);
514
+ bid.adUrl = replaceAuctionPrice(bid.adUrl, bid.originalCpm || bid.cpm);
515
+ // replacing clickthrough if submitted
516
+ if (options && options.clickThrough) {
517
+ const {clickThrough} = options;
518
+ bid.ad = replaceClickThrough(bid.ad, clickThrough);
519
+ bid.adUrl = replaceClickThrough(bid.adUrl, clickThrough);
520
+ }
521
+
522
+ // save winning bids
523
+ auctionManager.addWinningBid(bid);
524
+
525
+ // emit 'bid won' event here
526
+ events.emit(BID_WON, bid);
527
+
528
+ const {height, width, ad, mediaType, adUrl, renderer} = bid;
529
+
530
+ // video module
531
+ const adUnitCode = bid.adUnitCode;
532
+ const adUnit = $$PREBID_GLOBAL$$.adUnits.filter(adUnit => adUnit.code === adUnitCode);
533
+ const videoModule = $$PREBID_GLOBAL$$.videoModule;
534
+ if (adUnit.video && videoModule) {
535
+ videoModule.renderBid(adUnit.video.divId, bid);
536
+ return;
537
+ }
538
+
539
+ if (!doc) {
540
+ const message = `Error trying to write ad Id :${id} to the page. Missing document`;
541
+ emitAdRenderFail({ reason: MISSING_DOC_OR_ADID, message, id });
542
+ return;
543
+ }
544
+
545
+ const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`);
546
+ insertElement(creativeComment, doc, 'html');
547
+
548
+ if (isRendererRequired(renderer)) {
549
+ executeRenderer(renderer, bid, doc);
550
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
551
+ emitAdRenderSucceeded({ doc, bid, id });
552
+ } else if ((doc === document && !inIframe()) || mediaType === 'video') {
553
+ const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
554
+ emitAdRenderFail({reason: PREVENT_WRITING_ON_MAIN_DOCUMENT, message, bid, id});
555
+ } else if (ad) {
556
+ doc.write(ad);
557
+ doc.close();
558
+ setRenderSize(doc, width, height);
559
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
560
+ callBurl(bid);
561
+ emitAdRenderSucceeded({ doc, bid, id });
562
+ } else if (adUrl) {
563
+ const iframe = createInvisibleIframe();
564
+ iframe.height = height;
565
+ iframe.width = width;
566
+ iframe.style.display = 'inline';
567
+ iframe.style.overflow = 'hidden';
568
+ iframe.src = adUrl;
569
+
570
+ insertElement(iframe, doc, 'body');
571
+ setRenderSize(doc, width, height);
572
+ reinjectNodeIfRemoved(creativeComment, doc, 'html');
573
+ callBurl(bid);
574
+ emitAdRenderSucceeded({ doc, bid, id });
575
+ } else {
576
+ const message = `Error trying to write ad. No ad for bid response id: ${id}`;
577
+ emitAdRenderFail({reason: NO_AD, message, bid, id});
578
+ }
579
+ } catch (e) {
580
+ const message = `Error trying to write ad Id :${id} to the page:${e.message}`;
581
+ emitAdRenderFail({ reason: EXCEPTION, message, id });
568
582
  }
569
583
  });
570
584
 
@@ -609,7 +623,7 @@ $$PREBID_GLOBAL$$.removeAdUnit = function (adUnitCode) {
609
623
  * @alias module:pbjs.requestBids
610
624
  */
611
625
  $$PREBID_GLOBAL$$.requestBids = (function() {
612
- const delegate = hook('async', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ortb2, metrics } = {}) {
626
+ const delegate = hook('async', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2, metrics, defer } = {}) {
613
627
  events.emit(REQUEST_BIDS);
614
628
  const cbTimeout = timeout || config.getConfig('bidderTimeout');
615
629
  logInfo('Invoking $$PREBID_GLOBAL$$.requestBids', arguments);
@@ -617,23 +631,28 @@ $$PREBID_GLOBAL$$.requestBids = (function() {
617
631
  global: mergeDeep({}, config.getAnyConfig('ortb2') || {}, ortb2 || {}),
618
632
  bidder: Object.fromEntries(Object.entries(config.getBidderConfig()).map(([bidder, cfg]) => [bidder, cfg.ortb2]).filter(([_, ortb2]) => ortb2 != null))
619
633
  }
620
- return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ortb2Fragments, metrics});
634
+ return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics, defer});
621
635
  }, 'requestBids');
622
636
 
623
637
  return wrapHook(delegate, function requestBids(req = {}) {
624
- // if the request does not specify adUnits, clone the global adUnit array - before
625
- // any hook has a chance to run.
638
+ // unlike the main body of `delegate`, this runs before any other hook has a chance to;
639
+ // it's also not restricted in its return value in the way `async` hooks are.
640
+
641
+ // if the request does not specify adUnits, clone the global adUnit array;
626
642
  // otherwise, if the caller goes on to use addAdUnits/removeAdUnits, any asynchronous logic
627
643
  // in any hook might see their effects.
628
- req.metrics = newMetrics();
629
- req.metrics.checkpoint('requestBids');
630
644
  let adUnits = req.adUnits || $$PREBID_GLOBAL$$.adUnits;
631
645
  req.adUnits = (isArray(adUnits) ? adUnits.slice() : [adUnits]);
632
- return delegate.call(this, req);
646
+
647
+ req.metrics = newMetrics();
648
+ req.metrics.checkpoint('requestBids');
649
+ req.defer = defer({promiseFactory: (r) => new Promise(r)})
650
+ delegate.call(this, req);
651
+ return req.defer.promise;
633
652
  });
634
653
  })();
635
654
 
636
- export const startAuction = hook('async', function ({ bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ortb2Fragments, metrics } = {}) {
655
+ export const startAuction = hook('async', function ({ bidsBackHandler, timeout: cbTimeout, adUnits, ttlBuffer, adUnitCodes, labels, auctionId, ortb2Fragments, metrics, defer } = {}) {
637
656
  const s2sBidders = getS2SBidderSet(config.getConfig('s2sConfig') || []);
638
657
  adUnits = useMetrics(metrics).measureTime('requestBids.validate', () => checkAdUnitSetup(adUnits));
639
658
 
@@ -645,6 +664,17 @@ export const startAuction = hook('async', function ({ bidsBackHandler, timeout:
645
664
  adUnitCodes = adUnits && adUnits.map(unit => unit.code);
646
665
  }
647
666
 
667
+ function auctionDone(bids, timedOut, auctionId) {
668
+ if (typeof bidsBackHandler === 'function') {
669
+ try {
670
+ bidsBackHandler(bids, timedOut, auctionId);
671
+ } catch (e) {
672
+ logError('Error executing bidsBackHandler', null, e);
673
+ }
674
+ }
675
+ defer.resolve({bids, timedOut, auctionId})
676
+ }
677
+
648
678
  /*
649
679
  * for a given adunit which supports a set of mediaTypes
650
680
  * and a given bidder which supports a set of mediaTypes
@@ -663,6 +693,9 @@ export const startAuction = hook('async', function ({ bidsBackHandler, timeout:
663
693
 
664
694
  const tid = adUnit.ortb2Imp?.ext?.tid || generateUUID();
665
695
  adUnit.transactionId = tid;
696
+ if (ttlBuffer != null && !adUnit.hasOwnProperty('ttlBuffer')) {
697
+ adUnit.ttlBuffer = ttlBuffer;
698
+ }
666
699
  // Populate ortb2Imp.ext.tid with transactionId. Specifying a transaction ID per item in the ortb impression array, lets multiple transaction IDs be transmitted in a single bid request.
667
700
  deepSetValue(adUnit, 'ortb2Imp.ext.tid', tid);
668
701
 
@@ -687,35 +720,27 @@ export const startAuction = hook('async', function ({ bidsBackHandler, timeout:
687
720
 
688
721
  if (!adUnits || adUnits.length === 0) {
689
722
  logMessage('No adUnits configured. No bids requested.');
690
- if (typeof bidsBackHandler === 'function') {
691
- // executeCallback, this will only be called in case of first request
692
- try {
693
- bidsBackHandler();
694
- } catch (e) {
695
- logError('Error executing bidsBackHandler', null, e);
696
- }
697
- }
698
- return;
699
- }
723
+ auctionDone();
724
+ } else {
725
+ const auction = auctionManager.createAuction({
726
+ adUnits,
727
+ adUnitCodes,
728
+ callback: auctionDone,
729
+ cbTimeout,
730
+ labels,
731
+ auctionId,
732
+ ortb2Fragments,
733
+ metrics,
734
+ });
700
735
 
701
- const auction = auctionManager.createAuction({
702
- adUnits,
703
- adUnitCodes,
704
- callback: bidsBackHandler,
705
- cbTimeout,
706
- labels,
707
- auctionId,
708
- ortb2Fragments,
709
- metrics,
710
- });
736
+ let adUnitsLen = adUnits.length;
737
+ if (adUnitsLen > 15) {
738
+ logInfo(`Current auction ${auction.getAuctionId()} contains ${adUnitsLen} adUnits.`, adUnits);
739
+ }
711
740
 
712
- let adUnitsLen = adUnits.length;
713
- if (adUnitsLen > 15) {
714
- logInfo(`Current auction ${auction.getAuctionId()} contains ${adUnitsLen} adUnits.`, adUnits);
741
+ adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId()));
742
+ auction.callBids();
715
743
  }
716
-
717
- adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId()));
718
- auction.callBids();
719
744
  }, 'startAuction');
720
745
 
721
746
  export function executeCallbacks(fn, reqBidsConfigObj) {
package/src/targeting.js CHANGED
@@ -28,7 +28,15 @@ import CONSTANTS from './constants.json';
28
28
  var pbTargetingKeys = [];
29
29
 
30
30
  const MAX_DFP_KEYLENGTH = 20;
31
- const TTL_BUFFER = 1000;
31
+ let DEFAULT_TTL_BUFFER = 1;
32
+
33
+ config.getConfig('ttlBuffer', (cfg) => {
34
+ if (typeof cfg.ttlBuffer === 'number') {
35
+ DEFAULT_TTL_BUFFER = cfg.ttlBuffer;
36
+ } else {
37
+ logError('Invalid value for ttlBuffer', cfg.ttlBuffer);
38
+ }
39
+ })
32
40
 
33
41
  const CFG_ALLOW_TARGETING_KEYS = `targetingControls.allowTargetingKeys`;
34
42
  const CFG_ADD_TARGETING_KEYS = `targetingControls.addTargetingKeys`;
@@ -39,7 +47,7 @@ export const TARGETING_KEYS = Object.keys(CONSTANTS.TARGETING_KEYS).map(
39
47
  );
40
48
 
41
49
  // return unexpired bids
42
- const isBidNotExpired = (bid) => (bid.responseTimestamp + bid.ttl * 1000 - TTL_BUFFER) > timestamp();
50
+ const isBidNotExpired = (bid) => (bid.responseTimestamp + (bid.ttl - (bid.hasOwnProperty('ttlBuffer') ? bid.ttlBuffer : DEFAULT_TTL_BUFFER)) * 1000) > timestamp();
43
51
 
44
52
  // return bids whose status is not set. Winning bids can only have a status of `rendered`.
45
53
  const isUnusedBid = (bid) => bid && ((bid.status && !includes([CONSTANTS.BID_STATUS.RENDERED], bid.status)) || !bid.status);
@@ -0,0 +1,16 @@
1
+ import {getGlobal} from '../prebidGlobal.js';
2
+
3
+ /**
4
+ * "best effort" wrapper around currency conversion; always returns an amount that may or may not be correct.
5
+ */
6
+ export function beConvertCurrency(amount, from, to) {
7
+ if (from === to) return amount;
8
+ let result = amount;
9
+ if (typeof getGlobal().convertCurrency === 'function') {
10
+ try {
11
+ result = getGlobal().convertCurrency(amount, from, to);
12
+ } catch (e) {
13
+ }
14
+ }
15
+ return result;
16
+ }
package/src/utils.js CHANGED
@@ -1377,6 +1377,27 @@ export function safeJSONParse(data) {
1377
1377
  } catch (e) {}
1378
1378
  }
1379
1379
 
1380
+ /**
1381
+ * Returns a memoized version of `fn`.
1382
+ *
1383
+ * @param fn
1384
+ * @param key cache key generator, invoked with the same arguments passed to `fn`.
1385
+ * By default, the first argument is used as key.
1386
+ * @return {function(): any}
1387
+ */
1388
+ export function memoize(fn, key = function (arg) { return arg; }) {
1389
+ const cache = new Map();
1390
+ const memoized = function () {
1391
+ const cacheKey = key.apply(this, arguments);
1392
+ if (!cache.has(cacheKey)) {
1393
+ cache.set(cacheKey, fn.apply(this, arguments));
1394
+ }
1395
+ return cache.get(cacheKey);
1396
+ }
1397
+ memoized.clear = cache.clear.bind(cache);
1398
+ return memoized;
1399
+ }
1400
+
1380
1401
  /**
1381
1402
  * Sets dataset attributes on a script
1382
1403
  * @param {Script} script
@@ -955,6 +955,12 @@ describe('auctionmanager.js', function () {
955
955
  const addedBid = find(auction.getBidsReceived(), bid => bid.adUnitCode == ADUNIT_CODE);
956
956
  assert.equal(addedBid.renderer.url, 'renderer.js');
957
957
  });
958
+
959
+ it('sets bidResponse.ttlBuffer from adUnit.ttlBuffer', () => {
960
+ adUnits[0].ttlBuffer = 0;
961
+ auction.callBids();
962
+ expect(auction.getBidsReceived()[0].ttlBuffer).to.eql(0);
963
+ });
958
964
  });
959
965
 
960
966
  describe('when auction timeout is 20', function () {
@@ -1635,6 +1641,15 @@ describe('auctionmanager.js', function () {
1635
1641
  });
1636
1642
  });
1637
1643
 
1644
+ it('should return NO_BID replacement when rejected bid is not a "proper" bid', () => {
1645
+ const noBid = cbs.addBidResponse.reject(AU_CODE, {});
1646
+ sinon.assert.match(noBid, {
1647
+ status: CONSTANTS.BID_STATUS.BID_REJECTED,
1648
+ statusMessage: 'Bid returned empty or error response',
1649
+ cpm: 0,
1650
+ });
1651
+ })
1652
+
1638
1653
  it('addBidResponse hooks should not be able to reject the same bid twice', () => {
1639
1654
  cbs.addBidResponse(AU_CODE, bid);
1640
1655
  expect(auction.addBidRejected.calledOnce).to.be.true;