prebid.js 7.23.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 (159) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/admaticBidAdapter.js +1 -0
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/adyoulikeBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/audiencerunBidAdapter.js +1 -1
  17. package/dist/axonixBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bluebillywigBidAdapter.js +1 -1
  21. package/dist/bridgewellBidAdapter.js +1 -1
  22. package/dist/brightMountainMediaBidAdapter.js +1 -1
  23. package/dist/carodaBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectIdSystem.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/finativeBidAdapter.js +1 -1
  35. package/dist/glimpseBidAdapter.js +1 -1
  36. package/dist/gmosspBidAdapter.js +1 -1
  37. package/dist/goldbachBidAdapter.js +1 -1
  38. package/dist/gridBidAdapter.js +1 -1
  39. package/dist/gridNMBidAdapter.js +1 -1
  40. package/dist/growthCodeIdSystem.js +1 -1
  41. package/dist/gumgumBidAdapter.js +1 -1
  42. package/dist/h12mediaBidAdapter.js +1 -1
  43. package/dist/id5IdSystem.js +1 -1
  44. package/dist/impactifyBidAdapter.js +1 -1
  45. package/dist/improvedigitalBidAdapter.js +1 -1
  46. package/dist/inmarBidAdapter.js +1 -1
  47. package/dist/insticatorBidAdapter.js +1 -1
  48. package/dist/ixBidAdapter.js +1 -1
  49. package/dist/jixieBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/konduitAnalyticsAdapter.js +1 -1
  52. package/dist/kueezBidAdapter.js +1 -1
  53. package/dist/kueezRtbBidAdapter.js +1 -0
  54. package/dist/lassoBidAdapter.js +1 -1
  55. package/dist/lifestreetBidAdapter.js +1 -1
  56. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  57. package/dist/logicadBidAdapter.js +1 -1
  58. package/dist/loglyliftBidAdapter.js +1 -1
  59. package/dist/magniteAnalyticsAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediakeysBidAdapter.js +1 -1
  64. package/dist/mediasquareBidAdapter.js +1 -1
  65. package/dist/mgidBidAdapter.js +1 -1
  66. package/dist/mgidRtdProvider.js +1 -0
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/not-for-prod/prebid.js +122 -119
  69. package/dist/oguryBidAdapter.js +1 -1
  70. package/dist/onetagBidAdapter.js +1 -1
  71. package/dist/ooloAnalyticsAdapter.js +1 -1
  72. package/dist/outbrainBidAdapter.js +1 -1
  73. package/dist/parrableIdSystem.js +1 -1
  74. package/dist/pbsExtensions.js +1 -1
  75. package/dist/permutiveRtdProvider.js +1 -1
  76. package/dist/pixfutureBidAdapter.js +1 -1
  77. package/dist/prebid-core.js +1 -1
  78. package/dist/publinkIdSystem.js +1 -1
  79. package/dist/pubmaticBidAdapter.js +1 -1
  80. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  81. package/dist/pxyzBidAdapter.js +1 -1
  82. package/dist/quantcastBidAdapter.js +1 -1
  83. package/dist/readpeakBidAdapter.js +1 -1
  84. package/dist/relaidoBidAdapter.js +1 -1
  85. package/dist/rhythmoneBidAdapter.js +1 -1
  86. package/dist/riseBidAdapter.js +1 -1
  87. package/dist/rubiconAnalyticsAdapter.js +1 -1
  88. package/dist/rubiconBidAdapter.js +1 -1
  89. package/dist/seedingAllianceBidAdapter.js +1 -1
  90. package/dist/seedtagBidAdapter.js +1 -1
  91. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  92. package/dist/sharethroughBidAdapter.js +1 -1
  93. package/dist/shinezBidAdapter.js +1 -1
  94. package/dist/smaatoBidAdapter.js +1 -1
  95. package/dist/smartadserverBidAdapter.js +1 -1
  96. package/dist/smartxBidAdapter.js +1 -1
  97. package/dist/smilewantedBidAdapter.js +1 -1
  98. package/dist/sonobiBidAdapter.js +1 -1
  99. package/dist/sovrnAnalyticsAdapter.js +1 -1
  100. package/dist/sovrnBidAdapter.js +1 -1
  101. package/dist/sspBCBidAdapter.js +1 -1
  102. package/dist/sublimeBidAdapter.js +1 -1
  103. package/dist/synacormediaBidAdapter.js +1 -1
  104. package/dist/targetVideoBidAdapter.js +1 -1
  105. package/dist/teadsBidAdapter.js +1 -1
  106. package/dist/trionBidAdapter.js +1 -1
  107. package/dist/tripleliftBidAdapter.js +1 -1
  108. package/dist/ttdBidAdapter.js +1 -1
  109. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  110. package/dist/underdogmediaBidAdapter.js +1 -1
  111. package/dist/undertoneBidAdapter.js +1 -1
  112. package/dist/userId.js +1 -1
  113. package/dist/vidazooBidAdapter.js +1 -1
  114. package/dist/videobyteBidAdapter.js +1 -1
  115. package/dist/visxBidAdapter.js +1 -1
  116. package/dist/vuukleBidAdapter.js +1 -1
  117. package/dist/widespaceBidAdapter.js +1 -1
  118. package/dist/winrBidAdapter.js +1 -1
  119. package/dist/yahoosspBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
  123. package/modules/.submodules.json +1 -0
  124. package/modules/admaticBidAdapter.js +147 -0
  125. package/modules/admaticBidAdapter.md +48 -0
  126. package/modules/amxBidAdapter.js +1 -0
  127. package/modules/connectIdSystem.js +36 -23
  128. package/modules/connectIdSystem.md +3 -2
  129. package/modules/growthCodeIdSystem.js +9 -5
  130. package/modules/gumgumBidAdapter.js +4 -0
  131. package/modules/ixBidAdapter.js +30 -7
  132. package/modules/kueezRtbBidAdapter.js +278 -0
  133. package/modules/kueezRtbBidAdapter.md +35 -0
  134. package/modules/magniteAnalyticsAdapter.js +6 -1
  135. package/modules/mgidRtdProvider.js +190 -0
  136. package/modules/mgidRtdProvider.md +51 -0
  137. package/modules/permutiveRtdProvider.js +2 -1
  138. package/modules/permutiveRtdProvider.md +36 -1
  139. package/modules/pubmaticBidAdapter.js +21 -29
  140. package/modules/tripleliftBidAdapter.js +1 -1
  141. package/modules/userId/eids.js +3 -10
  142. package/package.json +8 -8
  143. package/src/adRendering.js +1 -1
  144. package/src/adloader.js +1 -0
  145. package/src/auction.js +1 -1
  146. package/src/prebid.js +83 -79
  147. package/test/spec/auctionmanager_spec.js +9 -0
  148. package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
  149. package/test/spec/modules/connectIdSystem_spec.js +175 -5
  150. package/test/spec/modules/eids_spec.js +10 -7
  151. package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
  152. package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
  153. package/test/spec/modules/ixBidAdapter_spec.js +203 -0
  154. package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
  155. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
  156. package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
  157. package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
  158. package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
  159. package/test/spec/unit/pbjs_api_spec.js +17 -1
@@ -45,17 +45,52 @@ as well as enabling settings for specific use cases mentioned above (e.g. acbidd
45
45
  | params.acBidders | String[] | An array of bidders which should receive AC cohorts. | `[]` |
46
46
  | params.maxSegs | Integer | Maximum number of cohorts to be included in either the `permutive` or `p_standard` key-value. | `500` |
47
47
  | params.transformations | Object[] | An array of configurations for ORTB2 user data transformations | |
48
+ | params.overwrites | Object | An object specifying functions for custom targeting logic for bidders. | - |
48
49
 
49
50
  ##### The `transformations` parameter
50
51
 
51
52
  This array contains configurations for transformations we'll apply to the Permutive object in the ORTB2 `user.data` array. The results of these transformations will be appended to the `user.data` array that's attached to ORTB2 bid requests.
52
53
 
53
- ##### Supported transformations
54
+ ###### Supported transformations
54
55
 
55
56
  | Name | ID | Config structure | Description |
56
57
  |----------------|-----|---------------------------------------------------|--------------------------------------------------------------------------------------|
57
58
  | IAB taxonomies | iab | { segtax: number, iabIds: Object<number, number>} | Transform segment IDs from Permutive to IAB (note: alpha version, subject to change) |
58
59
 
60
+ ##### The `overwrites` parameter
61
+
62
+ The keys for this object should match a bidder (e.g. `rubicon`), which then can define a function to overwrite the customer targeting logic.
63
+
64
+ ```javascript
65
+ {
66
+ params: {
67
+ overwrites: {
68
+ rubicon: function customTargeting(bid, data, acEnabled, utils, defaultFn) {
69
+ if (defaultFn) {
70
+ bid = defaultFn(bid, data, acEnabled)
71
+ }
72
+ if (data.gam && data.gam.length) {
73
+ utils.deepSetValue(bid, 'params.visitor.permutive', data.gam)
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ ###### `customTargeting` function parameters
82
+
83
+ | Name | Description |
84
+ |--------------|--------------------------------------------------------------------------------|
85
+ | `bid` | The bid request object. |
86
+ | `data` | Permutive's targeting data read from localStorage. |
87
+ | `acEnabled` | Boolean stating whether Audience Connect is enabled via `acBidders`. |
88
+ | `utils` | An object of helpful utilities. `(deepSetValue, deepAccess, isFn, mergeDeep)`. |
89
+ | `defaultFn` | The default targeting function. |
90
+
91
+
92
+
93
+
59
94
  #### Context
60
95
 
61
96
  Permutive is not listed as a TCF vendor as all data collection is on behalf of the publisher and based on consent the publisher has received from the user.
@@ -392,37 +392,29 @@ function _createNativeRequest(params) {
392
392
  }
393
393
  break;
394
394
  case NATIVE_ASSETS.IMAGE.KEY:
395
- if (params[key].sizes && params[key].sizes.length > 0) {
396
- assetObj = {
397
- id: NATIVE_ASSETS.IMAGE.ID,
398
- required: params[key].required ? 1 : 0,
399
- img: {
400
- type: NATIVE_ASSET_IMAGE_TYPE.IMAGE,
401
- w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
402
- h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
403
- wmin: params[key].wmin || params[key].minimumWidth || (params[key].minsizes ? params[key].minsizes[0] : UNDEFINED),
404
- hmin: params[key].hmin || params[key].minimumHeight || (params[key].minsizes ? params[key].minsizes[1] : UNDEFINED),
405
- mimes: params[key].mimes,
406
- ext: params[key].ext,
407
- }
408
- };
409
- } else {
410
- logWarn(LOG_WARN_PREFIX + 'Error: Image sizes is required for native ad: ' + JSON.stringify(params));
411
- }
395
+ assetObj = {
396
+ id: NATIVE_ASSETS.IMAGE.ID,
397
+ required: params[key].required ? 1 : 0,
398
+ img: {
399
+ type: NATIVE_ASSET_IMAGE_TYPE.IMAGE,
400
+ w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
401
+ h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
402
+ wmin: params[key].wmin || params[key].minimumWidth || (params[key].minsizes ? params[key].minsizes[0] : UNDEFINED),
403
+ hmin: params[key].hmin || params[key].minimumHeight || (params[key].minsizes ? params[key].minsizes[1] : UNDEFINED),
404
+ mimes: params[key].mimes,
405
+ ext: params[key].ext,
406
+ }
407
+ };
412
408
  break;
413
409
  case NATIVE_ASSETS.ICON.KEY:
414
- if (params[key].sizes && params[key].sizes.length > 0) {
415
- assetObj = {
416
- id: NATIVE_ASSETS.ICON.ID,
417
- required: params[key].required ? 1 : 0,
418
- img: {
419
- type: NATIVE_ASSET_IMAGE_TYPE.ICON,
420
- w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
421
- h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
422
- }
423
- };
424
- } else {
425
- logWarn(LOG_WARN_PREFIX + 'Error: Icon sizes is required for native ad: ' + JSON.stringify(params));
410
+ assetObj = {
411
+ id: NATIVE_ASSETS.ICON.ID,
412
+ required: params[key].required ? 1 : 0,
413
+ img: {
414
+ type: NATIVE_ASSET_IMAGE_TYPE.ICON,
415
+ w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
416
+ h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
417
+ }
426
418
  };
427
419
  break;
428
420
  case NATIVE_ASSETS.VIDEO.KEY:
@@ -29,7 +29,7 @@ export const tripleliftAdapterSpec = {
29
29
  tlCall = tryAppendQueryString(tlCall, 'v', '$prebid.version$');
30
30
 
31
31
  if (bidderRequest && bidderRequest.refererInfo) {
32
- let referrer = bidderRequest.refererInfo.page;
32
+ let referrer = bidderRequest?.refererInfo?.topmostLocation || bidderRequest?.refererInfo?.page;
33
33
  tlCall = tryAppendQueryString(tlCall, 'referrer', referrer);
34
34
  }
35
35
 
@@ -88,13 +88,13 @@ export const USER_IDS_CONFIG = {
88
88
  atype: 1,
89
89
  getValue: function(data) {
90
90
  let value = '';
91
- if (data.DeviceID) {
92
- value = data.DeviceID.join(',');
91
+ if (data && data.ext && data.ext.DeviceID) {
92
+ value = data.ext.DeviceID;
93
93
  }
94
94
  return value;
95
95
  },
96
96
  getUidExt: function(data) {
97
- return 'DeviceID';
97
+ return data && data.ext;
98
98
  }
99
99
  },
100
100
 
@@ -418,13 +418,6 @@ export function createEidsArray(bidRequestUserId) {
418
418
  if (bidRequestUserId.hasOwnProperty(subModuleKey)) {
419
419
  if (subModuleKey === 'pubProvidedId') {
420
420
  eids = eids.concat(bidRequestUserId['pubProvidedId']);
421
- } else if (subModuleKey === 'ftrackId') {
422
- // Schema based on the return value of ftrack decode() method
423
- eids.push({
424
- atype: 1,
425
- ext: bidRequestUserId.ftrackId.ext,
426
- id: bidRequestUserId.ftrackId.uid
427
- });
428
421
  } else if (Array.isArray(bidRequestUserId[subModuleKey])) {
429
422
  bidRequestUserId[subModuleKey].forEach((config, index, arr) => {
430
423
  const eid = createEidObject(config, subModuleKey);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "7.23.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",
@@ -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
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',
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',
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;
@@ -622,7 +623,7 @@ $$PREBID_GLOBAL$$.removeAdUnit = function (adUnitCode) {
622
623
  * @alias module:pbjs.requestBids
623
624
  */
624
625
  $$PREBID_GLOBAL$$.requestBids = (function() {
625
- const delegate = hook('sync', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2, metrics } = {}) {
626
+ const delegate = hook('async', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2, metrics, defer } = {}) {
626
627
  events.emit(REQUEST_BIDS);
627
628
  const cbTimeout = timeout || config.getConfig('bidderTimeout');
628
629
  logInfo('Invoking $$PREBID_GLOBAL$$.requestBids', arguments);
@@ -630,23 +631,28 @@ $$PREBID_GLOBAL$$.requestBids = (function() {
630
631
  global: mergeDeep({}, config.getAnyConfig('ortb2') || {}, ortb2 || {}),
631
632
  bidder: Object.fromEntries(Object.entries(config.getBidderConfig()).map(([bidder, cfg]) => [bidder, cfg.ortb2]).filter(([_, ortb2]) => ortb2 != null))
632
633
  }
633
- return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics});
634
+ return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics, defer});
634
635
  }, 'requestBids');
635
636
 
636
637
  return wrapHook(delegate, function requestBids(req = {}) {
637
- // if the request does not specify adUnits, clone the global adUnit array - before
638
- // 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;
639
642
  // otherwise, if the caller goes on to use addAdUnits/removeAdUnits, any asynchronous logic
640
643
  // in any hook might see their effects.
641
- req.metrics = newMetrics();
642
- req.metrics.checkpoint('requestBids');
643
644
  let adUnits = req.adUnits || $$PREBID_GLOBAL$$.adUnits;
644
645
  req.adUnits = (isArray(adUnits) ? adUnits.slice() : [adUnits]);
645
- 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;
646
652
  });
647
653
  })();
648
654
 
649
- export const startAuction = hook('sync', function ({ bidsBackHandler, timeout: cbTimeout, adUnits, ttlBuffer, adUnitCodes, labels, auctionId, ortb2Fragments, metrics } = {}) {
655
+ export const startAuction = hook('async', function ({ bidsBackHandler, timeout: cbTimeout, adUnits, ttlBuffer, adUnitCodes, labels, auctionId, ortb2Fragments, metrics, defer } = {}) {
650
656
  const s2sBidders = getS2SBidderSet(config.getConfig('s2sConfig') || []);
651
657
  adUnits = useMetrics(metrics).measureTime('requestBids.validate', () => checkAdUnitSetup(adUnits));
652
658
 
@@ -658,85 +664,83 @@ export const startAuction = hook('sync', function ({ bidsBackHandler, timeout: c
658
664
  adUnitCodes = adUnits && adUnits.map(unit => unit.code);
659
665
  }
660
666
 
661
- return new Promise((resolve) => {
662
- function auctionDone(bids, timedOut, auctionId) {
663
- if (typeof bidsBackHandler === 'function') {
664
- try {
665
- bidsBackHandler(bids, timedOut, auctionId);
666
- } catch (e) {
667
- logError('Error executing bidsBackHandler', null, e);
668
- }
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);
669
673
  }
670
- resolve({bids, timedOut, auctionId});
671
674
  }
675
+ defer.resolve({bids, timedOut, auctionId})
676
+ }
677
+
678
+ /*
679
+ * for a given adunit which supports a set of mediaTypes
680
+ * and a given bidder which supports a set of mediaTypes
681
+ * a bidder is eligible to participate on the adunit
682
+ * if it supports at least one of the mediaTypes on the adunit
683
+ */
684
+ adUnits.forEach(adUnit => {
685
+ // get the adunit's mediaTypes, defaulting to banner if mediaTypes isn't present
686
+ const adUnitMediaTypes = Object.keys(adUnit.mediaTypes || { 'banner': 'banner' });
672
687
 
673
- /*
674
- * for a given adunit which supports a set of mediaTypes
675
- * and a given bidder which supports a set of mediaTypes
676
- * a bidder is eligible to participate on the adunit
677
- * if it supports at least one of the mediaTypes on the adunit
678
- */
679
- adUnits.forEach(adUnit => {
680
- // get the adunit's mediaTypes, defaulting to banner if mediaTypes isn't present
681
- const adUnitMediaTypes = Object.keys(adUnit.mediaTypes || { 'banner': 'banner' });
682
-
683
- // get the bidder's mediaTypes
684
- const allBidders = adUnit.bids.map(bid => bid.bidder);
685
- const bidderRegistry = adapterManager.bidderRegistry;
686
-
687
- const bidders = allBidders.filter(bidder => !s2sBidders.has(bidder));
688
-
689
- const tid = adUnit.ortb2Imp?.ext?.tid || generateUUID();
690
- adUnit.transactionId = tid;
691
- if (ttlBuffer != null && !adUnit.hasOwnProperty('ttlBuffer')) {
692
- adUnit.ttlBuffer = ttlBuffer;
688
+ // get the bidder's mediaTypes
689
+ const allBidders = adUnit.bids.map(bid => bid.bidder);
690
+ const bidderRegistry = adapterManager.bidderRegistry;
691
+
692
+ const bidders = allBidders.filter(bidder => !s2sBidders.has(bidder));
693
+
694
+ const tid = adUnit.ortb2Imp?.ext?.tid || generateUUID();
695
+ adUnit.transactionId = tid;
696
+ if (ttlBuffer != null && !adUnit.hasOwnProperty('ttlBuffer')) {
697
+ adUnit.ttlBuffer = ttlBuffer;
698
+ }
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.
700
+ deepSetValue(adUnit, 'ortb2Imp.ext.tid', tid);
701
+
702
+ bidders.forEach(bidder => {
703
+ const adapter = bidderRegistry[bidder];
704
+ const spec = adapter && adapter.getSpec && adapter.getSpec();
705
+ // banner is default if not specified in spec
706
+ const bidderMediaTypes = (spec && spec.supportedMediaTypes) || ['banner'];
707
+
708
+ // check if the bidder's mediaTypes are not in the adUnit's mediaTypes
709
+ const bidderEligible = adUnitMediaTypes.some(type => includes(bidderMediaTypes, type));
710
+ if (!bidderEligible) {
711
+ // drop the bidder from the ad unit if it's not compatible
712
+ logWarn(unsupportedBidderMessage(adUnit, bidder));
713
+ adUnit.bids = adUnit.bids.filter(bid => bid.bidder !== bidder);
714
+ } else {
715
+ adunitCounter.incrementBidderRequestsCounter(adUnit.code, bidder);
693
716
  }
694
- // 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.
695
- deepSetValue(adUnit, 'ortb2Imp.ext.tid', tid);
696
-
697
- bidders.forEach(bidder => {
698
- const adapter = bidderRegistry[bidder];
699
- const spec = adapter && adapter.getSpec && adapter.getSpec();
700
- // banner is default if not specified in spec
701
- const bidderMediaTypes = (spec && spec.supportedMediaTypes) || ['banner'];
702
-
703
- // check if the bidder's mediaTypes are not in the adUnit's mediaTypes
704
- const bidderEligible = adUnitMediaTypes.some(type => includes(bidderMediaTypes, type));
705
- if (!bidderEligible) {
706
- // drop the bidder from the ad unit if it's not compatible
707
- logWarn(unsupportedBidderMessage(adUnit, bidder));
708
- adUnit.bids = adUnit.bids.filter(bid => bid.bidder !== bidder);
709
- } else {
710
- adunitCounter.incrementBidderRequestsCounter(adUnit.code, bidder);
711
- }
712
- });
713
- adunitCounter.incrementRequestsCounter(adUnit.code);
714
717
  });
718
+ adunitCounter.incrementRequestsCounter(adUnit.code);
719
+ });
715
720
 
716
- if (!adUnits || adUnits.length === 0) {
717
- logMessage('No adUnits configured. No bids requested.');
718
- auctionDone();
719
- } else {
720
- const auction = auctionManager.createAuction({
721
- adUnits,
722
- adUnitCodes,
723
- callback: auctionDone,
724
- cbTimeout,
725
- labels,
726
- auctionId,
727
- ortb2Fragments,
728
- metrics,
729
- });
730
-
731
- let adUnitsLen = adUnits.length;
732
- if (adUnitsLen > 15) {
733
- logInfo(`Current auction ${auction.getAuctionId()} contains ${adUnitsLen} adUnits.`, adUnits);
734
- }
721
+ if (!adUnits || adUnits.length === 0) {
722
+ logMessage('No adUnits configured. No bids requested.');
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
+ });
735
735
 
736
- adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId()));
737
- auction.callBids();
736
+ let adUnitsLen = adUnits.length;
737
+ if (adUnitsLen > 15) {
738
+ logInfo(`Current auction ${auction.getAuctionId()} contains ${adUnitsLen} adUnits.`, adUnits);
738
739
  }
739
- });
740
+
741
+ adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId()));
742
+ auction.callBids();
743
+ }
740
744
  }, 'startAuction');
741
745
 
742
746
  export function executeCallbacks(fn, reqBidsConfigObj) {
@@ -1641,6 +1641,15 @@ describe('auctionmanager.js', function () {
1641
1641
  });
1642
1642
  });
1643
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
+
1644
1653
  it('addBidResponse hooks should not be able to reject the same bid twice', () => {
1645
1654
  cbs.addBidResponse(AU_CODE, bid);
1646
1655
  expect(auction.addBidRejected.calledOnce).to.be.true;
@@ -0,0 +1,46 @@
1
+ import {expect} from 'chai';
2
+ import {spec, storage} from 'modules/admaticBidAdapter.js';
3
+ import {newBidder} from 'src/adapters/bidderFactory.js';
4
+ import {getStorageManager} from 'src/storageManager';
5
+
6
+ const ENDPOINT = 'https://layer.serve.admatic.com.tr/v1';
7
+
8
+ describe('admaticBidAdapter', () => {
9
+ const adapter = newBidder(spec);
10
+
11
+ describe('inherited functions', () => {
12
+ it('exists and is a function', () => {
13
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
14
+ });
15
+ });
16
+
17
+ describe('isBidRequestValid', function() {
18
+ let bid = {
19
+ 'bidder': 'admatic',
20
+ 'params': {
21
+ 'networkId': 10433394
22
+ },
23
+ 'adUnitCode': 'adunit-code',
24
+ 'sizes': [[300, 250], [300, 600]],
25
+ 'bidId': '30b31c1838de1e',
26
+ 'bidderRequestId': '22edbae2733bf6',
27
+ 'auctionId': '1d1a030790a475',
28
+ 'creativeId': 'er2ee'
29
+ };
30
+
31
+ it('should return true when required params found', function() {
32
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
33
+ });
34
+
35
+ it('should return false when required params are not passed', function() {
36
+ let bid = Object.assign({}, bid);
37
+ delete bid.params;
38
+
39
+ bid.params = {
40
+ 'networkId': 0
41
+ };
42
+
43
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
44
+ });
45
+ });
46
+ });