Skip to content

Commit 9fd4dfd

Browse files
Merge branch 'prebid:master' into master
2 parents 9e78e60 + 16c0bdd commit 9fd4dfd

50 files changed

Lines changed: 1328 additions & 844 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,6 @@ typings/
8383

8484
# MacOS system files
8585
.DS_Store
86+
87+
# Webpack cache
88+
.cache/

libraries/advangUtils/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { deepAccess, generateUUID, isFn, parseSizesInput, parseUrl } from '../../src/utils.js';
22
import { config } from '../../src/config.js';
3-
import { find, includes } from '../../src/polyfill.js';
3+
import { find } from '../../src/polyfill.js';
44

55
export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
66

@@ -115,12 +115,12 @@ export function getVideoTargetingParams(bid, VIDEO_TARGETING) {
115115
const result = {};
116116
const excludeProps = ['playerSize', 'context', 'w', 'h'];
117117
Object.keys(Object(bid.mediaTypes.video))
118-
.filter(key => !includes(excludeProps, key))
118+
.filter(key => !excludeProps.includes(key))
119119
.forEach(key => {
120120
result[ key ] = bid.mediaTypes.video[ key ];
121121
});
122122
Object.keys(Object(bid.params.video))
123-
.filter(key => includes(VIDEO_TARGETING, key))
123+
.filter(key => VIDEO_TARGETING.includes(key))
124124
.forEach(key => {
125125
result[ key ] = bid.params.video[ key ];
126126
});

libraries/blueUtils/bidderUtils.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { isFn, isPlainObject, deepSetValue, replaceAuctionPrice, triggerPixel } from '../../src/utils.js';
2+
3+
export function getBidFloor(bid, mediaType, defaultCurrency) {
4+
if (isFn(bid.getFloor)) {
5+
let floor = bid.getFloor({
6+
currency: defaultCurrency,
7+
mediaType: mediaType,
8+
size: '*',
9+
});
10+
if (
11+
isPlainObject(floor) &&
12+
!isNaN(floor.floor) &&
13+
floor.currency === defaultCurrency
14+
) {
15+
return floor.floor;
16+
}
17+
}
18+
return null;
19+
}
20+
21+
export function buildOrtbRequest(bidRequests, bidderRequest, context, gvlid, ortbConverterInstance) {
22+
const ortbRequest = ortbConverterInstance.toORTB({ bidRequests, bidderRequest, context });
23+
ortbRequest.ext = ortbRequest.ext || {};
24+
deepSetValue(ortbRequest, 'ext.gvlid', gvlid);
25+
return ortbRequest;
26+
}
27+
28+
export function ortbConverterRequest(buildRequest, imps, bidderRequest, context) {
29+
let request = buildRequest(imps, bidderRequest, context);
30+
deepSetValue(request, 'site.publisher.id', context.publisherId);
31+
return request;
32+
}
33+
34+
export function ortbConverterImp(buildImp, bidRequest, context) {
35+
let imp = buildImp(bidRequest, context);
36+
// context.mediaTypes is expected to be set by the adapter calling this function
37+
const floor = getBidFloor(bidRequest, context.mediaTypes.banner, context.mediaTypes.defaultCurrency);
38+
imp.tagid = bidRequest.params.placementId;
39+
40+
if (floor) {
41+
imp.bidfloor = floor;
42+
imp.bidfloorcur = context.mediaTypes.defaultCurrency;
43+
}
44+
45+
return imp;
46+
}
47+
48+
export function buildBidObjectBase(bid, serverResponseBody, bidderCode, defaultCurrency) {
49+
return {
50+
ad: replaceAuctionPrice(bid.adm, bid.price),
51+
adapterCode: bidderCode,
52+
cpm: bid.price,
53+
currency: serverResponseBody.cur || defaultCurrency,
54+
deferBilling: false,
55+
deferRendering: false,
56+
width: bid.w,
57+
height: bid.h,
58+
mediaType: bid.ext?.mediaType || 'banner',
59+
netRevenue: true,
60+
originalCpm: bid.price,
61+
originalCurrency: serverResponseBody.cur || defaultCurrency,
62+
requestId: bid.impid,
63+
seatBidId: bid.id
64+
};
65+
}
66+
67+
export function commonOnBidWonHandler(bid, processUrl = (url, bidData) => url) {
68+
const { burl, nurl } = bid || {};
69+
70+
if (nurl) {
71+
triggerPixel(processUrl(nurl, bid));
72+
}
73+
74+
if (burl) {
75+
triggerPixel(processUrl(burl, bid));
76+
}
77+
}
78+
79+
export function commonIsBidRequestValid(bid) {
80+
return !!bid.params.placementId && !!bid.params.publisherId;
81+
}
82+
83+
export function createOrtbConverter(ortbConverterFunc, bannerMediaType, defaultCurrencyConst, impFunc, requestFunc) {
84+
return ortbConverterFunc({
85+
context: {
86+
netRevenue: true,
87+
ttl: 100,
88+
mediaTypes: {
89+
banner: bannerMediaType,
90+
defaultCurrency: defaultCurrencyConst
91+
}
92+
},
93+
imp: impFunc,
94+
request: requestFunc,
95+
});
96+
}
97+
98+
export function getPublisherIdFromBids(validBidRequests) {
99+
return validBidRequests.find(
100+
(bidRequest) => bidRequest.params?.publisherId
101+
)?.params.publisherId;
102+
}
103+
104+
export function packageOrtbRequest(ortbRequest, endpointUrl, dataProcessor, requestOptions) {
105+
return [
106+
{
107+
method: 'POST',
108+
url: endpointUrl,
109+
data: dataProcessor(ortbRequest),
110+
options: requestOptions,
111+
}
112+
];
113+
}

libraries/liveIntentId/shared.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ export function setUpTreatment(config) {
160160

161161
export const eids = {
162162
...UID1_EIDS,
163+
tdid: {
164+
...UID1_EIDS.tdid,
165+
matcher: LI_PROVIDER_DOMAIN
166+
},
163167
...UID2_EIDS,
164168
'lipb': {
165169
getValue: function(data) {

libraries/xeUtils/bidderUtils.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {deepAccess, getBidIdParameter, isFn, logError, isArray, parseSizesInput, isPlainObject} from '../../src/utils.js';
22
import {getAdUnitSizes} from '../sizeUtils/sizeUtils.js';
3-
import {findIndex} from '../../src/polyfill.js';
43

54
export function getBidFloor(bid, currency = 'USD') {
65
if (!isFn(bid.getFloor)) {
@@ -114,9 +113,9 @@ export function interpretResponse(serverResponse, {bidderRequest}) {
114113
}
115114

116115
serverResponse.body.data.forEach(serverBid => {
117-
const bidIndex = findIndex(bidderRequest.bids, (bidRequest) => {
118-
return bidRequest.bidId === serverBid.requestId;
119-
});
116+
const bidIndex = Array.isArray(bidderRequest.bids)
117+
? bidderRequest.bids.findIndex(bidRequest => bidRequest.bidId === serverBid.requestId)
118+
: undefined;
120119

121120
if (bidIndex !== -1) {
122121
const bid = {

modules/adagioBidAdapter.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { Renderer } from '../src/Renderer.js';
2121
import { _ADAGIO } from '../libraries/adagioUtils/adagioUtils.js';
2222
import { config } from '../src/config.js';
2323
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
24-
import { find } from '../src/polyfill.js';
2524
import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js';
2625
import { registerBidder } from '../src/adapters/bidderFactory.js';
2726
import { userSync } from '../src/userSync.js';
@@ -757,7 +756,7 @@ export const spec = {
757756
}
758757
if (response.bids) {
759758
response.bids.forEach(bidObj => {
760-
const bidReq = (find(bidRequest.data.adUnits, bid => bid.bidId === bidObj.requestId));
759+
const bidReq = bidRequest.data.adUnits.find(bid => bid.bidId === bidObj.requestId);
761760

762761
if (bidReq) {
763762
// bidObj.meta is the `bidResponse.meta` object according to https://docs.prebid.org/dev-docs/bidder-adaptor.html#interpreting-the-response

modules/adverxoBidAdapter.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ const adverxoUtils = {
181181
bidRequests.forEach(bidRequest => {
182182
const adUnit = {
183183
host: bidRequest.params.host,
184-
id: bidRequest.params.adUnitId,
184+
id: Number(bidRequest.params.adUnitId),
185185
auth: bidRequest.params.auth,
186186
};
187187

@@ -229,8 +229,8 @@ export const spec = {
229229
return false;
230230
}
231231

232-
if (!bid.params.adUnitId || typeof bid.params.adUnitId !== 'number') {
233-
utils.logWarn('Adverxo Bid Adapter: adUnitId bid param is required and must be a number');
232+
if (!bid.params.adUnitId || isNaN(Number(bid.params.adUnitId)) || bid.params.adUnitId <= 0) {
233+
utils.logWarn('Adverxo Bid Adapter: adUnitId bid param is required and must be a positive number');
234234
return false;
235235
}
236236

modules/blueBidAdapter.js

Lines changed: 24 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ import { ortbConverter } from '../libraries/ortbConverter/converter.js';
22
import { registerBidder } from '../src/adapters/bidderFactory.js';
33
import { BANNER } from '../src/mediaTypes.js';
44
import { getStorageManager } from '../src/storageManager.js';
5+
import {
6+
buildOrtbRequest,
7+
ortbConverterRequest,
8+
ortbConverterImp,
9+
buildBidObjectBase,
10+
commonOnBidWonHandler,
11+
commonIsBidRequestValid,
12+
createOrtbConverter,
13+
getPublisherIdFromBids,
14+
packageOrtbRequest
15+
} from '../libraries/blueUtils/bidderUtils.js';
516
import {
617
replaceAuctionPrice,
7-
isFn,
8-
isPlainObject,
9-
deepSetValue,
10-
isEmpty,
11-
triggerPixel,
18+
isEmpty
1219
} from '../src/utils.js';
1320
const BIDDER_CODE = 'blue';
1421
const ENDPOINT_URL = 'https://bidder-us-east-1.getblue.io/engine/?src=prebid';
@@ -17,90 +24,27 @@ const DEFAULT_CURRENCY = 'USD';
1724

1825
export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
1926

20-
function getBidFloor(bid) {
21-
if (isFn(bid.getFloor)) {
22-
let floor = bid.getFloor({
23-
currency: DEFAULT_CURRENCY,
24-
mediaType: BANNER,
25-
size: '*',
26-
});
27-
if (
28-
isPlainObject(floor) &&
29-
!isNaN(floor.floor) &&
30-
floor.currency === DEFAULT_CURRENCY
31-
) {
32-
return floor.floor;
33-
}
34-
}
35-
return null;
36-
}
37-
38-
const converter = ortbConverter({
39-
context: {
40-
netRevenue: true, // Default netRevenue setting
41-
ttl: 100, // Default time-to-live for bid responses
42-
},
43-
imp,
44-
request,
45-
});
46-
47-
function request(buildRequest, imps, bidderRequest, context) {
48-
let request = buildRequest(imps, bidderRequest, context);
49-
deepSetValue(request, 'site.publisher.id', context.publisherId);
50-
return request;
51-
}
52-
53-
function imp(buildImp, bidRequest, context) {
54-
let imp = buildImp(bidRequest, context);
55-
const floor = getBidFloor(bidRequest);
56-
imp.tagid = bidRequest.params.placementId;
57-
58-
if (floor) {
59-
imp.bidfloor = floor;
60-
imp.bidfloorcur = DEFAULT_CURRENCY;
61-
}
62-
63-
return imp;
64-
}
27+
const converter = createOrtbConverter(ortbConverter, BANNER, DEFAULT_CURRENCY, ortbConverterImp, ortbConverterRequest);
6528

6629
export const spec = {
6730
code: BIDDER_CODE,
6831
gvlid: GVLID,
6932
supportedMediaTypes: [BANNER],
7033

7134
// Validate bid request
72-
isBidRequestValid: function (bid) {
73-
return !!bid.params.placementId && !!bid.params.publisherId;
74-
},
35+
isBidRequestValid: commonIsBidRequestValid,
7536

7637
// Build OpenRTB requests using `ortbConverter`
7738
buildRequests: function (validBidRequests, bidderRequest) {
7839
const context = {
79-
publisherId: validBidRequests.find(
80-
(bidRequest) => bidRequest.params?.publisherId
81-
)?.params.publisherId,
40+
publisherId: getPublisherIdFromBids(validBidRequests),
8241
};
42+
const ortbRequestData = buildOrtbRequest(validBidRequests, bidderRequest, context, GVLID, converter);
8343

84-
const ortbRequest = converter.toORTB({
85-
bidRequests: validBidRequests,
86-
bidderRequest,
87-
context,
88-
});
89-
90-
// Add extensions to the request
91-
ortbRequest.ext = ortbRequest.ext || {};
92-
deepSetValue(ortbRequest, 'ext.gvlid', GVLID);
44+
const blueDataProcessor = (data) => data;
45+
const blueOptions = { contentType: 'application/json' };
9346

94-
return [
95-
{
96-
method: 'POST',
97-
url: ENDPOINT_URL,
98-
data: ortbRequest,
99-
options: {
100-
contentType: 'application/json',
101-
},
102-
},
103-
];
47+
return packageOrtbRequest(ortbRequestData, ENDPOINT_URL, blueDataProcessor, blueOptions);
10448
},
10549

10650
interpretResponse: (serverResponse) => {
@@ -109,41 +53,17 @@ export const spec = {
10953
let bids = [];
11054
serverResponse.body.seatbid.forEach((response) => {
11155
response.bid.forEach((bid) => {
112-
const mediaType = bid.ext?.mediaType || 'banner';
113-
bids.push({
114-
ad: replaceAuctionPrice(bid.adm, bid.price),
115-
adapterCode: BIDDER_CODE,
116-
cpm: bid.price,
117-
creativeId: bid.ext.blue.adId,
118-
creative_id: bid.ext.blue.adId,
119-
currency: serverResponse.body.cur || 'USD',
120-
deferBilling: false,
121-
deferRendering: false,
122-
width: bid.w,
123-
height: bid.h,
124-
mediaType,
125-
netRevenue: true,
126-
originalCpm: bid.price,
127-
originalCurrency: serverResponse.body.cur || 'USD',
128-
requestId: bid.impid,
129-
seatBidId: bid.id,
130-
ttl: 1200,
131-
});
56+
const baseBid = buildBidObjectBase(bid, serverResponse.body, BIDDER_CODE, DEFAULT_CURRENCY);
57+
const blueSpecific = { creativeId: bid.ext.blue.adId, creative_id: bid.ext.blue.adId, ttl: 1200 };
58+
bids.push({ ...baseBid, ...blueSpecific });
13259
});
13360
});
13461
return bids;
13562
},
13663

13764
onBidWon: function (bid) {
138-
const { burl, nurl } = bid || {};
139-
140-
if (nurl) {
141-
triggerPixel(replaceAuctionPrice(nurl, bid.originalCpm || bid.cpm));
142-
}
143-
144-
if (burl) {
145-
triggerPixel(replaceAuctionPrice(burl, bid.originalCpm || bid.cpm));
146-
}
65+
// replaceAuctionPrice is available in this scope due to the import from ../src/utils.js
66+
commonOnBidWonHandler(bid, (url, bidData) => replaceAuctionPrice(url, bidData.originalCpm || bidData.cpm));
14767
},
14868
};
14969

0 commit comments

Comments
 (0)