prebid.js 6.5.0 → 6.9.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.
- package/.eslintrc.js +8 -1
- package/integrationExamples/gpt/amp/creative.html +11 -33
- package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
- package/integrationExamples/gpt/x-domain/creative.html +63 -29
- package/modules/.submodules.json +2 -1
- package/modules/adagioBidAdapter.js +0 -8
- package/modules/adagioBidAdapter.md +1 -1
- package/modules/adbookpspBidAdapter.js +27 -10
- package/modules/adhashBidAdapter.js +3 -3
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/admanBidAdapter.js +10 -4
- package/modules/adomikAnalyticsAdapter.js +23 -11
- package/modules/adqueryIdSystem.js +103 -0
- package/modules/adqueryIdSystem.md +35 -0
- package/modules/appnexusBidAdapter.js +14 -2
- package/modules/asealBidAdapter.js +58 -0
- package/modules/asealBidAdapter.md +52 -0
- package/modules/bliinkBidAdapter.js +2 -1
- package/modules/brandmetricsRtdProvider.js +168 -0
- package/modules/brandmetricsRtdProvider.md +40 -0
- package/modules/colossussspBidAdapter.js +12 -8
- package/modules/colossussspBidAdapter.md +15 -1
- package/modules/compassBidAdapter.js +10 -3
- package/modules/consumableBidAdapter.md +1 -1
- package/modules/conversantBidAdapter.js +7 -0
- package/modules/criteoBidAdapter.js +10 -1
- package/modules/criteoIdSystem.js +29 -7
- package/modules/currency.js +26 -1
- package/modules/displayioBidAdapter.js +157 -0
- package/modules/displayioBidAdapter.md +148 -0
- package/modules/e_volutionBidAdapter.js +158 -0
- package/modules/glimpseBidAdapter.js +66 -44
- package/modules/gnetBidAdapter.js +3 -3
- package/modules/gnetBidAdapter.md +4 -4
- package/modules/gumgumBidAdapter.js +56 -42
- package/modules/idImportLibrary.js +45 -8
- package/modules/idImportLibrary.md +4 -0
- package/modules/improvedigitalBidAdapter.js +29 -2
- package/modules/interactiveOffersBidAdapter.js +9 -6
- package/modules/jwplayerRtdProvider.js +71 -6
- package/modules/jwplayerRtdProvider.md +27 -11
- package/modules/kargoBidAdapter.js +2 -2
- package/modules/lunamediahbBidAdapter.js +32 -4
- package/modules/nextMillenniumBidAdapter.js +3 -1
- package/modules/oguryBidAdapter.js +14 -14
- package/modules/onetagBidAdapter.js +4 -2
- package/modules/pilotxBidAdapter.js +147 -0
- package/modules/pilotxBidAdapter.md +50 -0
- package/modules/priceFloors.js +2 -1
- package/modules/proxistoreBidAdapter.js +0 -2
- package/modules/pubmaticAnalyticsAdapter.js +16 -0
- package/modules/richaudienceBidAdapter.js +10 -4
- package/modules/riseBidAdapter.js +18 -7
- package/modules/rtbhouseBidAdapter.js +14 -4
- package/modules/rtdModule/index.js +14 -15
- package/modules/rubiconAnalyticsAdapter.js +8 -2
- package/modules/seedingAllianceBidAdapter.js +3 -3
- package/modules/sharethroughBidAdapter.js +12 -17
- package/modules/showheroes-bsBidAdapter.js +13 -2
- package/modules/sortableAnalyticsAdapter.js +5 -4
- package/modules/sovrnBidAdapter.js +93 -18
- package/modules/sovrnBidAdapter.md +80 -2
- package/modules/synacormediaBidAdapter.js +31 -10
- package/modules/tappxBidAdapter.js +8 -5
- package/modules/teadsBidAdapter.js +1 -2
- package/modules/undertoneBidAdapter.js +17 -1
- package/modules/userId/eids.js +7 -1
- package/modules/userId/userId.md +8 -0
- package/modules/viewability.js +177 -0
- package/modules/viewability.md +87 -0
- package/modules/weboramaRtdProvider.js +264 -34
- package/modules/weboramaRtdProvider.md +110 -40
- package/modules/welectBidAdapter.js +106 -0
- package/modules/yahoosspBidAdapter.js +2 -0
- package/package.json +2 -1
- package/src/adRendering.js +38 -0
- package/src/adloader.js +2 -1
- package/src/auction.js +103 -73
- package/src/bidderSettings.js +69 -0
- package/src/hook.js +5 -1
- package/src/prebid.js +19 -21
- package/src/secureCreatives.js +131 -47
- package/src/targeting.js +3 -2
- package/src/utils.js +13 -10
- package/test/helpers/syncPromise.js +71 -0
- package/test/spec/auctionmanager_spec.js +179 -15
- package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
- package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
- package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
- package/test/spec/modules/admanBidAdapter_spec.js +2 -2
- package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
- package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
- package/test/spec/modules/asealBidAdapter_spec.js +144 -0
- package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
- package/test/spec/modules/compassBidAdapter_spec.js +1 -0
- package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
- package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
- package/test/spec/modules/criteoIdSystem_spec.js +6 -3
- package/test/spec/modules/currency_spec.js +21 -6
- package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
- package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
- package/test/spec/modules/eids_spec.js +15 -0
- package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
- package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
- package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
- package/test/spec/modules/idImportLibrary_spec.js +197 -10
- package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
- package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
- package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
- package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
- package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
- package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
- package/test/spec/modules/realTimeDataModule_spec.js +67 -5
- package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
- package/test/spec/modules/riseBidAdapter_spec.js +31 -5
- package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
- package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
- package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
- package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
- package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
- package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
- package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
- package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
- package/test/spec/modules/userId_spec.js +68 -19
- package/test/spec/modules/viewability_spec.js +280 -0
- package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
- package/test/spec/modules/welectBidAdapter_spec.js +211 -0
- package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
- package/test/spec/unit/core/bidderSettings_spec.js +123 -0
- package/test/spec/unit/pbjs_api_spec.js +21 -8
- package/test/spec/unit/secureCreatives_spec.js +143 -24
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { deepAccess } from '../src/utils.js';
|
|
2
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
+
|
|
4
|
+
const BIDDER_CODE = 'welect';
|
|
5
|
+
const DEFAULT_DOMAIN = 'www.welect.de';
|
|
6
|
+
|
|
7
|
+
export const spec = {
|
|
8
|
+
code: BIDDER_CODE,
|
|
9
|
+
aliases: ['wlt'],
|
|
10
|
+
gvlid: 282,
|
|
11
|
+
supportedMediaTypes: ['video'],
|
|
12
|
+
|
|
13
|
+
// short code
|
|
14
|
+
/**
|
|
15
|
+
* Determines whether or not the given bid request is valid.
|
|
16
|
+
*
|
|
17
|
+
* @param {BidRequest} bid The bid params to validate.
|
|
18
|
+
* @return boolean True if this is a valid bid, and false otherwise.
|
|
19
|
+
*/
|
|
20
|
+
isBidRequestValid: function (bid) {
|
|
21
|
+
return (
|
|
22
|
+
deepAccess(bid, 'mediaTypes.video.context') === 'instream' &&
|
|
23
|
+
!!bid.params.placementId
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Make a server request from the list of BidRequests.
|
|
28
|
+
*
|
|
29
|
+
* @param {validBidRequests[]} - an array of bids
|
|
30
|
+
* @return ServerRequest Info describing the request to the server.
|
|
31
|
+
*/
|
|
32
|
+
buildRequests: function (validBidRequests) {
|
|
33
|
+
return validBidRequests.map((bidRequest) => {
|
|
34
|
+
let rawSizes =
|
|
35
|
+
deepAccess(bidRequest, 'mediaTypes.video.playerSize') ||
|
|
36
|
+
bidRequest.sizes;
|
|
37
|
+
let size = rawSizes[0];
|
|
38
|
+
|
|
39
|
+
let domain = bidRequest.params.domain || DEFAULT_DOMAIN;
|
|
40
|
+
|
|
41
|
+
let url = `https://${domain}/api/v2/preflight/${bidRequest.params.placementId}`;
|
|
42
|
+
|
|
43
|
+
let gdprConsent = null;
|
|
44
|
+
|
|
45
|
+
if (bidRequest && bidRequest.gdprConsent) {
|
|
46
|
+
gdprConsent = {
|
|
47
|
+
gdpr_consent: {
|
|
48
|
+
gdprApplies: bidRequest.gdprConsent.gdprApplies,
|
|
49
|
+
tcString: bidRequest.gdprConsent.gdprConsent,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const data = {
|
|
55
|
+
width: size[0],
|
|
56
|
+
height: size[1],
|
|
57
|
+
bid_id: bidRequest.bidId,
|
|
58
|
+
...gdprConsent,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
url: url,
|
|
64
|
+
data: data,
|
|
65
|
+
options: {
|
|
66
|
+
contentType: 'application/json',
|
|
67
|
+
withCredentials: false,
|
|
68
|
+
crossOrigin: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
/**
|
|
74
|
+
* Unpack the response from the server into a list of bids.
|
|
75
|
+
*
|
|
76
|
+
* @param {ServerResponse} serverResponse A successful response from the server.
|
|
77
|
+
* @return {Bid[]} An array of bids which were nested inside the server.
|
|
78
|
+
*/
|
|
79
|
+
interpretResponse: function (serverResponse, bidRequest) {
|
|
80
|
+
const responseBody = serverResponse.body;
|
|
81
|
+
|
|
82
|
+
if (typeof responseBody !== 'object' || responseBody.available !== true) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const bidResponses = [];
|
|
87
|
+
const bidResponse = {
|
|
88
|
+
requestId: responseBody.bidResponse.requestId,
|
|
89
|
+
cpm: responseBody.bidResponse.cpm,
|
|
90
|
+
width: responseBody.bidResponse.width,
|
|
91
|
+
height: responseBody.bidResponse.height,
|
|
92
|
+
creativeId: responseBody.bidResponse.creativeId,
|
|
93
|
+
currency: responseBody.bidResponse.currency,
|
|
94
|
+
netRevenue: responseBody.bidResponse.netRevenue,
|
|
95
|
+
ttl: responseBody.bidResponse.ttl,
|
|
96
|
+
ad: responseBody.bidResponse.ad,
|
|
97
|
+
vastUrl: responseBody.bidResponse.vastUrl,
|
|
98
|
+
meta: {
|
|
99
|
+
advertiserDomains: responseBody.bidResponse.meta.advertiserDomains
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
bidResponses.push(bidResponse);
|
|
103
|
+
return bidResponses;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
registerBidder(spec);
|
|
@@ -6,6 +6,7 @@ import { Renderer } from '../src/Renderer.js';
|
|
|
6
6
|
|
|
7
7
|
const INTEGRATION_METHOD = 'prebid.js';
|
|
8
8
|
const BIDDER_CODE = 'yahoossp';
|
|
9
|
+
const GVLID = 25;
|
|
9
10
|
const ADAPTER_VERSION = '1.0.2';
|
|
10
11
|
const PREBID_VERSION = '$prebid.version$';
|
|
11
12
|
const DEFAULT_BID_TTL = 300;
|
|
@@ -515,6 +516,7 @@ function createRenderer(bidderRequest, bidResponse) {
|
|
|
515
516
|
|
|
516
517
|
export const spec = {
|
|
517
518
|
code: BIDDER_CODE,
|
|
519
|
+
gvlid: GVLID,
|
|
518
520
|
aliases: [],
|
|
519
521
|
supportedMediaTypes: [BANNER, VIDEO],
|
|
520
522
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prebid.js",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.0",
|
|
4
4
|
"description": "Header Bidding Management Library",
|
|
5
5
|
"main": "src/prebid.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@babel/core": "^7.8.4",
|
|
33
|
+
"@babel/eslint-parser": "^7.16.5",
|
|
33
34
|
"@babel/preset-env": "^7.8.4",
|
|
34
35
|
"@jsdevtools/coverage-istanbul-loader": "^3.0.3",
|
|
35
36
|
"@wdio/browserstack-service": "^6.1.4",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {logError} from './utils.js';
|
|
2
|
+
import events from './events.js';
|
|
3
|
+
import CONSTANTS from './constants.json';
|
|
4
|
+
|
|
5
|
+
const {AD_RENDER_FAILED, AD_RENDER_SUCCEEDED} = CONSTANTS.EVENTS;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Emit the AD_RENDER_FAILED event.
|
|
9
|
+
*
|
|
10
|
+
* @param reason one of the values in CONSTANTS.AD_RENDER_FAILED_REASON
|
|
11
|
+
* @param message failure description
|
|
12
|
+
* @param bid? bid response object that failed to render
|
|
13
|
+
* @param id? adId that failed to render
|
|
14
|
+
*/
|
|
15
|
+
export function emitAdRenderFail({ reason, message, bid, id }) {
|
|
16
|
+
const data = { reason, message };
|
|
17
|
+
if (bid) data.bid = bid;
|
|
18
|
+
if (id) data.adId = id;
|
|
19
|
+
|
|
20
|
+
logError(message);
|
|
21
|
+
events.emit(AD_RENDER_FAILED, data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Emit the AD_RENDER_SUCCEEDED event.
|
|
26
|
+
*
|
|
27
|
+
* @param doc document object that was used to `.write` the ad. Should be `null` if unavailable (e.g. for documents in
|
|
28
|
+
* a cross-origin frame).
|
|
29
|
+
* @param bid bid response object for the ad that was rendered
|
|
30
|
+
* @param id adId that was rendered.
|
|
31
|
+
*/
|
|
32
|
+
export function emitAdRenderSucceeded({ doc, bid, id }) {
|
|
33
|
+
const data = { doc };
|
|
34
|
+
if (bid) data.bid = bid;
|
|
35
|
+
if (id) data.adId = id;
|
|
36
|
+
|
|
37
|
+
events.emit(AD_RENDER_SUCCEEDED, data);
|
|
38
|
+
}
|
package/src/adloader.js
CHANGED
package/src/auction.js
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
|
|
60
60
|
import {
|
|
61
61
|
flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl, generateUUID,
|
|
62
|
-
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr
|
|
62
|
+
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr
|
|
63
63
|
} from './utils.js';
|
|
64
64
|
import { getPriceBucketString } from './cpmBucketManager.js';
|
|
65
65
|
import { getNativeTargeting } from './native.js';
|
|
@@ -72,6 +72,7 @@ import find from 'core-js-pure/features/array/find.js';
|
|
|
72
72
|
import includes from 'core-js-pure/features/array/includes.js';
|
|
73
73
|
import { OUTSTREAM } from './video.js';
|
|
74
74
|
import { VIDEO } from './mediaTypes.js';
|
|
75
|
+
import {bidderSettings} from './bidderSettings.js';
|
|
75
76
|
|
|
76
77
|
const { syncUsers } = userSync;
|
|
77
78
|
|
|
@@ -250,10 +251,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a
|
|
|
250
251
|
|
|
251
252
|
let callbacks = auctionCallbacks(auctionDone, this);
|
|
252
253
|
adapterManager.callBids(_adUnits, bidRequests, function(...args) {
|
|
253
|
-
addBidResponse.apply(
|
|
254
|
-
dispatch: callbacks.addBidResponse,
|
|
255
|
-
bidderRequest: this
|
|
256
|
-
}, args)
|
|
254
|
+
callbacks.addBidResponse.apply(this, args);
|
|
257
255
|
}, callbacks.adapterDone, {
|
|
258
256
|
request(source, origin) {
|
|
259
257
|
increment(outstandingRequests, origin);
|
|
@@ -344,6 +342,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a
|
|
|
344
342
|
addWinningBid,
|
|
345
343
|
setBidTargeting,
|
|
346
344
|
getWinningBids: () => _winningBids,
|
|
345
|
+
getAuctionStart: () => _auctionStart,
|
|
347
346
|
getTimeout: () => _timeout,
|
|
348
347
|
getAuctionId: () => _auctionId,
|
|
349
348
|
getAuctionStatus: () => _auctionStatus,
|
|
@@ -355,8 +354,12 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a
|
|
|
355
354
|
}
|
|
356
355
|
}
|
|
357
356
|
|
|
358
|
-
|
|
359
|
-
|
|
357
|
+
/**
|
|
358
|
+
* addBidResponse may return a Promise; if it does, the auction will attempt to
|
|
359
|
+
* wait for it to complete (successfully or not) before closing.
|
|
360
|
+
*/
|
|
361
|
+
export const addBidResponse = hook('sync', function(adUnitCode, bid) {
|
|
362
|
+
return this.dispatch.call(this.bidderRequest, adUnitCode, bid);
|
|
360
363
|
}, 'addBidResponse');
|
|
361
364
|
|
|
362
365
|
export const addBidderRequests = hook('sync', function(bidderRequests) {
|
|
@@ -374,6 +377,32 @@ export function auctionCallbacks(auctionDone, auctionInstance) {
|
|
|
374
377
|
let allAdapterCalledDone = false;
|
|
375
378
|
let bidderRequestsDone = new Set();
|
|
376
379
|
let bidResponseMap = {};
|
|
380
|
+
const ready = {};
|
|
381
|
+
|
|
382
|
+
function waitFor(bidderRequest, result) {
|
|
383
|
+
const id = bidderRequest.bidderRequestId;
|
|
384
|
+
if (ready[id] == null) {
|
|
385
|
+
ready[id] = Promise.resolve();
|
|
386
|
+
}
|
|
387
|
+
ready[id] = ready[id].then(() => Promise.resolve(result).catch(() => {}))
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function guard(bidderRequest, fn) {
|
|
391
|
+
let timeout = bidderRequest.timeout;
|
|
392
|
+
if (timeout == null || timeout > auctionInstance.getTimeout()) {
|
|
393
|
+
timeout = auctionInstance.getTimeout();
|
|
394
|
+
}
|
|
395
|
+
const timeRemaining = auctionInstance.getAuctionStart() + timeout - Date.now();
|
|
396
|
+
const wait = ready[bidderRequest.bidderRequestId];
|
|
397
|
+
if (wait != null && timeRemaining > 0) {
|
|
398
|
+
Promise.race([
|
|
399
|
+
new Promise((resolve) => setTimeout(resolve, timeRemaining)),
|
|
400
|
+
wait
|
|
401
|
+
]).then(fn);
|
|
402
|
+
} else {
|
|
403
|
+
fn();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
377
406
|
|
|
378
407
|
function afterBidAdded() {
|
|
379
408
|
outstandingBidsAdded--;
|
|
@@ -382,7 +411,7 @@ export function auctionCallbacks(auctionDone, auctionInstance) {
|
|
|
382
411
|
}
|
|
383
412
|
}
|
|
384
413
|
|
|
385
|
-
function
|
|
414
|
+
function handleBidResponse(adUnitCode, bid) {
|
|
386
415
|
let bidderRequest = this;
|
|
387
416
|
|
|
388
417
|
bidResponseMap[bid.requestId] = true;
|
|
@@ -429,8 +458,15 @@ export function auctionCallbacks(auctionDone, auctionInstance) {
|
|
|
429
458
|
}
|
|
430
459
|
|
|
431
460
|
return {
|
|
432
|
-
addBidResponse
|
|
433
|
-
|
|
461
|
+
addBidResponse: function (...args) {
|
|
462
|
+
waitFor(this, addBidResponse.apply({
|
|
463
|
+
dispatch: handleBidResponse,
|
|
464
|
+
bidderRequest: this
|
|
465
|
+
}, args));
|
|
466
|
+
},
|
|
467
|
+
adapterDone: function () {
|
|
468
|
+
guard(this, adapterDone.bind(this))
|
|
469
|
+
}
|
|
434
470
|
}
|
|
435
471
|
}
|
|
436
472
|
|
|
@@ -567,7 +603,7 @@ function getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}) {
|
|
|
567
603
|
|
|
568
604
|
function setupBidTargeting(bidObject, bidderRequest) {
|
|
569
605
|
let keyValues;
|
|
570
|
-
const cpmCheck = (
|
|
606
|
+
const cpmCheck = (bidderSettings.get(bidObject.bidderCode, 'allowZeroCpmBids') === true) ? bidObject.cpm >= 0 : bidObject.cpm > 0;
|
|
571
607
|
if (bidObject.bidderCode && (cpmCheck || bidObject.dealId)) {
|
|
572
608
|
let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode && bid.bidId === bidObject.requestId);
|
|
573
609
|
keyValues = getKeyValueTargetingPairs(bidObject.bidderCode, bidObject, bidReq);
|
|
@@ -615,18 +651,18 @@ export const getPriceGranularity = (mediaType, bidReq) => {
|
|
|
615
651
|
*/
|
|
616
652
|
export const getPriceByGranularity = (granularity) => {
|
|
617
653
|
return (bid, bidReq) => {
|
|
618
|
-
|
|
619
|
-
if (
|
|
654
|
+
const bidGranularity = granularity || getPriceGranularity(bid.mediaType, bidReq);
|
|
655
|
+
if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) {
|
|
620
656
|
return bid.pbAg;
|
|
621
|
-
} else if (
|
|
657
|
+
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) {
|
|
622
658
|
return bid.pbDg;
|
|
623
|
-
} else if (
|
|
659
|
+
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) {
|
|
624
660
|
return bid.pbLg;
|
|
625
|
-
} else if (
|
|
661
|
+
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) {
|
|
626
662
|
return bid.pbMg;
|
|
627
|
-
} else if (
|
|
663
|
+
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) {
|
|
628
664
|
return bid.pbHg;
|
|
629
|
-
} else if (
|
|
665
|
+
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) {
|
|
630
666
|
return bid.pbCg;
|
|
631
667
|
}
|
|
632
668
|
}
|
|
@@ -642,6 +678,34 @@ export const getAdvertiserDomain = () => {
|
|
|
642
678
|
}
|
|
643
679
|
}
|
|
644
680
|
|
|
681
|
+
// factory for key value objs
|
|
682
|
+
function createKeyVal(key, value) {
|
|
683
|
+
return {
|
|
684
|
+
key,
|
|
685
|
+
val: (typeof value === 'function')
|
|
686
|
+
? function (bidResponse, bidReq) {
|
|
687
|
+
return value(bidResponse, bidReq);
|
|
688
|
+
}
|
|
689
|
+
: function (bidResponse) {
|
|
690
|
+
return getValue(bidResponse, value);
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function defaultAdserverTargeting() {
|
|
696
|
+
const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS;
|
|
697
|
+
return [
|
|
698
|
+
createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'),
|
|
699
|
+
createKeyVal(TARGETING_KEYS.AD_ID, 'adId'),
|
|
700
|
+
createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()),
|
|
701
|
+
createKeyVal(TARGETING_KEYS.SIZE, 'size'),
|
|
702
|
+
createKeyVal(TARGETING_KEYS.DEAL, 'dealId'),
|
|
703
|
+
createKeyVal(TARGETING_KEYS.SOURCE, 'source'),
|
|
704
|
+
createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'),
|
|
705
|
+
createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()),
|
|
706
|
+
]
|
|
707
|
+
}
|
|
708
|
+
|
|
645
709
|
/**
|
|
646
710
|
* @param {string} mediaType
|
|
647
711
|
* @param {string} bidderCode
|
|
@@ -649,40 +713,16 @@ export const getAdvertiserDomain = () => {
|
|
|
649
713
|
* @returns {*}
|
|
650
714
|
*/
|
|
651
715
|
export function getStandardBidderSettings(mediaType, bidderCode) {
|
|
652
|
-
// factory for key value objs
|
|
653
|
-
function createKeyVal(key, value) {
|
|
654
|
-
return {
|
|
655
|
-
key,
|
|
656
|
-
val: (typeof value === 'function')
|
|
657
|
-
? function (bidResponse, bidReq) {
|
|
658
|
-
return value(bidResponse, bidReq);
|
|
659
|
-
}
|
|
660
|
-
: function (bidResponse) {
|
|
661
|
-
return getValue(bidResponse, value);
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
716
|
const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS;
|
|
717
|
+
const standardSettings = Object.assign({}, bidderSettings.settingsFor(null));
|
|
666
718
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD] = {};
|
|
670
|
-
}
|
|
671
|
-
if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) {
|
|
672
|
-
bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = [
|
|
673
|
-
createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'),
|
|
674
|
-
createKeyVal(TARGETING_KEYS.AD_ID, 'adId'),
|
|
675
|
-
createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()),
|
|
676
|
-
createKeyVal(TARGETING_KEYS.SIZE, 'size'),
|
|
677
|
-
createKeyVal(TARGETING_KEYS.DEAL, 'dealId'),
|
|
678
|
-
createKeyVal(TARGETING_KEYS.SOURCE, 'source'),
|
|
679
|
-
createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'),
|
|
680
|
-
createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()),
|
|
681
|
-
]
|
|
719
|
+
if (!standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) {
|
|
720
|
+
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = defaultAdserverTargeting();
|
|
682
721
|
}
|
|
683
722
|
|
|
684
723
|
if (mediaType === 'video') {
|
|
685
|
-
const adserverTargeting =
|
|
724
|
+
const adserverTargeting = standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING].slice();
|
|
725
|
+
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = adserverTargeting;
|
|
686
726
|
|
|
687
727
|
// Adding hb_uuid + hb_cache_id
|
|
688
728
|
[TARGETING_KEYS.UUID, TARGETING_KEYS.CACHE_ID].forEach(targetingKeyVal => {
|
|
@@ -692,7 +732,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) {
|
|
|
692
732
|
});
|
|
693
733
|
|
|
694
734
|
// Adding hb_cache_host
|
|
695
|
-
if (config.getConfig('cache.url') && (!bidderCode ||
|
|
735
|
+
if (config.getConfig('cache.url') && (!bidderCode || bidderSettings.get(bidderCode, 'sendStandardTargeting') !== false)) {
|
|
696
736
|
const urlInfo = parseUrl(config.getConfig('cache.url'));
|
|
697
737
|
|
|
698
738
|
if (typeof find(adserverTargeting, targetingKeyVal => targetingKeyVal.key === TARGETING_KEYS.CACHE_HOST) === 'undefined') {
|
|
@@ -703,7 +743,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) {
|
|
|
703
743
|
}
|
|
704
744
|
}
|
|
705
745
|
}
|
|
706
|
-
return
|
|
746
|
+
return standardSettings;
|
|
707
747
|
}
|
|
708
748
|
|
|
709
749
|
export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
|
|
@@ -712,19 +752,15 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
|
|
|
712
752
|
}
|
|
713
753
|
|
|
714
754
|
var keyValues = {};
|
|
715
|
-
var bidderSettings = $$PREBID_GLOBAL$$.bidderSettings;
|
|
716
755
|
|
|
717
756
|
// 1) set the keys from "standard" setting or from prebid defaults
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
setKeys(keyValues, bidderSettings[bidderCode], custBidObj, bidReq);
|
|
726
|
-
custBidObj.sendStandardTargeting = bidderSettings[bidderCode].sendStandardTargeting;
|
|
727
|
-
}
|
|
757
|
+
const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode);
|
|
758
|
+
setKeys(keyValues, standardSettings, custBidObj, bidReq);
|
|
759
|
+
|
|
760
|
+
// 2) set keys from specific bidder setting override if they exist
|
|
761
|
+
if (bidderCode && bidderSettings.getOwn(bidderCode, CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING)) {
|
|
762
|
+
setKeys(keyValues, bidderSettings.ownSettingsFor(bidderCode), custBidObj, bidReq);
|
|
763
|
+
custBidObj.sendStandardTargeting = bidderSettings.get(bidderCode, 'sendStandardTargeting');
|
|
728
764
|
}
|
|
729
765
|
|
|
730
766
|
// set native key value targeting
|
|
@@ -776,19 +812,13 @@ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) {
|
|
|
776
812
|
export function adjustBids(bid) {
|
|
777
813
|
let code = bid.bidderCode;
|
|
778
814
|
let bidPriceAdjusted = bid.cpm;
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if (bidCpmAdjustment) {
|
|
787
|
-
try {
|
|
788
|
-
bidPriceAdjusted = bidCpmAdjustment(bid.cpm, Object.assign({}, bid));
|
|
789
|
-
} catch (e) {
|
|
790
|
-
logError('Error during bid adjustment', 'bidmanager.js', e);
|
|
791
|
-
}
|
|
815
|
+
const bidCpmAdjustment = bidderSettings.get(code || null, 'bidCpmAdjustment');
|
|
816
|
+
|
|
817
|
+
if (bidCpmAdjustment && typeof bidCpmAdjustment === 'function') {
|
|
818
|
+
try {
|
|
819
|
+
bidPriceAdjusted = bidCpmAdjustment(bid.cpm, Object.assign({}, bid));
|
|
820
|
+
} catch (e) {
|
|
821
|
+
logError('Error during bid adjustment', 'bidmanager.js', e);
|
|
792
822
|
}
|
|
793
823
|
}
|
|
794
824
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {deepAccess, mergeDeep} from './utils.js';
|
|
2
|
+
import {getGlobal} from './prebidGlobal.js';
|
|
3
|
+
|
|
4
|
+
const CONSTANTS = require('./constants.json');
|
|
5
|
+
|
|
6
|
+
export class ScopedSettings {
|
|
7
|
+
constructor(getSettings, defaultScope) {
|
|
8
|
+
this.getSettings = getSettings;
|
|
9
|
+
this.defaultScope = defaultScope;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get setting value at `path` under the given scope, falling back to the default scope if needed.
|
|
14
|
+
* If `scope` is `null`, get the setting's default value.
|
|
15
|
+
* @param scope {String|null}
|
|
16
|
+
* @param path {String}
|
|
17
|
+
* @returns {*}
|
|
18
|
+
*/
|
|
19
|
+
get(scope, path) {
|
|
20
|
+
let value = this.getOwn(scope, path);
|
|
21
|
+
if (typeof value === 'undefined') {
|
|
22
|
+
value = this.getOwn(null, path);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the setting value at `path` *without* falling back to the default value.
|
|
29
|
+
* @param scope {String}
|
|
30
|
+
* @param path {String}
|
|
31
|
+
* @returns {*}
|
|
32
|
+
*/
|
|
33
|
+
getOwn(scope, path) {
|
|
34
|
+
scope = this.#resolveScope(scope);
|
|
35
|
+
return deepAccess(this.getSettings(), `${scope}.${path}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @returns {string[]} all existing scopes except the default one.
|
|
40
|
+
*/
|
|
41
|
+
getScopes() {
|
|
42
|
+
return Object.keys(this.getSettings()).filter((scope) => scope !== this.defaultScope);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @returns all settings in the given scope, merged with the settings for the default scope.
|
|
47
|
+
*/
|
|
48
|
+
settingsFor(scope) {
|
|
49
|
+
return mergeDeep({}, this.ownSettingsFor(null), this.ownSettingsFor(scope));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @returns all settings in the given scope, *without* any of the default settings.
|
|
54
|
+
*/
|
|
55
|
+
ownSettingsFor(scope) {
|
|
56
|
+
scope = this.#resolveScope(scope);
|
|
57
|
+
return this.getSettings()[scope] || {};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#resolveScope(scope) {
|
|
61
|
+
if (scope == null) {
|
|
62
|
+
return this.defaultScope;
|
|
63
|
+
} else {
|
|
64
|
+
return scope;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const bidderSettings = new ScopedSettings(() => getGlobal().bidderSettings || {}, CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD);
|
package/src/hook.js
CHANGED
|
@@ -13,14 +13,18 @@ export function setupBeforeHookFnOnce(baseFn, hookFn, priority = 15) {
|
|
|
13
13
|
baseFn.before(hookFn, priority);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
const submoduleInstallMap = {};
|
|
16
17
|
|
|
17
|
-
export function module(name, install) {
|
|
18
|
+
export function module(name, install, {postInstallAllowed = false} = {}) {
|
|
18
19
|
hook('async', function (submodules) {
|
|
19
20
|
submodules.forEach(args => install(...args));
|
|
21
|
+
if (postInstallAllowed) submoduleInstallMap[name] = install;
|
|
20
22
|
}, name)([]); // will be queued until hook.ready() called in pbjs.processQueue();
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export function submodule(name, ...args) {
|
|
26
|
+
const install = submoduleInstallMap[name];
|
|
27
|
+
if (install) return install(...args);
|
|
24
28
|
getHook(name).before((next, modules) => {
|
|
25
29
|
modules.push(args);
|
|
26
30
|
next(modules);
|
package/src/prebid.js
CHANGED
|
@@ -19,6 +19,7 @@ import { adunitCounter } from './adUnits.js';
|
|
|
19
19
|
import { executeRenderer, isRendererRequired } from './Renderer.js';
|
|
20
20
|
import { createBid } from './bidfactory.js';
|
|
21
21
|
import { storageCallbacks } from './storageManager.js';
|
|
22
|
+
import { emitAdRenderSucceeded, emitAdRenderFail } from './adRendering.js';
|
|
22
23
|
|
|
23
24
|
const $$PREBID_GLOBAL$$ = getGlobal();
|
|
24
25
|
const CONSTANTS = require('./constants.json');
|
|
@@ -27,7 +28,7 @@ const events = require('./events.js');
|
|
|
27
28
|
const { triggerUserSyncs } = userSync;
|
|
28
29
|
|
|
29
30
|
/* private variables */
|
|
30
|
-
const { ADD_AD_UNITS, BID_WON, REQUEST_BIDS, SET_TARGETING,
|
|
31
|
+
const { ADD_AD_UNITS, BID_WON, REQUEST_BIDS, SET_TARGETING, STALE_RENDER } = CONSTANTS.EVENTS;
|
|
31
32
|
const { PREVENT_WRITING_ON_MAIN_DOCUMENT, NO_AD, EXCEPTION, CANNOT_FIND_AD, MISSING_DOC_OR_ADID } = CONSTANTS.AD_RENDER_FAILED_REASON;
|
|
32
33
|
|
|
33
34
|
const eventValidators = {
|
|
@@ -146,7 +147,7 @@ function validateNativeMediaType(adUnit) {
|
|
|
146
147
|
function validateAdUnitPos(adUnit, mediaType) {
|
|
147
148
|
let pos = deepAccess(adUnit, `mediaTypes.${mediaType}.pos`);
|
|
148
149
|
|
|
149
|
-
if (!pos ||
|
|
150
|
+
if (!isNumber(pos) || isNaN(pos) || !isFinite(pos)) {
|
|
150
151
|
let warning = `Value of property 'pos' on ad unit ${adUnit.code} should be of type: Number`;
|
|
151
152
|
|
|
152
153
|
logWarn(warning);
|
|
@@ -385,27 +386,23 @@ $$PREBID_GLOBAL$$.setTargetingForAst = function (adUnitCodes) {
|
|
|
385
386
|
events.emit(SET_TARGETING, targeting.getAllTargeting());
|
|
386
387
|
};
|
|
387
388
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (bid) data.bid = bid;
|
|
400
|
-
if (id) data.adId = id;
|
|
401
|
-
|
|
402
|
-
events.emit(AD_RENDER_SUCCEEDED, data);
|
|
389
|
+
/**
|
|
390
|
+
* This function will check for presence of given node in given parent. If not present - will inject it.
|
|
391
|
+
* @param {Node} node node, whose existance is in question
|
|
392
|
+
* @param {Document} doc document element do look in
|
|
393
|
+
* @param {string} tagName tag name to look in
|
|
394
|
+
*/
|
|
395
|
+
function reinjectNodeIfRemoved(node, doc, tagName) {
|
|
396
|
+
const injectionNode = doc.querySelector(tagName);
|
|
397
|
+
if (!node.parentNode || node.parentNode !== injectionNode) {
|
|
398
|
+
insertElement(node, doc, tagName);
|
|
399
|
+
}
|
|
403
400
|
}
|
|
404
401
|
|
|
405
402
|
/**
|
|
406
403
|
* This function will render the ad (based on params) in the given iframe document passed through.
|
|
407
404
|
* Note that doc SHOULD NOT be the parent document page as we can't doc.write() asynchronously
|
|
408
|
-
* @param {
|
|
405
|
+
* @param {Document} doc document
|
|
409
406
|
* @param {string} id bid id to locate the ad
|
|
410
407
|
* @alias module:pbjs.renderAd
|
|
411
408
|
*/
|
|
@@ -449,10 +446,11 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
449
446
|
const {height, width, ad, mediaType, adUrl, renderer} = bid;
|
|
450
447
|
|
|
451
448
|
const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`);
|
|
449
|
+
insertElement(creativeComment, doc, 'html');
|
|
452
450
|
|
|
453
451
|
if (isRendererRequired(renderer)) {
|
|
454
452
|
executeRenderer(renderer, bid);
|
|
455
|
-
|
|
453
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
456
454
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
457
455
|
} else if ((doc === document && !inIframe()) || mediaType === 'video') {
|
|
458
456
|
const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
|
|
@@ -471,7 +469,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
471
469
|
doc.write(ad);
|
|
472
470
|
doc.close();
|
|
473
471
|
setRenderSize(doc, width, height);
|
|
474
|
-
|
|
472
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
475
473
|
callBurl(bid);
|
|
476
474
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
477
475
|
} else if (adUrl) {
|
|
@@ -484,7 +482,7 @@ $$PREBID_GLOBAL$$.renderAd = hook('async', function (doc, id, options) {
|
|
|
484
482
|
|
|
485
483
|
insertElement(iframe, doc, 'body');
|
|
486
484
|
setRenderSize(doc, width, height);
|
|
487
|
-
|
|
485
|
+
reinjectNodeIfRemoved(creativeComment, doc, 'html');
|
|
488
486
|
callBurl(bid);
|
|
489
487
|
emitAdRenderSucceeded({ doc, bid, id });
|
|
490
488
|
} else {
|