prebid.js 7.6.0 → 7.7.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/dist/1plusXRtdProvider.js +1 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adoceanBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bliinkBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/not-for-prod/prebid.js +112 -111
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
- package/modules/.submodules.json +2 -1
- package/modules/1plusXRtdProvider.js +251 -0
- package/modules/1plusXRtdProvider.md +65 -0
- package/modules/adoceanBidAdapter.js +10 -3
- package/modules/big-richmediaBidAdapter.js +3 -3
- package/modules/bliinkBidAdapter.js +120 -193
- package/modules/bliinkBidAdapter.md +2 -5
- package/modules/consumableBidAdapter.js +9 -0
- package/modules/currency.js +2 -2
- package/modules/impactifyBidAdapter.js +6 -2
- package/modules/ixBidAdapter.js +61 -14
- package/modules/ixBidAdapter.md +2 -5
- package/modules/jixieBidAdapter.js +10 -10
- package/modules/naveggIdSystem.js +1 -12
- package/modules/nextMillenniumBidAdapter.md +1 -1
- package/modules/onetagBidAdapter.js +44 -7
- package/modules/prebidServerBidAdapter/index.js +7 -0
- package/modules/rubiconBidAdapter.js +5 -0
- package/modules/seedingAllianceBidAdapter.js +3 -0
- package/modules/targetVideoBidAdapter.js +18 -0
- package/modules/userId/index.js +39 -21
- package/package.json +1 -1
- package/src/auction.js +6 -5
- package/src/consentHandler.js +11 -11
- package/src/debugging.js +5 -3
- package/src/hook.js +2 -2
- package/src/utils/promise.js +96 -21
- package/src/utils.js +3 -2
- package/test/helpers/consentData.js +2 -1
- package/test/spec/auctionmanager_spec.js +1 -6
- package/test/spec/debugging_spec.js +2 -2
- package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
- package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
- package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
- package/test/spec/modules/consumableBidAdapter_spec.js +47 -1
- package/test/spec/modules/idxIdSystem_spec.js +1 -1
- package/test/spec/modules/ixBidAdapter_spec.js +77 -2
- package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
- package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
- package/test/spec/modules/parrableIdSystem_spec.js +2 -1
- package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
- package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
- package/test/spec/modules/userId_spec.js +15 -2
- package/test/spec/unit/pbjs_api_spec.js +1 -5
- package/test/spec/unit/utils/promise_spec.js +283 -38
- package/test/helpers/syncPromise.js +0 -71
|
@@ -28,14 +28,14 @@ function setIds_(clientId, sessionId) {
|
|
|
28
28
|
let expC = (new Date(new Date().setFullYear(new Date().getFullYear() + 1))).toUTCString();
|
|
29
29
|
let expS = (new Date(new Date().setMinutes(new Date().getMinutes() + sidTTLMins_))).toUTCString();
|
|
30
30
|
|
|
31
|
-
storage.setCookie('
|
|
32
|
-
storage.setCookie('
|
|
31
|
+
storage.setCookie('_jxx', clientId, expC, 'None', null);
|
|
32
|
+
storage.setCookie('_jxx', clientId, expC, 'None', dd);
|
|
33
33
|
|
|
34
|
-
storage.setCookie('
|
|
35
|
-
storage.setCookie('
|
|
34
|
+
storage.setCookie('_jxxs', sessionId, expS, 'None', null);
|
|
35
|
+
storage.setCookie('_jxxs', sessionId, expS, 'None', dd);
|
|
36
36
|
|
|
37
|
-
storage.setDataInLocalStorage('
|
|
38
|
-
storage.setDataInLocalStorage('
|
|
37
|
+
storage.setDataInLocalStorage('_jxx', clientId);
|
|
38
|
+
storage.setDataInLocalStorage('_jxxs', sessionId);
|
|
39
39
|
} catch (error) {}
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -47,14 +47,14 @@ function fetchIds_() {
|
|
|
47
47
|
session_id_ls: ''
|
|
48
48
|
};
|
|
49
49
|
try {
|
|
50
|
-
let tmp = storage.getCookie('
|
|
50
|
+
let tmp = storage.getCookie('_jxx');
|
|
51
51
|
if (tmp) ret.client_id_c = tmp;
|
|
52
|
-
tmp = storage.getCookie('
|
|
52
|
+
tmp = storage.getCookie('_jxxs');
|
|
53
53
|
if (tmp) ret.session_id_c = tmp;
|
|
54
54
|
|
|
55
|
-
tmp = storage.getDataFromLocalStorage('
|
|
55
|
+
tmp = storage.getDataFromLocalStorage('_jxx');
|
|
56
56
|
if (tmp) ret.client_id_ls = tmp;
|
|
57
|
-
tmp = storage.getDataFromLocalStorage('
|
|
57
|
+
tmp = storage.getDataFromLocalStorage('_jxxs');
|
|
58
58
|
if (tmp) ret.session_id_ls = tmp;
|
|
59
59
|
} catch (error) {}
|
|
60
60
|
return ret;
|
|
@@ -34,17 +34,6 @@ function readnavIDFromCookie() {
|
|
|
34
34
|
return storage.cookiesAreEnabled ? (storage.findSimilarCookies('nav') ? storage.findSimilarCookies('nav')[0] : null) : null;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function readnvgnavFromLocalStorage() {
|
|
38
|
-
var i;
|
|
39
|
-
const query = /[nvga]{3}\d+/;
|
|
40
|
-
for (i in window.localStorage) {
|
|
41
|
-
if (i.match(query) || (!query && typeof i === 'string')) {
|
|
42
|
-
const naveggId = storage.getDataFromLocalStorage(i.match(query).input).split('|')[0]
|
|
43
|
-
return naveggId.split('_')[0];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
37
|
/** @type {Submodule} */
|
|
49
38
|
export const naveggIdSubmodule = {
|
|
50
39
|
/**
|
|
@@ -73,7 +62,7 @@ export const naveggIdSubmodule = {
|
|
|
73
62
|
getId() {
|
|
74
63
|
let naveggIdStringFromLocalStorage = null;
|
|
75
64
|
if (storage.localStorageIsEnabled) {
|
|
76
|
-
naveggIdStringFromLocalStorage = readnaveggIdFromLocalStorage()
|
|
65
|
+
naveggIdStringFromLocalStorage = readnaveggIdFromLocalStorage();
|
|
77
66
|
}
|
|
78
67
|
|
|
79
68
|
const naveggIdString = naveggIdStringFromLocalStorage || readnaveggIDFromCookie() || readoldnaveggIDFromCookie() || readnvgIDFromCookie() || readnavIDFromCookie();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
|
-
import {INSTREAM, OUTSTREAM} from '../src/video.js';
|
|
5
|
-
import {Renderer} from '../src/Renderer.js';
|
|
3
|
+
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
4
|
+
import { INSTREAM, OUTSTREAM } from '../src/video.js';
|
|
5
|
+
import { Renderer } from '../src/Renderer.js';
|
|
6
6
|
import {find} from '../src/polyfill.js';
|
|
7
|
-
import {getStorageManager} from '../src/storageManager.js';
|
|
8
|
-
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
9
|
-
import {createEidsArray} from './userId/eids.js';
|
|
10
|
-
import {deepClone} from '../src/utils.js';
|
|
7
|
+
import { getStorageManager } from '../src/storageManager.js';
|
|
8
|
+
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
9
|
+
import { createEidsArray } from './userId/eids.js';
|
|
10
|
+
import { deepClone, logError, deepAccess } from '../src/utils.js';
|
|
11
11
|
|
|
12
12
|
const ENDPOINT = 'https://onetag-sys.com/prebid-request';
|
|
13
13
|
const USER_SYNC_ENDPOINT = 'https://onetag-sys.com/usync/';
|
|
@@ -68,6 +68,9 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
68
68
|
if (validBidRequests && validBidRequests.length !== 0 && validBidRequests[0].userId) {
|
|
69
69
|
payload.userId = createEidsArray(validBidRequests[0].userId);
|
|
70
70
|
}
|
|
71
|
+
if (validBidRequests && validBidRequests.length !== 0 && validBidRequests[0].schain && isSchainValid(validBidRequests[0].schain)) {
|
|
72
|
+
payload.schain = validBidRequests[0].schain;
|
|
73
|
+
}
|
|
71
74
|
try {
|
|
72
75
|
if (storage.hasLocalStorage()) {
|
|
73
76
|
payload.onetagSid = storage.getDataFromLocalStorage('onetag_sid');
|
|
@@ -245,6 +248,7 @@ function requestsToBids(bidRequests) {
|
|
|
245
248
|
// Other params
|
|
246
249
|
videoObj['mediaTypeInfo'] = deepClone(bidRequest.mediaTypes.video);
|
|
247
250
|
videoObj['type'] = VIDEO;
|
|
251
|
+
videoObj['priceFloors'] = getBidFloor(bidRequest, VIDEO, videoObj['playerSize']);
|
|
248
252
|
return videoObj;
|
|
249
253
|
});
|
|
250
254
|
const bannerBidRequests = bidRequests.filter(bidRequest => isValid(BANNER, bidRequest)).map(bidRequest => {
|
|
@@ -253,6 +257,7 @@ function requestsToBids(bidRequests) {
|
|
|
253
257
|
bannerObj['sizes'] = parseSizes(bidRequest);
|
|
254
258
|
bannerObj['type'] = BANNER;
|
|
255
259
|
bannerObj['mediaTypeInfo'] = deepClone(bidRequest.mediaTypes.banner);
|
|
260
|
+
bannerObj['priceFloors'] = getBidFloor(bidRequest, BANNER, bannerObj['sizes']);
|
|
256
261
|
return bannerObj;
|
|
257
262
|
});
|
|
258
263
|
return videoBidRequests.concat(bannerBidRequests);
|
|
@@ -265,6 +270,7 @@ function setGeneralInfo(bidRequest) {
|
|
|
265
270
|
this['bidderRequestId'] = bidRequest.bidderRequestId;
|
|
266
271
|
this['auctionId'] = bidRequest.auctionId;
|
|
267
272
|
this['transactionId'] = bidRequest.transactionId;
|
|
273
|
+
this['gpid'] = deepAccess(bidRequest, 'ortb2Imp.ext.gpid') || deepAccess(bidRequest, 'ortb2Imp.ext.data.pbadslot');
|
|
268
274
|
this['pubId'] = params.pubId;
|
|
269
275
|
this['ext'] = params.ext;
|
|
270
276
|
if (params.pubClick) {
|
|
@@ -373,6 +379,37 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
|
|
|
373
379
|
return syncs;
|
|
374
380
|
}
|
|
375
381
|
|
|
382
|
+
function getBidFloor(bidRequest, mediaType, sizes) {
|
|
383
|
+
const priceFloors = [];
|
|
384
|
+
if (typeof bidRequest.getFloor === 'function') {
|
|
385
|
+
sizes.forEach(size => {
|
|
386
|
+
const floor = bidRequest.getFloor({
|
|
387
|
+
currency: 'EUR',
|
|
388
|
+
mediaType: mediaType || '*',
|
|
389
|
+
size: [size.width, size.height]
|
|
390
|
+
});
|
|
391
|
+
floor.size = deepClone(size);
|
|
392
|
+
if (!floor.floor) { floor.floor = null; }
|
|
393
|
+
priceFloors.push(floor);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return priceFloors;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export function isSchainValid(schain) {
|
|
400
|
+
let isValid = false;
|
|
401
|
+
const requiredFields = ['asi', 'sid', 'hp'];
|
|
402
|
+
if (!schain || !schain.nodes) return isValid;
|
|
403
|
+
isValid = schain.nodes.reduce((status, node) => {
|
|
404
|
+
if (!status) return status;
|
|
405
|
+
return requiredFields.every(field => node.hasOwnProperty(field));
|
|
406
|
+
}, true);
|
|
407
|
+
if (!isValid) {
|
|
408
|
+
logError('OneTag: required schain params missing');
|
|
409
|
+
}
|
|
410
|
+
return isValid;
|
|
411
|
+
}
|
|
412
|
+
|
|
376
413
|
export const spec = {
|
|
377
414
|
code: BIDDER_CODE,
|
|
378
415
|
gvlid: GVLID,
|
|
@@ -984,6 +984,13 @@ Object.assign(ORTB2.prototype, {
|
|
|
984
984
|
});
|
|
985
985
|
bidObject.requestTimestamp = this.requestTimestamp;
|
|
986
986
|
bidObject.cpm = cpm;
|
|
987
|
+
if (bid?.ext?.prebid?.meta?.adaptercode) {
|
|
988
|
+
bidObject.adapterCode = bid.ext.prebid.meta.adaptercode;
|
|
989
|
+
} else if (bidRequest?.bidder) {
|
|
990
|
+
bidObject.adapterCode = bidRequest.bidder;
|
|
991
|
+
} else {
|
|
992
|
+
bidObject.adapterCode = seatbid.seat;
|
|
993
|
+
}
|
|
987
994
|
|
|
988
995
|
// temporarily leaving attaching it to each bidResponse so no breaking change
|
|
989
996
|
// BUT: this is a flat map, so it should be only attached to bidderRequest, a the change above does
|
|
@@ -320,6 +320,11 @@ export const spec = {
|
|
|
320
320
|
// set ext.prebid.auctiontimestamp using auction time
|
|
321
321
|
deepSetValue(data.imp[0], 'ext.prebid.auctiontimestamp', bidderRequest.auctionStart);
|
|
322
322
|
|
|
323
|
+
// set storedrequests to undefined so not sent to PBS
|
|
324
|
+
// top level and imp level both 'ext.prebid' objects are set above so no exception thrown here
|
|
325
|
+
data.ext.prebid.storedrequest = undefined;
|
|
326
|
+
data.imp[0].ext.prebid.storedrequest = undefined;
|
|
327
|
+
|
|
323
328
|
return {
|
|
324
329
|
method: 'POST',
|
|
325
330
|
url: `https://${rubiConf.videoHost || 'prebid-server'}.rubiconproject.com/openrtb2/auction`,
|
|
@@ -7,6 +7,7 @@ import { _map, deepSetValue, isEmpty, deepAccess } from '../src/utils.js';
|
|
|
7
7
|
import { config } from '../src/config.js';
|
|
8
8
|
|
|
9
9
|
const BIDDER_CODE = 'seedingAlliance';
|
|
10
|
+
const GVL_ID = 371;
|
|
10
11
|
const DEFAULT_CUR = 'EUR';
|
|
11
12
|
const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb';
|
|
12
13
|
|
|
@@ -52,6 +53,8 @@ const NATIVE_PARAMS = {
|
|
|
52
53
|
export const spec = {
|
|
53
54
|
code: BIDDER_CODE,
|
|
54
55
|
|
|
56
|
+
gvlid: GVL_ID,
|
|
57
|
+
|
|
55
58
|
supportedMediaTypes: [NATIVE],
|
|
56
59
|
|
|
57
60
|
isBidRequestValid: function(bid) {
|
|
@@ -42,6 +42,24 @@ export const spec = {
|
|
|
42
42
|
},
|
|
43
43
|
schain: schain
|
|
44
44
|
};
|
|
45
|
+
|
|
46
|
+
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
47
|
+
payload.gdpr_consent = {
|
|
48
|
+
consent_string: bidderRequest.gdprConsent.consentString,
|
|
49
|
+
consent_required: bidderRequest.gdprConsent.gdprApplies
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
if (bidderRequest.gdprConsent.addtlConsent && bidderRequest.gdprConsent.addtlConsent.indexOf('~') !== -1) {
|
|
53
|
+
let ac = bidderRequest.gdprConsent.addtlConsent;
|
|
54
|
+
let acStr = ac.substring(ac.indexOf('~') + 1);
|
|
55
|
+
payload.gdpr_consent.addtl_consent = acStr.split('.').map(id => parseInt(id, 10));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (bidderRequest && bidderRequest.uspConsent) {
|
|
60
|
+
payload.us_privacy = bidderRequest.uspConsent
|
|
61
|
+
}
|
|
62
|
+
|
|
45
63
|
return formatRequest(payload, bidderRequest);
|
|
46
64
|
},
|
|
47
65
|
|
package/modules/userId/index.js
CHANGED
|
@@ -152,7 +152,7 @@ import {
|
|
|
152
152
|
isEmpty
|
|
153
153
|
} from '../../src/utils.js';
|
|
154
154
|
import {getPPID as coreGetPPID} from '../../src/adserver.js';
|
|
155
|
-
import {
|
|
155
|
+
import {defer, GreedyPromise} from '../../src/utils/promise.js';
|
|
156
156
|
import {hasPurpose1Consent} from '../../src/utils/gpdr.js';
|
|
157
157
|
|
|
158
158
|
const MODULE_NAME = 'User ID';
|
|
@@ -504,15 +504,11 @@ function addIdDataToAdUnitBids(adUnits, submodules) {
|
|
|
504
504
|
});
|
|
505
505
|
}
|
|
506
506
|
|
|
507
|
-
function delayFor(ms) {
|
|
508
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
509
|
-
}
|
|
510
|
-
|
|
511
507
|
const INIT_CANCELED = {};
|
|
512
508
|
|
|
513
|
-
function idSystemInitializer({delay =
|
|
514
|
-
const startInit =
|
|
515
|
-
const startCallbacks =
|
|
509
|
+
function idSystemInitializer({delay = GreedyPromise.timeout} = {}) {
|
|
510
|
+
const startInit = defer();
|
|
511
|
+
const startCallbacks = defer();
|
|
516
512
|
let cancel;
|
|
517
513
|
let initialized = false;
|
|
518
514
|
|
|
@@ -520,8 +516,8 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
520
516
|
if (cancel != null) {
|
|
521
517
|
cancel.reject(INIT_CANCELED);
|
|
522
518
|
}
|
|
523
|
-
cancel =
|
|
524
|
-
return
|
|
519
|
+
cancel = defer();
|
|
520
|
+
return GreedyPromise.race([promise, cancel.promise]);
|
|
525
521
|
}
|
|
526
522
|
|
|
527
523
|
// grab a reference to global vars so that the promise chains remain isolated;
|
|
@@ -540,7 +536,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
540
536
|
}
|
|
541
537
|
|
|
542
538
|
let done = cancelAndTry(
|
|
543
|
-
|
|
539
|
+
GreedyPromise.all([hooksReady, startInit.promise])
|
|
544
540
|
.then(() => gdprDataHandler.promise)
|
|
545
541
|
.then(checkRefs((consentData) => {
|
|
546
542
|
initSubmodules(initModules, allModules, consentData);
|
|
@@ -549,7 +545,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
549
545
|
.then(checkRefs(() => {
|
|
550
546
|
const modWithCb = initModules.filter(item => isFn(item.callback));
|
|
551
547
|
if (modWithCb.length) {
|
|
552
|
-
return new
|
|
548
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(modWithCb, resolve));
|
|
553
549
|
}
|
|
554
550
|
}))
|
|
555
551
|
);
|
|
@@ -573,7 +569,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
573
569
|
});
|
|
574
570
|
}
|
|
575
571
|
}
|
|
576
|
-
if (refresh) {
|
|
572
|
+
if (refresh && initialized) {
|
|
577
573
|
done = cancelAndTry(
|
|
578
574
|
done
|
|
579
575
|
.catch(() => null)
|
|
@@ -588,7 +584,7 @@ function idSystemInitializer({delay = delayFor} = {}) {
|
|
|
588
584
|
return sm.callback != null;
|
|
589
585
|
});
|
|
590
586
|
if (cbModules.length) {
|
|
591
|
-
return new
|
|
587
|
+
return new GreedyPromise((resolve) => processSubmoduleCallbacks(cbModules, resolve));
|
|
592
588
|
}
|
|
593
589
|
}))
|
|
594
590
|
);
|
|
@@ -621,8 +617,8 @@ function getPPID() {
|
|
|
621
617
|
* @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
|
|
622
618
|
* @param {function} fn required; The next function in the chain, used by hook.js
|
|
623
619
|
*/
|
|
624
|
-
export function requestBidsHook(fn, reqBidsConfigObj, {delay =
|
|
625
|
-
|
|
620
|
+
export function requestBidsHook(fn, reqBidsConfigObj, {delay = GreedyPromise.timeout} = {}) {
|
|
621
|
+
GreedyPromise.race([
|
|
626
622
|
getUserIdsAsync(),
|
|
627
623
|
delay(auctionDelay)
|
|
628
624
|
]).then(() => {
|
|
@@ -767,7 +763,16 @@ function refreshUserIds({submoduleNames} = {}, callback) {
|
|
|
767
763
|
*/
|
|
768
764
|
|
|
769
765
|
function getUserIdsAsync() {
|
|
770
|
-
return initIdSystem().then(
|
|
766
|
+
return initIdSystem().then(
|
|
767
|
+
() => getUserIds(),
|
|
768
|
+
(e) =>
|
|
769
|
+
e === INIT_CANCELED
|
|
770
|
+
// there's a pending refresh - because GreedyPromise runs this synchronously, we are now in the middle
|
|
771
|
+
// of canceling the previous init, before the refresh logic has had a chance to run.
|
|
772
|
+
// Use a "normal" Promise to clear the stack and let it complete (or this will just recurse infinitely)
|
|
773
|
+
? Promise.resolve().then(getUserIdsAsync)
|
|
774
|
+
: GreedyPromise.reject(e)
|
|
775
|
+
);
|
|
771
776
|
}
|
|
772
777
|
|
|
773
778
|
/**
|
|
@@ -914,6 +919,8 @@ function updateSubmodules() {
|
|
|
914
919
|
return;
|
|
915
920
|
}
|
|
916
921
|
// do this to avoid reprocessing submodules
|
|
922
|
+
// TODO: the logic does not match the comment - addedSubmodules is always a copy of submoduleRegistry
|
|
923
|
+
// (if it did it would not be correct - it's not enough to find new modules, as others may have been removed or changed)
|
|
917
924
|
const addedSubmodules = submoduleRegistry.filter(i => !find(submodules, j => j.name === i.name));
|
|
918
925
|
|
|
919
926
|
submodules.splice(0, submodules.length);
|
|
@@ -949,6 +956,17 @@ export function attachIdSystem(submodule) {
|
|
|
949
956
|
if (!find(submoduleRegistry, i => i.name === submodule.name)) {
|
|
950
957
|
submoduleRegistry.push(submodule);
|
|
951
958
|
updateSubmodules();
|
|
959
|
+
// TODO: a test case wants this to work even if called after init (the setConfig({userId}))
|
|
960
|
+
// so we trigger a refresh. But is that even possible outside of tests?
|
|
961
|
+
initIdSystem({refresh: true, submoduleNames: [submodule.name]});
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function normalizePromise(fn) {
|
|
966
|
+
// for public methods that return promises, make sure we return a "normal" one - to avoid
|
|
967
|
+
// exposing confusing stack traces
|
|
968
|
+
return function() {
|
|
969
|
+
return Promise.resolve(fn.apply(this, arguments));
|
|
952
970
|
}
|
|
953
971
|
}
|
|
954
972
|
|
|
@@ -957,7 +975,7 @@ export function attachIdSystem(submodule) {
|
|
|
957
975
|
* so a callback is added to fire after the consentManagement module.
|
|
958
976
|
* @param {{getConfig:function}} config
|
|
959
977
|
*/
|
|
960
|
-
export function init(config, {delay =
|
|
978
|
+
export function init(config, {delay = GreedyPromise.timeout} = {}) {
|
|
961
979
|
ppidSource = undefined;
|
|
962
980
|
submodules = [];
|
|
963
981
|
configRegistry = [];
|
|
@@ -1002,10 +1020,10 @@ export function init(config, {delay = delayFor} = {}) {
|
|
|
1002
1020
|
// exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes.
|
|
1003
1021
|
(getGlobal()).getUserIds = getUserIds;
|
|
1004
1022
|
(getGlobal()).getUserIdsAsEids = getUserIdsAsEids;
|
|
1005
|
-
(getGlobal()).getEncryptedEidsForSource = getEncryptedEidsForSource;
|
|
1023
|
+
(getGlobal()).getEncryptedEidsForSource = normalizePromise(getEncryptedEidsForSource);
|
|
1006
1024
|
(getGlobal()).registerSignalSources = registerSignalSources;
|
|
1007
|
-
(getGlobal()).refreshUserIds = refreshUserIds;
|
|
1008
|
-
(getGlobal()).getUserIdsAsync = getUserIdsAsync;
|
|
1025
|
+
(getGlobal()).refreshUserIds = normalizePromise(refreshUserIds);
|
|
1026
|
+
(getGlobal()).getUserIdsAsync = normalizePromise(getUserIdsAsync);
|
|
1009
1027
|
(getGlobal()).getUserIdsAsEidBySource = getUserIdsAsEidBySource;
|
|
1010
1028
|
}
|
|
1011
1029
|
|
package/package.json
CHANGED
package/src/auction.js
CHANGED
|
@@ -76,6 +76,7 @@ import {bidderSettings} from './bidderSettings.js';
|
|
|
76
76
|
import * as events from './events.js'
|
|
77
77
|
import adapterManager from './adapterManager.js';
|
|
78
78
|
import CONSTANTS from './constants.json';
|
|
79
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
79
80
|
|
|
80
81
|
const { syncUsers } = userSync;
|
|
81
82
|
|
|
@@ -384,9 +385,9 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
|
|
|
384
385
|
|
|
385
386
|
function waitFor(requestId, result) {
|
|
386
387
|
if (ready[requestId] == null) {
|
|
387
|
-
ready[requestId] =
|
|
388
|
+
ready[requestId] = GreedyPromise.resolve();
|
|
388
389
|
}
|
|
389
|
-
ready[requestId] = ready[requestId].then(() =>
|
|
390
|
+
ready[requestId] = ready[requestId].then(() => GreedyPromise.resolve(result).catch(() => {}))
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
function guard(bidderRequest, fn) {
|
|
@@ -398,9 +399,9 @@ export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionM
|
|
|
398
399
|
const wait = ready[bidderRequest.bidderRequestId];
|
|
399
400
|
const orphanWait = ready['']; // also wait for "orphan" responses that are not associated with any request
|
|
400
401
|
if ((wait != null || orphanWait != null) && timeRemaining > 0) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
402
|
+
GreedyPromise.race([
|
|
403
|
+
GreedyPromise.timeout(timeRemaining),
|
|
404
|
+
GreedyPromise.resolve(orphanWait).then(() => wait)
|
|
404
405
|
]).then(fn);
|
|
405
406
|
} else {
|
|
406
407
|
fn();
|
package/src/consentHandler.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {isStr, timestamp} from './utils.js';
|
|
2
|
+
import {defer, GreedyPromise} from './utils/promise.js';
|
|
2
3
|
|
|
3
4
|
export class ConsentHandler {
|
|
4
5
|
#enabled;
|
|
5
6
|
#data;
|
|
6
|
-
#
|
|
7
|
-
#resolve;
|
|
7
|
+
#defer;
|
|
8
8
|
#ready;
|
|
9
9
|
generatedTime;
|
|
10
10
|
|
|
@@ -12,17 +12,17 @@ export class ConsentHandler {
|
|
|
12
12
|
this.reset();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
#resolve(data) {
|
|
16
|
+
this.#ready = true;
|
|
17
|
+
this.#data = data;
|
|
18
|
+
this.#defer.resolve(data);
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
/**
|
|
16
22
|
* reset this handler (mainly for tests)
|
|
17
23
|
*/
|
|
18
24
|
reset() {
|
|
19
|
-
this.#
|
|
20
|
-
this.#resolve = (data) => {
|
|
21
|
-
this.#ready = true;
|
|
22
|
-
this.#data = data;
|
|
23
|
-
resolve(data);
|
|
24
|
-
};
|
|
25
|
-
});
|
|
25
|
+
this.#defer = defer();
|
|
26
26
|
this.#enabled = false;
|
|
27
27
|
this.#data = null;
|
|
28
28
|
this.#ready = false;
|
|
@@ -56,12 +56,12 @@ export class ConsentHandler {
|
|
|
56
56
|
*/
|
|
57
57
|
get promise() {
|
|
58
58
|
if (this.#ready) {
|
|
59
|
-
return
|
|
59
|
+
return GreedyPromise.resolve(this.#data);
|
|
60
60
|
}
|
|
61
61
|
if (!this.#enabled) {
|
|
62
62
|
this.#resolve(null);
|
|
63
63
|
}
|
|
64
|
-
return this.#promise;
|
|
64
|
+
return this.#defer.promise;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
setConsentData(data, time = timestamp()) {
|
package/src/debugging.js
CHANGED
|
@@ -4,6 +4,7 @@ import {getGlobal} from './prebidGlobal.js';
|
|
|
4
4
|
import {logMessage, prefixLog} from './utils.js';
|
|
5
5
|
import {createBid} from './bidfactory.js';
|
|
6
6
|
import {loadExternalScript} from './adloader.js';
|
|
7
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
7
8
|
|
|
8
9
|
export const DEBUG_KEY = '__$$PREBID_GLOBAL$$_debugging__';
|
|
9
10
|
|
|
@@ -12,7 +13,7 @@ function isDebuggingInstalled() {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
function loadScript(url) {
|
|
15
|
-
return new
|
|
16
|
+
return new GreedyPromise((resolve) => {
|
|
16
17
|
loadExternalScript(url, 'debugging', resolve);
|
|
17
18
|
});
|
|
18
19
|
}
|
|
@@ -21,7 +22,8 @@ export function debuggingModuleLoader({alreadyInstalled = isDebuggingInstalled,
|
|
|
21
22
|
let loading = null;
|
|
22
23
|
return function () {
|
|
23
24
|
if (loading == null) {
|
|
24
|
-
loading = new
|
|
25
|
+
loading = new GreedyPromise((resolve, reject) => {
|
|
26
|
+
// run this in a 0-delay timeout to give installedModules time to be populated
|
|
25
27
|
setTimeout(() => {
|
|
26
28
|
if (alreadyInstalled()) {
|
|
27
29
|
resolve();
|
|
@@ -44,7 +46,7 @@ export function debuggingControls({load = debuggingModuleLoader(), hook = getHoo
|
|
|
44
46
|
let promise = null;
|
|
45
47
|
let enabled = false;
|
|
46
48
|
function waitForDebugging(next, ...args) {
|
|
47
|
-
return (promise ||
|
|
49
|
+
return (promise || GreedyPromise.resolve()).then(() => next.apply(this, args))
|
|
48
50
|
}
|
|
49
51
|
function enable() {
|
|
50
52
|
if (!enabled) {
|
package/src/hook.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import funHooks from 'fun-hooks/no-eval/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import {defer} from './utils/promise.js';
|
|
3
3
|
|
|
4
4
|
export let hook = funHooks({
|
|
5
5
|
ready: funHooks.SYNC | funHooks.ASYNC | funHooks.QUEUE
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
const readyCtl =
|
|
8
|
+
const readyCtl = defer();
|
|
9
9
|
hook.ready = (() => {
|
|
10
10
|
const ready = hook.ready;
|
|
11
11
|
return function () {
|
package/src/utils/promise.js
CHANGED
|
@@ -1,36 +1,111 @@
|
|
|
1
1
|
const SUCCESS = 0;
|
|
2
2
|
const FAIL = 1;
|
|
3
|
-
const RESULT = 2;
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
5
|
+
* A version of Promise that runs callbacks synchronously when it can (i.e. after it's been fulfilled or rejected).
|
|
7
6
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
7
|
+
export class GreedyPromise extends Promise {
|
|
8
|
+
#result;
|
|
9
|
+
#callbacks;
|
|
10
|
+
#parent = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Convenience wrapper for setTimeout; takes care of returning an already fulfilled GreedyPromise when the delay is zero.
|
|
14
|
+
*
|
|
15
|
+
* @param {Number} delayMs delay in milliseconds
|
|
16
|
+
* @returns {GreedyPromise} a promise that resolves (to undefined) in `delayMs` milliseconds
|
|
17
|
+
*/
|
|
18
|
+
static timeout(delayMs = 0) {
|
|
19
|
+
return new GreedyPromise((resolve) => {
|
|
20
|
+
delayMs === 0 ? resolve() : setTimeout(resolve, delayMs);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
constructor(resolver) {
|
|
25
|
+
const result = [];
|
|
26
|
+
const callbacks = [];
|
|
27
|
+
function handler(type, resolveFn) {
|
|
28
|
+
return function (value) {
|
|
29
|
+
if (!result.length) {
|
|
30
|
+
result.push(type, value);
|
|
31
|
+
while (callbacks.length) callbacks.shift()();
|
|
32
|
+
resolveFn(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
super(
|
|
37
|
+
typeof resolver !== 'function'
|
|
38
|
+
? resolver // let super throw an error
|
|
39
|
+
: (resolve, reject) => {
|
|
40
|
+
const rejectHandler = handler(FAIL, reject);
|
|
41
|
+
const resolveHandler = (() => {
|
|
42
|
+
const done = handler(SUCCESS, resolve);
|
|
43
|
+
return value =>
|
|
44
|
+
typeof value?.then === 'function' ? value.then(done, rejectHandler) : done(value);
|
|
45
|
+
})();
|
|
46
|
+
try {
|
|
47
|
+
resolver(resolveHandler, rejectHandler);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
rejectHandler(e);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
this.#result = result;
|
|
54
|
+
this.#callbacks = callbacks;
|
|
55
|
+
}
|
|
56
|
+
then(onSuccess, onError) {
|
|
57
|
+
if (typeof onError === 'function') {
|
|
58
|
+
// if an error handler is provided, attach a dummy error handler to super,
|
|
59
|
+
// and do the same for all promises without an error handler that precede this one in a chain.
|
|
60
|
+
// This is to avoid unhandled rejection events / warnings for errors that were, in fact, handled;
|
|
61
|
+
// since we are not using super's callback mechanisms we need to make it aware of this separately.
|
|
62
|
+
let node = this;
|
|
63
|
+
while (node) {
|
|
64
|
+
super.then.call(node, null, () => null);
|
|
65
|
+
const next = node.#parent;
|
|
66
|
+
node.#parent = null; // since we attached a handler already, we are no longer interested in what will happen later in the chain
|
|
67
|
+
node = next;
|
|
18
68
|
}
|
|
19
69
|
}
|
|
70
|
+
const result = this.#result;
|
|
71
|
+
const res = new GreedyPromise((resolve, reject) => {
|
|
72
|
+
const continuation = () => {
|
|
73
|
+
let value = result[1];
|
|
74
|
+
let [handler, resolveFn] = result[0] === SUCCESS ? [onSuccess, resolve] : [onError, reject];
|
|
75
|
+
if (typeof handler === 'function') {
|
|
76
|
+
try {
|
|
77
|
+
value = handler(value);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
reject(e);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
resolveFn = resolve;
|
|
83
|
+
}
|
|
84
|
+
resolveFn(value);
|
|
85
|
+
}
|
|
86
|
+
result.length ? continuation() : this.#callbacks.push(continuation);
|
|
87
|
+
});
|
|
88
|
+
res.#parent = this;
|
|
89
|
+
return res;
|
|
20
90
|
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @returns a {promise, resolve, reject} trio where `promise` is resolved by calling `resolve` or `reject`.
|
|
95
|
+
*/
|
|
96
|
+
export function defer({promiseFactory = (resolver) => new GreedyPromise(resolver)} = {}) {
|
|
97
|
+
function invoker(delegate) {
|
|
98
|
+
return (val) => delegate(val);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let resolveFn, rejectFn;
|
|
21
102
|
|
|
22
103
|
return {
|
|
23
104
|
promise: promiseFactory((resolve, reject) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} else if (status[FAIL] != null) {
|
|
27
|
-
reject(status[RESULT]);
|
|
28
|
-
} else {
|
|
29
|
-
status[SUCCESS] = resolve;
|
|
30
|
-
status[FAIL] = reject;
|
|
31
|
-
}
|
|
105
|
+
resolveFn = resolve;
|
|
106
|
+
rejectFn = reject;
|
|
32
107
|
}),
|
|
33
|
-
resolve:
|
|
34
|
-
reject:
|
|
108
|
+
resolve: invoker(resolveFn),
|
|
109
|
+
reject: invoker(rejectFn)
|
|
35
110
|
}
|
|
36
111
|
}
|