From 1d74541e262051f61e9641a20fd30f08339f8ec2 Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Thu, 28 Apr 2022 13:23:38 -0700 Subject: [PATCH] Revert "Merge master into prebid-7 (#8336)" This reverts commit 90df3ff201aee8f01bd21c346243dfdb25196a6b. --- .circleci/config.yml | 12 +- gulpfile.js | 123 +- modules/adomikAnalyticsAdapter.js | 110 +- modules/adotBidAdapter.js | 2 +- modules/adyoulikeBidAdapter.js | 2 - modules/apacdexBidAdapter.js | 93 +- modules/audiencerunBidAdapter.js | 97 +- modules/betweenBidAdapter.js | 2 +- modules/cointrafficBidAdapter.js | 2 +- modules/colossussspBidAdapter.js | 6 +- modules/consentManagement.js | 8 +- modules/consentManagementUsp.js | 4 +- modules/currency.js | 2 - modules/debugging/pbsInterceptor.js | 2 +- modules/e_volutionBidAdapter.js | 20 +- modules/ftrackIdSystem.js | 18 +- modules/ftrackIdSystem.md | 13 +- modules/malltvAnalyticsAdapter.js | 2 +- modules/mobfoxpbBidAdapter.js | 135 -- modules/mobfoxpbBidAdapter.md | 6 +- modules/nextMillenniumBidAdapter.js | 8 +- modules/nexx360BidAdapter.js | 18 +- modules/otmBidAdapter.js | 78 +- modules/prebidServerBidAdapter/index.js | 72 +- modules/pubmaticBidAdapter.js | 36 +- modules/seedingAllianceBidAdapter.js | 12 +- modules/userId/index.js | 348 ++--- modules/vibrantmediaBidAdapter.js | 11 +- package-lock.json | 754 +--------- package.json | 5 +- src/adapters/bidderFactory.js | 17 - src/auction.js | 8 +- test/fake-server/bundle.js | 41 - test/fake-server/fake-responder.js | 23 +- .../fixtures/basic-banner/request.json | 2 +- .../fixtures/basic-outstream/request.json | 6 +- test/fake-server/index.js | 9 +- test/helpers/consentData.js | 6 - test/helpers/testing-utils.js | 42 +- test/pages/banner.html | 2 +- test/pages/bidderSettings.html | 4 +- test/pages/consent_mgt_gdpr.html | 5 +- test/pages/currency.html | 4 +- test/pages/instream.html | 9 +- test/pages/multiple_bidders.html | 4 +- test/pages/native.html | 2 +- test/pages/outstream.html | 2 +- test/pages/priceGranularity.html | 133 ++ test/pages/sizeConfig.html | 144 ++ test/pages/userSync.html | 123 ++ test/spec/auctionmanager_spec.js | 2 - test/spec/e2e/banner/basic_banner_ad.spec.js | 31 +- .../instream/basic_instream_video_ad.spec.js | 27 +- .../e2e/modules/e2e_bidderSettings.spec.js | 46 +- .../e2e/modules/e2e_consent_mgt_gdpr.spec.js | 9 +- test/spec/e2e/modules/e2e_currency.spec.js | 55 +- .../e2e/modules/e2e_priceGranularity.spec.js | 61 + test/spec/e2e/modules/e2e_sizeConfig.spec.js | 61 + test/spec/e2e/modules/e2e_userSync.spec.js | 61 + .../multi-bidder/e2e_multiple_bidders.spec.js | 46 +- test/spec/e2e/native/basic_native_ad.spec.js | 40 +- .../basic_outstream_video_ad.spec.js | 31 +- .../modules/adomikAnalyticsAdapter_spec.js | 166 +-- test/spec/modules/adotBidAdapter_spec.js | 2 +- test/spec/modules/adyoulikeBidAdapter_spec.js | 7 +- test/spec/modules/apacdexBidAdapter_spec.js | 12 +- .../modules/audiencerunBidAdapter_spec.js | 282 ++-- .../modules/cointrafficBidAdapter_spec.js | 2 +- .../modules/colossussspBidAdapter_spec.js | 100 +- .../spec/modules/consentManagementUsp_spec.js | 1 - test/spec/modules/consentManagement_spec.js | 22 - .../spec/modules/e_volutionBidAdapter_spec.js | 77 +- test/spec/modules/eplanningBidAdapter_spec.js | 33 +- test/spec/modules/ftrackIdSystem_spec.js | 76 +- test/spec/modules/id5IdSystem_spec.js | 101 +- test/spec/modules/idImportLibrary_spec.js | 18 +- test/spec/modules/idxIdSystem_spec.js | 10 +- test/spec/modules/mobfoxpbBidAdapter_spec.js | 307 ---- test/spec/modules/nexx360BidAdapter_spec.js | 49 - test/spec/modules/otmBidAdapter_spec.js | 43 +- test/spec/modules/parrableIdSystem_spec.js | 7 +- .../modules/prebidServerBidAdapter_spec.js | 200 --- test/spec/modules/pubmaticBidAdapter_spec.js | 129 -- test/spec/modules/userId_spec.js | 1290 +++++++++-------- .../spec/modules/zeotapIdPlusIdSystem_spec.js | 2 +- test/spec/unit/core/bidderFactory_spec.js | 137 -- test/spec/unit/pbjs_api_spec.js | 1 - wdio.conf.js | 51 +- 88 files changed, 2228 insertions(+), 3954 deletions(-) delete mode 100644 modules/mobfoxpbBidAdapter.js delete mode 100644 test/fake-server/bundle.js delete mode 100644 test/helpers/consentData.js create mode 100644 test/pages/priceGranularity.html create mode 100644 test/pages/sizeConfig.html create mode 100644 test/pages/userSync.html create mode 100644 test/spec/e2e/modules/e2e_priceGranularity.spec.js create mode 100644 test/spec/e2e/modules/e2e_sizeConfig.spec.js create mode 100644 test/spec/e2e/modules/e2e_userSync.spec.js delete mode 100644 test/spec/modules/mobfoxpbBidAdapter_spec.js diff --git a/.circleci/config.yml b/.circleci/config.yml index c11f87b6f59..784b520ecc1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,7 +36,7 @@ aliases: - &run_endtoend_test name: BrowserStack End to end testing - command: gulp e2e-test + command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost # Download and run BrowserStack local - &setup_browserstack @@ -82,6 +82,16 @@ workflows: commit: jobs: - build + nightly: + triggers: + - schedule: + cron: "0 0 * * *" + filters: + branches: + only: + - master + jobs: + - e2etest experimental: pipelines: true diff --git a/gulpfile.js b/gulpfile.js index ff49436384b..0c4ebc50653 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -32,8 +32,8 @@ var prebid = require('./package.json'); var dateString = 'Updated : ' + (new Date()).toISOString().substring(0, 10); var banner = '/* <%= prebid.name %> v<%= prebid.version %>\n' + dateString + '*/\n'; var port = 9999; -const INTEG_SERVER_HOST = argv.host ? argv.host : 'localhost'; -const INTEG_SERVER_PORT = 4444; +const FAKE_SERVER_HOST = argv.host ? argv.host : 'localhost'; +const FAKE_SERVER_PORT = 4444; const { spawn } = require('child_process'); // these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules @@ -167,9 +167,9 @@ function gulpBundle(dev) { return bundle(dev).pipe(gulp.dest('build/' + (dev ? 'dev' : 'dist'))); } -function nodeBundle(modules, dev = false) { +function nodeBundle(modules) { return new Promise((resolve, reject) => { - bundle(dev, modules) + bundle(false, modules) .on('error', (err) => { reject(err); }) @@ -243,18 +243,41 @@ function testTaskMaker(options = {}) { if (options.notest) { done(); } else if (options.e2e) { - const integ = startIntegServer(); - startLocalServer(); - runWebdriver(options) + let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio'); + let wdioConf = path.join(__dirname, 'wdio.conf.js'); + let wdioOpts; + + if (options.file) { + wdioOpts = [ + wdioConf, + `--spec`, + `${options.file}` + ] + } else { + wdioOpts = [ + wdioConf + ]; + } + + // run fake-server + const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]); + fakeServer.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + fakeServer.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + }); + + execa(wdioCmd, wdioOpts, { stdio: 'inherit' }) .then(stdout => { // kill fake server - integ.kill('SIGINT'); + fakeServer.kill('SIGINT'); done(); process.exit(0); }) .catch(err => { // kill fake server - integ.kill('SIGINT'); + fakeServer.kill('SIGINT'); done(new Error(`Tests failed with error: ${err}`)); process.exit(1); }); @@ -273,26 +296,6 @@ function testTaskMaker(options = {}) { const test = testTaskMaker(); -function runWebdriver({file}) { - process.env.TEST_SERVER_HOST = argv.host || 'localhost'; - let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio'); - let wdioConf = path.join(__dirname, 'wdio.conf.js'); - let wdioOpts; - - if (file) { - wdioOpts = [ - wdioConf, - `--spec`, - `${file}` - ] - } else { - wdioOpts = [ - wdioConf - ]; - } - return execa(wdioCmd, wdioOpts, { stdio: 'inherit' }); -} - function newKarmaCallback(done) { return function (exitCode) { if (exitCode) { @@ -332,29 +335,41 @@ function buildPostbid() { .pipe(gulp.dest('build/postbid/')); } -function startIntegServer(dev = false) { - const args = ['./test/fake-server/index.js', `--port=${INTEG_SERVER_PORT}`, `--host=${INTEG_SERVER_HOST}`]; - if (dev) { - args.push('--dev=true') +function setupE2e(done) { + if (!argv.host) { + throw new gutil.PluginError({ + plugin: 'E2E test', + message: gutil.colors.red('Host should be defined e.g. ap.localhost, anlocalhost. localhost cannot be used as safari browserstack is not able to connect to localhost') + }); } - const srv = spawn('node', args); - srv.stdout.on('data', (data) => { + process.env.TEST_SERVER_HOST = argv.host; + if (argv.https) { + process.env.TEST_SERVER_PROTOCOL = argv.https; + } + argv.e2e = true; + done(); +} + +function injectFakeServerEndpoint() { + return gulp.src(['build/dist/*.js']) + .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`)) + .pipe(gulp.dest('build/dist')); +} + +function injectFakeServerEndpointDev() { + return gulp.src(['build/dev/*.js']) + .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`)) + .pipe(gulp.dest('build/dev')); +} + +function startFakeServer() { + const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]); + fakeServer.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); - srv.stderr.on('data', (data) => { + fakeServer.stderr.on('data', (data) => { console.log(`stderr: ${data}`); }); - return srv; -} - -function startLocalServer(options = {}) { - connect.server({ - https: argv.https, - port: port, - host: INTEG_SERVER_HOST, - root: './', - livereload: options.livereload - }); } // Watch Task with Live Reload @@ -370,7 +385,13 @@ function watchTaskMaker(options = {}) { 'modules/**/*.js', ].concat(options.alsoWatch)); - startLocalServer(options); + connect.server({ + https: argv.https, + port: port, + host: FAKE_SERVER_HOST, + root: './', + livereload: options.livereload + }); mainWatcher.on('all', options.task()); done(); @@ -406,13 +427,11 @@ gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid)); gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test))); gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast))); gulp.task('serve-and-test', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast, testTaskMaker({watch: true})))); -gulp.task('serve-e2e', gulp.series(clean, 'build-bundle-prod', gulp.parallel(() => startIntegServer(), startLocalServer))) -gulp.task('serve-e2e-dev', gulp.series(clean, 'build-bundle-dev', gulp.parallel(() => startIntegServer(true), startLocalServer))) +gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer)); gulp.task('default', gulp.series(clean, 'build-bundle-prod')); -gulp.task('e2e-test-only', () => runWebdriver({file: argv.file})) -gulp.task('e2e-test', gulp.series(clean, 'build-bundle-prod', testTaskMaker({e2e: true}))); +gulp.task('e2e-test', gulp.series(clean, setupE2e, gulp.parallel('build-bundle-prod', watch), injectFakeServerEndpoint, test)); // other tasks gulp.task(bundleToStdout); gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenating pre-built files with no build step diff --git a/modules/adomikAnalyticsAdapter.js b/modules/adomikAnalyticsAdapter.js index 40809c59093..44c0c6868cf 100644 --- a/modules/adomikAnalyticsAdapter.js +++ b/modules/adomikAnalyticsAdapter.js @@ -4,7 +4,7 @@ import adapterManager from '../src/adapterManager.js'; import {logInfo} from '../src/utils.js'; import {find, findIndex} from '../src/polyfill.js'; -// Events used in adomik analytics adapter. +// Events used in adomik analytics adapter const auctionInit = CONSTANTS.EVENTS.AUCTION_INIT; const auctionEnd = CONSTANTS.EVENTS.AUCTION_END; const bidRequested = CONSTANTS.EVENTS.BID_REQUESTED; @@ -30,13 +30,17 @@ let adomikAdapter = Object.assign(adapter({}), break; case bidResponse: - adomikAdapter.saveBidResponse(args); + adomikAdapter.bucketEvents.push({ + type: 'response', + event: adomikAdapter.buildBidResponse(args) + }); break; case bidWon: - args.id = args.adId; - args.placementCode = args.adUnitCode; - adomikAdapter.sendWonEvent(args); + adomikAdapter.sendWonEvent({ + id: args.adId, + placementCode: args.adUnitCode + }); break; case bidRequested: @@ -65,28 +69,16 @@ adomikAdapter.initializeBucketEvents = function() { adomikAdapter.bucketEvents = []; } -adomikAdapter.saveBidResponse = function(args) { - let responseSaved = adomikAdapter.bucketEvents.find((bucketEvent) => - bucketEvent.type == 'response' && bucketEvent.event.id == args.id - ); - if (responseSaved) { return true; } - adomikAdapter.bucketEvents.push({ - type: 'response', - event: adomikAdapter.buildBidResponse(args) - }); -} - adomikAdapter.maxPartLength = function () { return (ua.includes(' MSIE ')) ? 1600 : 60000; }; adomikAdapter.sendTypedEvent = function() { - let [testId, testValue] = adomikAdapter.getKeyValues(); const groupedTypedEvents = adomikAdapter.buildTypedEvents(); const bulkEvents = { - testId: testId, - testValue: testValue, + testId: adomikAdapter.currentContext.testId, + testValue: adomikAdapter.currentContext.testValue, uid: adomikAdapter.currentContext.uid, ahbaid: adomikAdapter.currentContext.id, hostname: window.location.hostname, @@ -122,8 +114,10 @@ adomikAdapter.sendTypedEvent = function() { const stringBulkEvents = JSON.stringify(bulkEvents) logInfo('Events sent to adomik prebid analytic ' + stringBulkEvents); + // Encode object in base64 const encodedBuf = window.btoa(stringBulkEvents); + // Create final url and split it (+endpoint length) const encodedUri = encodeURIComponent(encodedBuf); const maxLength = adomikAdapter.maxPartLength(); const splittedUrl = encodedUri.match(new RegExp(`.{1,${maxLength}}`, 'g')); @@ -136,18 +130,16 @@ adomikAdapter.sendTypedEvent = function() { }; adomikAdapter.sendWonEvent = function (wonEvent) { - let [testId, testValue] = adomikAdapter.getKeyValues(); - let keyValues = { testId: testId, testValue: testValue }; - let samplingInfo = { sampling: adomikAdapter.currentContext.sampling }; - wonEvent = { ...adomikAdapter.buildBidResponse(wonEvent), ...keyValues, ...samplingInfo }; - - const stringWonEvent = JSON.stringify(wonEvent); + let keyValues = { testId: adomikAdapter.currentContext.testId, testValue: adomikAdapter.currentContext.testValue } + wonEvent = {...wonEvent, ...keyValues} + const stringWonEvent = JSON.stringify(wonEvent) logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent); + // Encode object in base64 const encodedBuf = window.btoa(stringWonEvent); const encodedUri = encodeURIComponent(encodedBuf); const img = new Image(1, 1); - img.src = `https://${adomikAdapter.currentContext.url}/?q=${encodedUri}&id=${adomikAdapter.currentContext.id}&won=true`; + img.src = `https://${adomikAdapter.currentContext.url}/?q=${encodedUri}&id=${adomikAdapter.currentContext.id}&won=true` } adomikAdapter.buildBidResponse = function (bid) { @@ -209,49 +201,33 @@ adomikAdapter.buildTypedEvents = function () { return groupedTypedEvents; } -adomikAdapter.getKeyValues = function () { - let preventTest = sessionStorage.getItem(window.location.hostname + '_NoAdomikTest') - let inScope = sessionStorage.getItem(window.location.hostname + '_AdomikTestInScope') - let keyValues = JSON.parse(sessionStorage.getItem(window.location.hostname + '_AdomikTest')) - let testId; - let testValue; - if (typeof (keyValues) === 'object' && keyValues != undefined && !preventTest && inScope) { - testId = keyValues.testId - testValue = keyValues.testOptionLabel - } - return [testId, testValue] -} - -adomikAdapter.enable = function(options) { - adomikAdapter.currentContext = { - uid: options.id, - url: options.url, - id: '', - timeouted: false, - sampling: options.sampling - } - logInfo('Adomik Analytics enabled with config', options); - adomikAdapter.adapterEnableAnalytics(options); -}; - -adomikAdapter.checkOptions = function(options) { - if (typeof options !== 'undefined') { - if (options.id && options.url) { adomikAdapter.enable(options); } else { logInfo('Adomik Analytics disabled because id and/or url is missing from config', options); } - } else { logInfo('Adomik Analytics disabled because config is missing'); } -}; - -adomikAdapter.checkSampling = function(options) { - _sampled = typeof options === 'undefined' || - typeof options.sampling === 'undefined' || - (options.sampling > 0 && Math.random() < parseFloat(options.sampling)); - if (_sampled) { adomikAdapter.checkOptions(options) } else { logInfo('Adomik Analytics ignored for sampling', options.sampling); } -}; - adomikAdapter.adapterEnableAnalytics = adomikAdapter.enableAnalytics; -adomikAdapter.enableAnalytics = function ({ provider, options }) { - logInfo('Adomik Analytics enableAnalytics', provider); - adomikAdapter.checkSampling(options); +adomikAdapter.enableAnalytics = function (config) { + adomikAdapter.currentContext = {}; + const initOptions = config.options; + + _sampled = typeof config === 'undefined' || + typeof config.sampling === 'undefined' || + Math.random() < parseFloat(config.sampling); + + if (_sampled) { + if (initOptions) { + adomikAdapter.currentContext = { + uid: initOptions.id, + url: initOptions.url, + testId: initOptions.testId, + testValue: initOptions.testValue, + id: '', + timeouted: false, + sampling: config.sampling + } + logInfo('Adomik Analytics enabled with config', initOptions); + adomikAdapter.adapterEnableAnalytics(config); + } + } else { + logInfo('Adomik Analytics ignored for sampling', config.sampling); + } }; adapterManager.registerAnalyticsAdapter({ diff --git a/modules/adotBidAdapter.js b/modules/adotBidAdapter.js index ac49f7ae32d..a28ab4257df 100644 --- a/modules/adotBidAdapter.js +++ b/modules/adotBidAdapter.js @@ -10,7 +10,7 @@ const BIDDER_CODE = 'adot'; const ADAPTER_VERSION = 'v2.0.0'; const BID_METHOD = 'POST'; const BIDDER_URL = 'https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest'; -const REQUIRED_VIDEO_PARAMS = ['mimes', 'protocols']; +const REQUIRED_VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols']; const DOMAIN_REGEX = new RegExp('//([^/]*)'); const FIRST_PRICE = 1; const IMP_BUILDER = { banner: buildBanner, video: buildVideo, native: buildNative }; diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index 6710448f00e..1a0074e668b 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -488,8 +488,6 @@ function createBid(response, bidRequests) { // retreive video response if present const vast64 = response.Vast || getVideoAd(response); if (vast64) { - bid.width = response.Width; - bid.height = response.Height; bid.vastXml = window.atob(vast64); bid.mediaType = 'video'; } else if (request.Native) { diff --git a/modules/apacdexBidAdapter.js b/modules/apacdexBidAdapter.js index d7b6b7c4020..421eb99b4c1 100644 --- a/modules/apacdexBidAdapter.js +++ b/modules/apacdexBidAdapter.js @@ -2,9 +2,22 @@ import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn } from '. import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'apacdex'; -const ENDPOINT = 'https://useast.quantumdex.io/auction/pbjs' -const USERSYNC = 'https://sync.quantumdex.io/usersync/pbjs' +const CONFIG = { + 'apacdex': { + 'ENDPOINT': 'https://useast.quantumdex.io/auction/apacdex', + 'USERSYNC': 'https://sync.quantumdex.io/usersync/apacdex' + }, + 'quantumdex': { + 'ENDPOINT': 'https://useast.quantumdex.io/auction/quantumdex', + 'USERSYNC': 'https://sync.quantumdex.io/usersync/quantumdex' + }, + 'valueimpression': { + 'ENDPOINT': 'https://useast.quantumdex.io/auction/adapter', + 'USERSYNC': 'https://sync.quantumdex.io/usersync/adapter' + } +}; +var bidderConfig = CONFIG[BIDDER_CODE]; var bySlotTargetKey = {}; var bySlotSizesCount = {} @@ -43,6 +56,8 @@ export const spec = { let test; let bids = []; + bidderConfig = CONFIG[validBidRequests[0].bidder]; + test = config.getConfig('debug'); validBidRequests.forEach(bidReq => { @@ -141,14 +156,13 @@ export const spec = { transactionId: bid.transactionId, sizes: bid.sizes, bidId: bid.bidId, - adUnitCode: bid.adUnitCode, bidFloor: bid.bidFloor } }); return { method: 'POST', - url: ENDPOINT, + url: bidderConfig.ENDPOINT, data: payload, withCredentials: true, bidderRequests: bids @@ -195,47 +209,32 @@ export const spec = { }); return bidResponses; }, - getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) { + getUserSyncs: function (syncOptions, serverResponses) { const syncs = []; - if (hasPurpose1Consent(gdprConsent)) { - let params = ''; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - params = `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params = `?gdpr_consent=${gdprConsent.consentString}`; - } + try { + if (syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe', + url: bidderConfig.USERSYNC + }); } - if (uspConsent) { - params += `${params ? '&' : '?'}us_privacy=${encodeURIComponent(uspConsent)}`; + if (serverResponses.length > 0 && serverResponses[0].body && serverResponses[0].body.pixel) { + serverResponses[0].body.pixel.forEach(px => { + if (px.type === 'image' && syncOptions.pixelEnabled) { + syncs.push({ + type: 'image', + url: px.url + }); + } + if (px.type === 'iframe' && syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe', + url: px.url + }); + } + }); } - - try { - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: USERSYNC + params - }); - } - if (serverResponses.length > 0 && serverResponses[0].body && serverResponses[0].body.pixel) { - serverResponses[0].body.pixel.forEach(px => { - if (px.type === 'image' && syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: px.url + params - }); - } - if (px.type === 'iframe' && syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: px.url + params - }); - } - }); - } - } catch (e) { } - } + } catch (e) { } return syncs; } }; @@ -378,14 +377,4 @@ function getBidFloor(bid) { return null; } -function hasPurpose1Consent(gdprConsent) { - let result = true; - if (gdprConsent) { - if (gdprConsent.gdprApplies && gdprConsent.apiVersion === 2) { - result = !!(deepAccess(gdprConsent, 'vendorData.purpose.consents.1') === true); - } - } - return result; -} - registerBidder(spec); diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js index 2744e38e820..2c100bce27b 100644 --- a/modules/audiencerunBidAdapter.js +++ b/modules/audiencerunBidAdapter.js @@ -1,30 +1,32 @@ -import { - deepAccess, - isFn, - logError, - getValue, - getBidIdParameter, - _each, - isArray, - triggerPixel, - formatQS, -} from '../src/utils.js'; +import { deepAccess, isFn, logError, getValue, getBidIdParameter, _each, isArray, triggerPixel } from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import { createEidsArray } from './userId/eids.js'; const BIDDER_CODE = 'audiencerun'; const BASE_URL = 'https://d.audiencerun.com'; const AUCTION_URL = `${BASE_URL}/prebid`; const TIMEOUT_EVENT_URL = `${BASE_URL}/ps/pbtimeout`; -const ERROR_EVENT_URL = `${BASE_URL}/js_log`; const DEFAULT_CURRENCY = 'USD'; let requestedBids = []; /** - * Returns bidfloor through floors module if available. + * Gets bidder request referer + * + * @param {Object} bidderRequest + * @return {string} + */ +function getPageUrl(bidderRequest) { + return ( + config.getConfig('pageUrl') || + deepAccess(bidderRequest, 'refererInfo.referer') || + null + ); +} + +/** + * Returns bidfloor through floors module if available * * @param {Object} bid * @returns {number} @@ -42,53 +44,19 @@ function getBidFloor(bid) { }); return bidFloor.floor; } catch (_) { - return 0; + return 0 } } -/** - * Returns the most top page referer. - * - * @returns {string} - */ -function getPageReferer() { - let t, e; - do { - t = t ? t.parent : window; - try { - e = t.document.referrer; - } catch (_) { - break; - } - } while (t !== window.top); - return e; -} - -/** - * Returns bidder request page url. - * - * @param {Object} bidderRequest - * @return {string} - */ -function getPageUrl(bidderRequest) { - return ( - config.getConfig('pageUrl') || - deepAccess(bidderRequest, 'refererInfo.referer') || - getPageReferer() || - null - ); -} - export const spec = { - version: '1.2.0', + version: '1.1.0', code: BIDDER_CODE, - gvlid: 944, supportedMediaTypes: [BANNER], /** * Determines whether or not the given bid request is valid. * - * @param {BidRequest} bid The bid params to validate. + * @param {object} bid The bid to validate. * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { @@ -127,19 +95,12 @@ export const spec = { const payload = { libVersion: this.version, - pageUrl: config.getConfig('pageUrl'), - pageReferer: getPageReferer(), - referer: deepAccess(bidderRequest, 'refererInfo.referer'), - refererInfo: deepAccess(bidderRequest, 'refererInfo'), + referer: getPageUrl(bidderRequest), currencyCode: config.getConfig('currency.adServerCurrency'), timeout: config.getConfig('bidderTimeout'), bids, }; - payload.uspConsent = deepAccess(bidderRequest, 'uspConsent'); - payload.schain = deepAccess(bidRequests, '0.schain'); - payload.userId = deepAccess(bidRequests, '0.userId') ? createEidsArray(bidRequests[0].userId) : []; - if (bidderRequest && bidderRequest.gdprConsent) { payload.gdpr = { consent: bidderRequest.gdprConsent.consentString, @@ -156,7 +117,7 @@ export const spec = { return { method: 'POST', - url: deepAccess(bidRequests, '0.params.auctionUrl', AUCTION_URL), + url: AUCTION_URL, data: JSON.stringify(payload), options: { withCredentials: true, @@ -240,9 +201,7 @@ export const spec = { } timeoutData.forEach((bid) => { - const bidOnTimeout = requestedBids.find( - (requestedBid) => requestedBid.bidId === bid.bidId - ); + const bidOnTimeout = requestedBids.find((requestedBid) => requestedBid.bidId === bid.bidId); if (bidOnTimeout) { triggerPixel( @@ -251,18 +210,6 @@ export const spec = { } }); }, - - /** - * Registers bidder specific code, which will execute if the bidder responded with an error. - * @param {{bidderRequest: object}} args An object from which we extract bidderRequest object. - */ - onBidderError: function ({ bidderRequest }) { - const queryString = formatQS({ - message: `Prebid.js: Server call for ${bidderRequest.bidderCode} failed.`, - url: encodeURIComponent(getPageUrl(bidderRequest)), - }); - triggerPixel(`${ERROR_EVENT_URL}/?${queryString}`); - }, }; registerBidder(spec); diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js index e4907c15974..acf574a3fe2 100644 --- a/modules/betweenBidAdapter.js +++ b/modules/betweenBidAdapter.js @@ -53,7 +53,7 @@ export const spec = { params.maxd = video.maxd; params.mind = video.mind; params.pos = 'atf'; - params.jst = 'pvc'; + ENDPOINT += '&jst=pvc'; params.codeType = includes(CODE_TYPES, video.codeType) ? video.codeType : 'inpage'; } diff --git a/modules/cointrafficBidAdapter.js b/modules/cointrafficBidAdapter.js index f61d58664ca..e3d3c65a4f0 100644 --- a/modules/cointrafficBidAdapter.js +++ b/modules/cointrafficBidAdapter.js @@ -4,7 +4,7 @@ import { BANNER } from '../src/mediaTypes.js' import { config } from '../src/config.js' const BIDDER_CODE = 'cointraffic'; -const ENDPOINT_URL = 'https://apps-pbd.ctengine.io/pb/tmp'; +const ENDPOINT_URL = 'https://appspb.cointraffic.io/pb/tmp'; const DEFAULT_CURRENCY = 'EUR'; const ALLOWED_CURRENCIES = [ 'EUR', 'USD', 'JPY', 'BGN', 'CZK', 'DKK', 'GBP', 'HUF', 'PLN', 'RON', 'SEK', 'CHF', 'ISK', 'NOK', 'HRK', 'RUB', 'TRY', diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js index fec0d1b6510..c1b6e31ff2e 100644 --- a/modules/colossussspBidAdapter.js +++ b/modules/colossussspBidAdapter.js @@ -112,6 +112,7 @@ export const spec = { placementId: bid.params.placement_id, groupId: bid.params.group_id, bidId: bid.bidId, + sizes: bid.mediaTypes[traff].sizes, traffic: traff, eids: [], floor: {} @@ -145,12 +146,7 @@ export const spec = { rtiPartner: 'TDID' }); } - if (traff === BANNER) { - placement.sizes = bid.mediaTypes[BANNER].sizes - } - if (traff === VIDEO) { - placement.sizes = bid.mediaTypes[VIDEO].playerSize; placement.playerSize = bid.mediaTypes[VIDEO].playerSize; placement.minduration = bid.mediaTypes[VIDEO].minduration; placement.maxduration = bid.mediaTypes[VIDEO].maxduration; diff --git a/modules/consentManagement.js b/modules/consentManagement.js index 5fbcc0f8ac1..f0355749055 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -36,8 +36,8 @@ const cmpCallMap = { * This function reads the consent string from the config to obtain the consent information of the user. * @param {function({})} onSuccess acts as a success callback when the value is read from config; pass along consentObject from CMP */ -function lookupStaticConsentData({onSuccess, onError}) { - processCmpData(staticConsentData, {onSuccess, onError}) +function lookupStaticConsentData({onSuccess}) { + onSuccess(staticConsentData); } /** @@ -335,8 +335,8 @@ export function requestBidsHook(fn, reqBidsConfigObj) { let height = 1; if (Array.isArray(adUnits) && adUnits.length > 0) { let sizes = getAdUnitSizes(adUnits[0]); - width = sizes?.[0]?.[0] || 1; - height = sizes?.[0]?.[1] || 1; + width = sizes[0][0]; + height = sizes[0][1]; } return function (cb) { diff --git a/modules/consentManagementUsp.js b/modules/consentManagementUsp.js index d6bf913b366..e98b41d5c9e 100644 --- a/modules/consentManagementUsp.js +++ b/modules/consentManagementUsp.js @@ -28,8 +28,8 @@ const uspCallMap = { /** * This function reads the consent string from the config to obtain the consent information of the user. */ -function lookupStaticConsentData({onSuccess, onError}) { - processUspData(staticConsentData, {onSuccess, onError}); +function lookupStaticConsentData({onSuccess}) { + onSuccess(staticConsentData); } /** diff --git a/modules/currency.js b/modules/currency.js index 7f88c4b0aeb..a59a9880af1 100644 --- a/modules/currency.js +++ b/modules/currency.js @@ -168,8 +168,6 @@ function initCurrency(url) { } } ); - } else { - ready.done(); } } diff --git a/modules/debugging/pbsInterceptor.js b/modules/debugging/pbsInterceptor.js index c8de1ed9753..5af2384cad9 100644 --- a/modules/debugging/pbsInterceptor.js +++ b/modules/debugging/pbsInterceptor.js @@ -1,6 +1,6 @@ import {deepClone, delayExecution} from '../../src/utils.js'; import {createBid} from '../../src/bidfactory.js'; -import {default as CONSTANTS} from '../../src/constants.json'; +import * as CONSTANTS from '../../src/constants.json'; export function pbsBidInterceptor (next, interceptBids, s2sBidRequest, bidRequests, ajax, { onResponse, diff --git a/modules/e_volutionBidAdapter.js b/modules/e_volutionBidAdapter.js index 63332db8725..884c4f0c067 100644 --- a/modules/e_volutionBidAdapter.js +++ b/modules/e_volutionBidAdapter.js @@ -41,19 +41,6 @@ function getBidFloor(bid) { } } -function getUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); - } -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], @@ -99,12 +86,7 @@ export const spec = { const placement = { placementId: bid.params.placementId, bidId: bid.bidId, - bidfloor: getBidFloor(bid), - eids: [] - } - - if (bid.userId) { - getUserId(placement.eids, bid.userId.id5id, 'id5-sync.com'); + bidfloor: getBidFloor(bid) } if (bid.mediaTypes && bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { diff --git a/modules/ftrackIdSystem.js b/modules/ftrackIdSystem.js index 21206109ee0..c570e69e1d3 100644 --- a/modules/ftrackIdSystem.js +++ b/modules/ftrackIdSystem.js @@ -73,6 +73,8 @@ export const ftrackIdSubmodule = { CCampID: '148556' }; window.D9r = { + DeviceID: true, + SingleDeviceID: true, callback: function(response) { if (response) { storage.setDataInLocalStorage(`${FTRACK_STORAGE_NAME}_exp`, (new Date(Date.now() + (1000 * 60 * 60 * 24 * LOCAL_STORAGE_EXP_DAYS))).toUTCString()); @@ -86,22 +88,6 @@ export const ftrackIdSubmodule = { } }; - // If config.params.ids does not exist, set defaults - if (!config.params.hasOwnProperty('ids')) { - window.D9r.DeviceID = true; - window.D9r.SingleDeviceID = true; - } else { - if (config.params.ids.hasOwnProperty('device id') && config.params.ids['device id'] === true) { - window.D9r.DeviceID = true; - } - if (config.params.ids.hasOwnProperty('single device id') && config.params.ids['single device id'] === true) { - window.D9r.SingleDeviceID = true; - } - if (config.params.ids.hasOwnProperty('household id') && config.params.ids['household id'] === true) { - window.D9r.HHID = true; - } - } - if (config.params && config.params.url && config.params.url === FTRACK_URL) { var ftrackScript = document.createElement('script'); ftrackScript.setAttribute('src', config.params.url); diff --git a/modules/ftrackIdSystem.md b/modules/ftrackIdSystem.md index 0c92f5afab1..c5f255c2fc2 100644 --- a/modules/ftrackIdSystem.md +++ b/modules/ftrackIdSystem.md @@ -30,12 +30,7 @@ pbjs.setConfig({ userIds: [{ name: 'FTrack', params: { - url: 'https://d9.flashtalking.com/d9core', // required, if not populated ftrack will not run - ids: { - 'device id': true, - 'single device id': true, - 'household id': true - } + url: 'https://d9.flashtalking.com/d9core' // required, if not populated ftrack will not run }, storage: { type: 'html5', // "html5" is the required storage type @@ -52,12 +47,6 @@ pbjs.setConfig({ | Param under userSync.userIds[] | Scope | Type | Description | Example | | :-- | :-- | :-- | :-- | :-- | | name | Required | String | The name of this module: `"FTrack"` | `"FTrack"` | -| params | Required | Object | The IDs available, if not populated then the defaults "Device ID" and "Single Device ID" will be returned | | -| params.url | Required | String | The URL for the ftrack library reference. If not populate, ftrack will not run. | 'https://d9.flashtalking.com/d9core' | -| params.ids | Optional | Object | The ftrack IDs available, if not populated then the defaults "Device ID" and "Single Device ID" will be returned | | -| params.ids['device id'] | Optional | Boolean | Should ftrack return "device id". Set to `true` to return it. If set to `undefined` or `false`, ftrack will not return "device id". Default is `false` | `true` | -| params.ids['single device id'] | Optional | Boolean | Should ftrack return "single device id". Set to `true` to return it. If set to `undefined` or `false`, ftrack will not return "single device id". Default is `false` | `true` | -| params.ids['household id'] | Optional; _Requires pairing with either "device id" or "single device id"_ | Boolean | __1.__ Should ftrack return "household id". Set to `true` to attempt to return it. If set to `undefined` or `false`, ftrack will not return "household id". Default is `false`. __2.__ _This will only return "household id" if value of this field is `true` **AND** "household id" is defined on the device._ __3.__ _"household id" requires either "device id" or "single device id" to be also set to `true`, otherwise ftrack will not return "household id"._ | `true` | | storage | Required | Object | Storage settings for how the User ID module will cache the FTrack ID locally | | | storage.type | Required | String | This is where the results of the user ID will be stored. FTrack **requires** `"html5"`. | `"html5"` | | storage.name | Required | String | The name of the local storage where the user ID will be stored. FTrack **requires** `"FTrackId"`. | `"FTrackId"` | diff --git a/modules/malltvAnalyticsAdapter.js b/modules/malltvAnalyticsAdapter.js index a0e2a208bc9..3431681ef2f 100644 --- a/modules/malltvAnalyticsAdapter.js +++ b/modules/malltvAnalyticsAdapter.js @@ -184,5 +184,5 @@ malltvAnalyticsAdapter.enableAnalytics = function (config) { adapterManager.registerAnalyticsAdapter({ adapter: malltvAnalyticsAdapter, - code: 'malltv' + code: 'malltvAnalytics' }) diff --git a/modules/mobfoxpbBidAdapter.js b/modules/mobfoxpbBidAdapter.js deleted file mode 100644 index a4af7133370..00000000000 --- a/modules/mobfoxpbBidAdapter.js +++ /dev/null @@ -1,135 +0,0 @@ -import { isFn, deepAccess, getWindowTop } from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'mobfoxpb'; -const AD_URL = 'https://bes.mobfox.com/pbjs'; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers); - default: - return false; - } -} - -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - - try { - const bidFloor = bid.getFloor({ - currency: 'USD', - mediaType: '*', - size: '*', - }); - return bidFloor.floor; - } catch (_) { - return 0 - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && bid.params.placementId); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - const winTop = getWindowTop(); - const location = winTop.location; - const placements = []; - const request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const placement = { - placementId: bid.params.placementId, - bidId: bid.bidId, - schain: bid.schain || {}, - bidfloor: getBidFloor(bid) - }; - const mediaType = bid.mediaTypes - - if (mediaType && mediaType[BANNER] && mediaType[BANNER].sizes) { - placement.traffic = BANNER; - placement.sizes = mediaType[BANNER].sizes; - } else if (mediaType && mediaType[VIDEO] && mediaType[VIDEO].playerSize) { - placement.traffic = VIDEO; - placement.wPlayer = mediaType[VIDEO].playerSize[0]; - placement.hPlayer = mediaType[VIDEO].playerSize[1]; - placement.playerSize = mediaType[VIDEO].playerSize; - placement.minduration = mediaType[VIDEO].minduration; - placement.maxduration = mediaType[VIDEO].maxduration; - placement.mimes = mediaType[VIDEO].mimes; - placement.protocols = mediaType[VIDEO].protocols; - placement.startdelay = mediaType[VIDEO].startdelay; - placement.placement = mediaType[VIDEO].placement; - placement.skip = mediaType[VIDEO].skip; - placement.skipafter = mediaType[VIDEO].skipafter; - placement.minbitrate = mediaType[VIDEO].minbitrate; - placement.maxbitrate = mediaType[VIDEO].maxbitrate; - placement.delivery = mediaType[VIDEO].delivery; - placement.playbackmethod = mediaType[VIDEO].playbackmethod; - placement.api = mediaType[VIDEO].api; - placement.linearity = mediaType[VIDEO].linearity; - } else if (mediaType && mediaType[NATIVE]) { - placement.traffic = NATIVE; - placement.native = mediaType[NATIVE]; - } - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - resItem.meta = resItem.meta || {}; - resItem.meta.advertiserDomains = resItem.adomain || []; - - response.push(resItem); - } - } - return response; - }, -}; - -registerBidder(spec); diff --git a/modules/mobfoxpbBidAdapter.md b/modules/mobfoxpbBidAdapter.md index f434b2792a9..6eb549919d7 100644 --- a/modules/mobfoxpbBidAdapter.md +++ b/modules/mobfoxpbBidAdapter.md @@ -24,7 +24,7 @@ Module that connects to mobfox demand sources { bidder: 'mobfoxpb', params: { - placementId: 'testBanner' + placementId: 0 } } ] @@ -41,7 +41,7 @@ Module that connects to mobfox demand sources { bidder: 'mobfoxpb', params: { - placementId: 'testVideo' + placementId: 0 } } ] @@ -63,7 +63,7 @@ Module that connects to mobfox demand sources { bidder: 'mobfoxpb', params: { - placementId: 'testNative' + placementId: 0 } } ] diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 91508d38ca0..365d692e614 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -1,10 +1,9 @@ -import { isStr, _each, parseUrl, getWindowTop, getBidIdParameter } from '../src/utils.js'; +import { isStr, _each, getBidIdParameter } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; -const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction'; const SYNC_ENDPOINT = 'https://statics.nextmillmedia.com/load-cookie.html?v=4'; const TIME_TO_LIVE = 360; @@ -62,12 +61,9 @@ export const spec = { } } - const urlParameters = parseUrl(getWindowTop().location.href).search; - const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; - requests.push({ method: 'POST', - url: isTest ? TEST_ENDPOINT : ENDPOINT, + url: ENDPOINT, data: JSON.stringify(postBody), options: { contentType: 'application/json', diff --git a/modules/nexx360BidAdapter.js b/modules/nexx360BidAdapter.js index 814a2f55299..0689d3b04ce 100644 --- a/modules/nexx360BidAdapter.js +++ b/modules/nexx360BidAdapter.js @@ -1,6 +1,5 @@ import {ajax} from '../src/ajax.js'; import {config} from '../src/config.js'; -import { transformBidderParamKeywords } from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; @@ -9,11 +8,8 @@ const BIDDER_URL = 'https://fast.nexx360.io/prebid'; const CACHE_URL = 'https://fast.nexx360.io/cache'; const METRICS_TRACKER_URL = 'https://fast.nexx360.io/track-imp'; -const GVLID = 965; - export const spec = { code: BIDDER_CODE, - gvlid: GVLID, aliases: ['revenuemaker'], // short code supportedMediaTypes: [BANNER, VIDEO], /** @@ -23,9 +19,6 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function(bid) { - if (!!bid.params.bidfloorCurrency && !['EUR', 'USD'].includes(bid.params.bidfloorCurrency)) return false; - if (!!bid.params.bidfloor && typeof bid.params.bidfloor !== 'number') return false; - if (!!bid.params.keywords && typeof bid.params.keywords !== 'object') return false; return !!(bid.params.account && bid.params.tagId); }, /** @@ -41,7 +34,7 @@ export const spec = { let userEids = null; Object.keys(validBidRequests).forEach(key => { adunitValue = validBidRequests[key]; - const foo = { + adUnits.push({ account: adunitValue.params.account, tagId: adunitValue.params.tagId, videoExt: adunitValue.params.videoExt, @@ -49,12 +42,8 @@ export const spec = { bidId: adunitValue.bidId, auctionId: adunitValue.auctionId, transactionId: adunitValue.transactionId, - mediatypes: adunitValue.mediaTypes, - bidfloor: adunitValue.params.bidfloor || 0, - bidfloorCurrency: adunitValue.params.bidfloorCurrency || 'USD', - keywords: adunitValue.params.keywords ? transformBidderParamKeywords(adunitValue.params.keywords) : [], - } - adUnits.push(foo); + mediatypes: adunitValue.mediaTypes + }); if (adunitValue.userIdAsEids) userEids = adunitValue.userIdAsEids; }); const payload = { @@ -89,6 +78,7 @@ export const spec = { */ interpretResponse: function(serverResponse, bidRequest) { const serverBody = serverResponse.body; + // const headerValue = serverResponse.headers.get('some-response-header'); const bidResponses = []; let bidResponse = null; let value = null; diff --git a/modules/otmBidAdapter.js b/modules/otmBidAdapter.js index e81bdfa9e6a..a0e91a480a2 100644 --- a/modules/otmBidAdapter.js +++ b/modules/otmBidAdapter.js @@ -1,21 +1,10 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { - logInfo, - logError, - getBidIdParameter, - _each, - getValue, - isFn, - isPlainObject, - isArray, - isStr, - isNumber, -} from '../src/utils.js'; +import {logInfo, logError, getBidIdParameter, _each, getValue, isFn, isPlainObject} from '../src/utils.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'otm'; const OTM_BID_URL = 'https://ssp.otm-r.com/adjson'; -const DEFAULT_CURRENCY = 'RUB' +const DEF_CUR = 'RUB' export const spec = { @@ -30,7 +19,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { - return Boolean(bid.params.tid); + return !!bid.params.tid; }, /** @@ -44,41 +33,43 @@ export const spec = { logInfo('validBidRequests', validBidRequests); const bidRequests = []; - const tz = new Date().getTimezoneOffset() - const referrer = bidderRequest && bidderRequest.refererInfo ? bidderRequest.refererInfo.referer : ''; + let tz = new Date().getTimezoneOffset() + let referrer = ''; + if (bidderRequest && bidderRequest.refererInfo) { + referrer = bidderRequest.refererInfo.referer; + } _each(validBidRequests, (bid) => { - let topOrigin = '' - try { - if (isStr(referrer)) topOrigin = new URL(referrer).host - } catch (e) { /* do nothing */ } - const domain = isStr(bid.params.domain) ? bid.params.domain : topOrigin - const cur = getValue(bid.params, 'currency') || DEFAULT_CURRENCY - const bidid = getBidIdParameter('bidId', bid) - const transactionid = getBidIdParameter('transactionId', bid) - const auctionid = getBidIdParameter('auctionId', bid) - const bidfloor = _getBidFloor(bid) + let domain = getValue(bid.params, 'domain') || '' + let tid = getValue(bid.params, 'tid') + let cur = getValue(bid.params, 'currency') || DEF_CUR + let bidid = getBidIdParameter('bidId', bid) + let transactionid = getBidIdParameter('transactionId', bid) + let auctionid = getBidIdParameter('auctionId', bid) + let bidfloor = _getBidFloor(bid) _each(bid.sizes, size => { - const hasSizes = isArray(size) && isNumber(size[0]) && isNumber(size[1]) - const width = hasSizes ? size[0] : 0; - const height = hasSizes ? size[1] : 0; - + let width = 0; + let height = 0; + if (size.length && typeof size[0] === 'number' && typeof size[1] === 'number') { + width = size[0]; + height = size[1]; + } bidRequests.push({ method: 'GET', url: OTM_BID_URL, data: { - tz, + tz: tz, w: width, h: height, - domain, + domain: domain, l: referrer, - s: bid.params.tid, - cur, - bidid, - transactionid, - auctionid, - bidfloor, + s: tid, + cur: cur, + bidid: bidid, + transactionid: transactionid, + auctionid: auctionid, + bidfloor: bidfloor, }, }) }) @@ -90,9 +81,10 @@ export const spec = { * Generate response. * * @param serverResponse + * @param request * @returns {[]|*[]} */ - interpretResponse: function (serverResponse) { + interpretResponse: function (serverResponse, request) { logInfo('serverResponse', serverResponse.body); const responsesBody = serverResponse ? serverResponse.body : {}; @@ -110,7 +102,7 @@ export const spec = { width: bid.w, height: bid.h, creativeId: bid.creativeid, - currency: bid.currency || DEFAULT_CURRENCY, + currency: bid.currency || 'RUB', netRevenue: true, ad: bid.ad, ttl: bid.ttl, @@ -140,12 +132,12 @@ function _getBidFloor(bid) { return bid.params.bidfloor ? bid.params.bidfloor : 0; } - const floor = bid.getFloor({ - currency: DEFAULT_CURRENCY, + let floor = bid.getFloor({ + currency: DEF_CUR, mediaType: '*', size: '*' }); - if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === DEFAULT_CURRENCY) { + if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === DEF_CUR) { return floor.floor; } return 0; diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 62f550eb216..d30fd5bf810 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -38,7 +38,6 @@ import {find, includes} from '../../src/polyfill.js'; import { S2S_VENDORS } from './config.js'; import { ajax } from '../../src/ajax.js'; import {hook} from '../../src/hook.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; const getConfig = config.getConfig; @@ -756,64 +755,21 @@ Object.assign(ORTB2.prototype, { deepSetValue(imp, 'ext.prebid.storedauctionresponse.id', storedAuctionResponseBid.storedAuctionResponse.toString()); } - const floor = (() => { - // we have to pick a floor for the imp - here we attempt to find the minimum floor - // across all bids for this adUnit - - const convertCurrency = typeof getGlobal().convertCurrency !== 'function' - ? (amount) => amount - : (amount, from, to) => { - if (from === to) return amount; - let result = null; - try { - result = getGlobal().convertCurrency(amount, from, to); - } catch (e) { - } - return result; - } - const s2sCurrency = config.getConfig('currency.adServerCurrency') || DEFAULT_S2S_CURRENCY; - - return adUnit.bids - .map((bid) => this.getBidRequest(imp.id, bid.bidder)) - .map((bid) => { - if (!bid || typeof bid.getFloor !== 'function') return; - try { - const {currency, floor} = bid.getFloor({ - currency: s2sCurrency - }); - return { - currency, - floor: parseFloat(floor) - } - } catch (e) { - logError('PBS: getFloor threw an error: ', e); - } - }) - .reduce((min, floor) => { - // if any bid does not have a valid floor, do not attempt to send any to PBS - if (floor == null || floor.currency == null || floor.floor == null || isNaN(floor.floor)) { - min.min = null; - } - if (min.min === null) { - return min; - } - // otherwise, pick the minimum one (or, in some strange confluence of circumstances, the one in the best currency) - if (min.ref == null) { - min.ref = min.min = floor; - } else { - const value = convertCurrency(floor.floor, floor.currency, min.ref.currency); - if (value != null && value < min.ref.floor) { - min.ref.floor = value; - min.min = floor; - } - } - return min; - }, {}).min - })(); + const getFloorBid = find(firstBidRequest.bids, bid => bid.adUnitCode === adUnit.code && typeof bid.getFloor === 'function'); - if (floor) { - imp.bidfloor = floor.floor; - imp.bidfloorcur = floor.currency + if (getFloorBid) { + let floorInfo; + try { + floorInfo = getFloorBid.getFloor({ + currency: config.getConfig('currency.adServerCurrency') || DEFAULT_S2S_CURRENCY, + }); + } catch (e) { + logError('PBS: getFloor threw an error: ', e); + } + if (floorInfo && floorInfo.currency && !isNaN(parseFloat(floorInfo.floor))) { + imp.bidfloor = parseFloat(floorInfo.floor); + imp.bidfloorcur = floorInfo.currency + } } if (imp.banner || imp.video || imp.native) { diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index d64c6092afa..0667ac0fc74 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -977,25 +977,6 @@ function _blockedIabCategoriesValidation(payload, blockedIabCategories) { } } -function _allowedIabCategoriesValidation(payload, allowedIabCategories) { - allowedIabCategories = allowedIabCategories - .filter(function(category) { - if (typeof category === 'string') { // returns only strings - return true; - } else { - logWarn(LOG_WARN_PREFIX + 'acat: Each category should be a string, ignoring category: ' + category); - return false; - } - }) - .map(category => category.trim()) // trim all categories - .filter((category, index, arr) => arr.indexOf(category) === index); // return unique values only - - if (allowedIabCategories.length > 0) { - logWarn(LOG_WARN_PREFIX + 'acat: Selected: ', allowedIabCategories); - payload.ext.acat = allowedIabCategories; - } -} - function _assignRenderer(newBid, request) { let bidParams, context, adUnitCode; if (request.bidderRequest && request.bidderRequest.bids) { @@ -1101,7 +1082,6 @@ export const spec = { var dctrArr = []; var bid; var blockedIabCategories = []; - var allowedIabCategories = []; validBidRequests.forEach(originalBid => { bid = deepClone(originalBid); @@ -1133,9 +1113,6 @@ export const spec = { if (bid.params.hasOwnProperty('bcat') && isArray(bid.params.bcat)) { blockedIabCategories = blockedIabCategories.concat(bid.params.bcat); } - if (bid.params.hasOwnProperty('acat') && isArray(bid.params.acat)) { - allowedIabCategories = allowedIabCategories.concat(bid.params.acat); - } var impObj = _createImpressionObject(bid, conf); if (impObj) { payload.imp.push(impObj); @@ -1205,7 +1182,7 @@ export const spec = { } _handleEids(payload, validBidRequests); - + _blockedIabCategoriesValidation(payload, blockedIabCategories); _handleFlocId(payload, validBidRequests); // First Party Data const commonFpd = config.getConfig('ortb2') || {}; @@ -1215,16 +1192,7 @@ export const spec = { if (commonFpd.user) { mergeDeep(payload, {user: commonFpd.user}); } - if (commonFpd.bcat) { - blockedIabCategories = blockedIabCategories.concat(commonFpd.bcat) - } - if (commonFpd.ext?.prebid?.bidderparams?.[bidderRequest.bidderCode]?.acat) { - const acatParams = commonFpd.ext.prebid.bidderparams[bidderRequest.bidderCode].acat; - _allowedIabCategoriesValidation(payload, acatParams); - } else if (allowedIabCategories.length) { - _allowedIabCategoriesValidation(payload, allowedIabCategories); - } - _blockedIabCategoriesValidation(payload, blockedIabCategories); + // Note: Do not move this block up // if site object is set in Prebid config then we need to copy required fields from site into app and unset the site object if (typeof config.getConfig('app') === 'object') { diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index a071cdfea80..05dcf15909a 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -8,7 +8,7 @@ import { config } from '../src/config.js'; const BIDDER_CODE = 'seedingAlliance'; const DEFAULT_CUR = 'EUR'; -const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb'; +const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=nativendo'; const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon'}; @@ -124,8 +124,7 @@ export const spec = { user: {}, regs: { ext: { - gdpr: 0, - pb_ver: '$prebid.version$' + gdpr: 0 } } }; @@ -188,14 +187,11 @@ registerBidder(spec); function parseNative(bid) { const {assets, link, imptrackers} = bid.adm.native; - let clickUrl = link.url.replace(/\$\{AUCTION_PRICE\}/g, bid.price); - if (link.clicktrackers) { link.clicktrackers.forEach(function (clicktracker, index) { link.clicktrackers[index] = clicktracker.replace(/\$\{AUCTION_PRICE\}/g, bid.price); }); } - if (imptrackers) { imptrackers.forEach(function (imptracker, index) { imptrackers[index] = imptracker.replace(/\$\{AUCTION_PRICE\}/g, bid.price); @@ -203,8 +199,8 @@ function parseNative(bid) { } const result = { - url: clickUrl, - clickUrl: clickUrl, + url: link.url, + clickUrl: link.url, clickTrackers: link.clicktrackers || undefined, impressionTrackers: imptrackers || undefined }; diff --git a/modules/userId/index.js b/modules/userId/index.js index 44fbc871bb5..e656673befb 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -125,6 +125,11 @@ * @property {(function|undefined)} callback - function that will return an id */ +/** + * @typedef {Object} RefreshUserIdsOptions + * @property {(string[]|undefined)} submoduleNames - submodules to refresh + */ + import {find, includes} from '../../src/polyfill.js'; import {config} from '../../src/config.js'; import * as events from '../../src/events.js'; @@ -194,8 +199,6 @@ export let auctionDelay; /** @type {(string|undefined)} */ let ppidSource; -let configListener; - /** @param {Submodule[]} submodules */ export function setSubmoduleRegistry(submodules) { submoduleRegistry = submodules; @@ -470,8 +473,8 @@ function getSubmoduleId(submodules, sourceName) { return {}; } const submodule = submodules.filter(sub => isPlainObject(sub.idObj) && - Object.keys(sub.idObj).length && USER_IDS_CONFIG[Object.keys(sub.idObj)[0]]?.source === sourceName); - return !isEmpty(submodule) ? submodule[0].idObj : []; + Object.keys(sub.idObj).length && USER_IDS_CONFIG[Object.keys(sub.idObj)[0]].source === sourceName) + return !isEmpty(submodule) ? submodule[0].idObj : [] } /** @@ -516,133 +519,59 @@ function addIdDataToAdUnitBids(adUnits, submodules) { }); } -function delayFor(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} +/** + * This is a common function that will initialize subModules if not already done and it will also execute subModule callbacks + */ +function initializeSubmodulesAndExecuteCallbacks(continueAuction) { + let delayed = false; -function idSystemInitializer({delay = delayFor} = {}) { - /** - * @returns a {promise, resolve, reject} trio where `promise` is resolved by calling `resolve` or `reject`. - */ - function breakpoint() { - const [SUCCESS, FAIL, RESULT] = [0, 1, 2]; - const status = {}; - - function finisher(slot) { - return function (val) { - if (status[slot] != null) { - status[slot](val); - } else { - status[slot] = true; - status[RESULT] = val; - } - } - } + // initialize submodules only when undefined + if (typeof initializedSubmodules === 'undefined') { + initializedSubmodules = initSubmodules(submodules, gdprDataHandler.getConsentData()); + if (initializedSubmodules.length) { + setPrebidServerEidPermissions(initializedSubmodules); + // list of submodules that have callbacks that need to be executed + const submodulesWithCallbacks = initializedSubmodules.filter(item => isFn(item.callback)); - return { - promise: new Promise((resolve, reject) => { - if (status[SUCCESS] != null) { - resolve(status[RESULT]); - } else if (status[FAIL] != null) { - reject(status[RESULT]); + if (submodulesWithCallbacks.length) { + if (continueAuction && auctionDelay > 0) { + // delay auction until ids are available + delayed = true; + let continued = false; + const continueCallback = function () { + if (!continued) { + continued = true; + continueAuction(); + } + } + logInfo(`${MODULE_NAME} - auction delayed by ${auctionDelay} at most to fetch ids`); + + timeoutID = setTimeout(continueCallback, auctionDelay); + processSubmoduleCallbacks(submodulesWithCallbacks, continueCallback); } else { - status[SUCCESS] = resolve; - status[FAIL] = reject; + // wait for auction complete before processing submodule callbacks + events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { + events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler); + + // when syncDelay is zero, process callbacks now, otherwise delay process with a setTimeout + if (syncDelay > 0) { + setTimeout(function () { + processSubmoduleCallbacks(submodulesWithCallbacks); + }, syncDelay); + } else { + processSubmoduleCallbacks(submodulesWithCallbacks); + } + }); } - }), - resolve: finisher(SUCCESS), - reject: finisher(FAIL) - } - } - - const startInit = breakpoint(); - const startCallbacks = breakpoint(); - let cancel; - let initialized = false; - - function cancelAndTry(promise) { - if (cancel != null) { - cancel.reject(); - } - cancel = breakpoint(); - return Promise.race([promise, cancel.promise]); - } - - // grab a reference to global vars so that the promise chains remain isolated; - // multiple calls to `init` (from tests) might otherwise cause them to interfere with each other - let initModules = initializedSubmodules; - let allModules = submodules; - - function checkRefs(fn) { - // unfortunately tests have their own global state that needs to be guarded, so even if we keep ours tidy, - // we cannot let things like submodule callbacks run (they pollute things like the global `server` XHR mock) - return function(...args) { - if (initModules === initializedSubmodules && allModules === submodules) { - return fn(...args); } } } - let done = cancelAndTry( - startInit.promise - .then(() => gdprDataHandler.promise) - .then(checkRefs((consentData) => { - initSubmodules(initModules, allModules, consentData); - })) - .then(() => startCallbacks.promise) - .then(checkRefs(() => { - const modWithCb = initModules.filter(item => isFn(item.callback)); - if (modWithCb.length) { - return new Promise((resolve) => processSubmoduleCallbacks(modWithCb, resolve)); - } - })) - ); - - /** - * with `ready` = true, starts initialization; with `refresh` = true, reinitialize submodules (optionally - * filtered by `submoduleNames`). - */ - return function ({refresh = false, submoduleNames = null, ready = false} = {}) { - if (ready && !initialized) { - initialized = true; - startInit.resolve(); - // submodule callbacks should run immediately if `auctionDelay` > 0, or `syncDelay` ms after the - // auction ends otherwise - if (auctionDelay > 0) { - startCallbacks.resolve(); - } else { - events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { - events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler); - delay(syncDelay).then(startCallbacks.resolve); - }); - } - } - if (refresh) { - done = cancelAndTry( - done - .catch(() => null) - .then(() => gdprDataHandler.promise) // fetch again in case a refresh was forced before this was resolved - .then(checkRefs((consentData) => { - const cbModules = initSubmodules( - initModules, - allModules.filter((sm) => submoduleNames == null || submoduleNames.includes(sm.submodule.name)), - consentData, - true - ).filter((sm) => { - return sm.callback != null; - }); - if (cbModules.length) { - return new Promise((resolve) => processSubmoduleCallbacks(cbModules, resolve)); - } - })) - ); - } - return done; - }; + if (continueAuction && !delayed) { + continueAuction(); + } } -let initIdSystem; - /** * Hook is executed before adapters, but after consentManagement. Consent data is requied because * this module requires GDPR consent with Purpose #1 to save data locally. @@ -652,11 +581,9 @@ let initIdSystem; * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. * @param {function} fn required; The next function in the chain, used by hook.js */ -export function requestBidsHook(fn, reqBidsConfigObj, {delay = delayFor} = {}) { - Promise.race([ - getUserIdsAsync(), - delay(auctionDelay) - ]).then(() => { +export function requestBidsHook(fn, reqBidsConfigObj) { + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(function () { // pass available user id data to bid adapters addIdDataToAdUnitBids(reqBidsConfigObj.adUnits || getGlobal().adUnits, initializedSubmodules); @@ -689,7 +616,9 @@ export function requestBidsHook(fn, reqBidsConfigObj, {delay = delayFor} = {}) { * Simple use case will be passing these UserIds to A9 wrapper solution */ function getUserIds() { - return getCombinedSubmoduleIds(initializedSubmodules) + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(); + return getCombinedSubmoduleIds(initializedSubmodules); } /** @@ -697,7 +626,9 @@ function getUserIds() { * Simple use case will be passing these UserIds to A9 wrapper solution */ function getUserIdsAsEids() { - return createEidsArray(getUserIds()) + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(); + return createEidsArray(getCombinedSubmoduleIds(initializedSubmodules)); } /** @@ -706,33 +637,33 @@ function getUserIdsAsEids() { */ function getUserIdsAsEidBySource(sourceName) { + initializeSubmodulesAndExecuteCallbacks(); return createEidsArray(getSubmoduleId(initializedSubmodules, sourceName))[0]; -} +}; /** * This function will be exposed in global-name-space so that userIds for a source can be exposed * Sample use case is exposing this function to ESP */ function getEncryptedEidsForSource(source, encrypt, customFunction) { - return initIdSystem().then(() => { - let eidsSignals = {}; - - if (isFn(customFunction)) { - logInfo(`${MODULE_NAME} - Getting encrypted signal from custom function : ${customFunction.name} & source : ${source} `); - // Publishers are expected to define a common function which will be proxy for signal function. - const customSignals = customFunction(source); - eidsSignals[source] = customSignals ? encryptSignals(customSignals) : null; // by default encrypt using base64 to avoid JSON errors - } else { - // initialize signal with eids by default - const eid = getUserIdsAsEidBySource(source); - logInfo(`${MODULE_NAME} - Getting encrypted signal for eids :${JSON.stringify(eid)}`); - if (!isEmpty(eid)) { - eidsSignals[eid.source] = encrypt === true ? encryptSignals(eid) : eid.uids[0].id; // If encryption is enabled append version (1||) and encrypt entire object - } + let eidsSignals = {}; + + if (isFn(customFunction)) { + logInfo(`${MODULE_NAME} - Getting encrypted signal from custom function : ${customFunction.name} & source : ${source} `); + // Publishers are expected to define a common function which will be proxy for signal function. + const customSignals = customFunction(source); + eidsSignals[source] = customSignals ? encryptSignals(customSignals) : null; // by default encrypt using base64 to avoid JSON errors + } else { + // initialize signal with eids by default + const eid = getUserIdsAsEidBySource(source); + logInfo(`${MODULE_NAME} - Getting encrypted signal for eids :${JSON.stringify(eid)}`); + if (!isEmpty(eid)) { + eidsSignals[eid.source] = encrypt === true ? encryptSignals(eid) : eid.uids[0].id; // If encryption is enabled append version (1||) and encrypt entire object } - logInfo(`${MODULE_NAME} - Fetching encrypted eids: ${eidsSignals[source]}`); - return eidsSignals[source]; - }) + } + const promise = Promise.resolve(eidsSignals[source]); + logInfo(`${MODULE_NAME} - Fetching encrypted eids: ${eidsSignals[source]}`); + return promise; } function encryptSignals(signals, version = 1) { @@ -774,37 +705,57 @@ function registerSignalSources() { } /** - * Force (re)initialization of ID submodules. - * - * This will force a refresh of the specified ID submodules regardless of `auctionDelay` / `syncDelay` settings, and - * return a promise that resolves to the same value as `getUserIds()` when the refresh is complete. - * If a refresh is already in progress, it will be canceled (rejecting promises returned by previous calls to `refreshUserIds`). - * - * @param submoduleNames? submodules to refresh. If omitted, refresh all submodules. - * @param callback? called when the refresh is complete - */ -function refreshUserIds({submoduleNames} = {}, callback) { - return initIdSystem({refresh: true, submoduleNames}) - .then(() => { - if (callback && isFn(callback)) { - callback(); +* This function will be exposed in the global-name-space so that userIds can be refreshed after initialization. +* @param {RefreshUserIdsOptions} options +*/ +function refreshUserIds(options, callback) { + let submoduleNames = options ? options.submoduleNames : null; + if (!submoduleNames) { + submoduleNames = []; + } + + initializeSubmodulesAndExecuteCallbacks(function() { + let consentData = gdprDataHandler.getConsentData() + + // gdpr consent with purpose one is required, otherwise exit immediately + let {userIdModules, hasValidated} = validateGdprEnforcement(submodules, consentData); + if (!hasValidated && !hasGDPRConsent(consentData)) { + logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`); + return; + } + + // we always want the latest consentData stored, even if we don't execute any submodules + const storedConsentData = getStoredConsentData(); + setStoredConsentData(consentData); + + let callbackSubmodules = []; + for (let submodule of userIdModules) { + if (submoduleNames.length > 0 && + submoduleNames.indexOf(submodule.submodule.name) === -1) { + continue; } - return getUserIds(); - }); -} -/** - * @returns a promise that resolves to the same value as `getUserIds()`, but only once all ID submodules have completed - * initialization. This can also be used to synchronize calls to other ID accessors, e.g. - * - * ``` - * pbjs.getUserIdsAsync().then(() => { - * const eids = pbjs.getUserIdsAsEids(); // guaranteed to be completely initialized at this point - * }); - * ``` - */ -function getUserIdsAsync() { - return initIdSystem().then(() => getUserIds(), () => getUserIdsAsync()); + logInfo(`${MODULE_NAME} - refreshing ${submodule.submodule.name}`); + populateSubmoduleId(submodule, consentData, storedConsentData, true); + updateInitializedSubmodules(submodule); + + if (initializedSubmodules.length) { + setPrebidServerEidPermissions(initializedSubmodules); + } + + if (isFn(submodule.callback)) { + callbackSubmodules.push(submodule); + } + } + + if (callbackSubmodules.length > 0) { + processSubmoduleCallbacks(callbackSubmodules); + } + + if (callback) { + callback(); + } + }); } /** @@ -865,7 +816,12 @@ function populateSubmoduleId(submodule, consentData, storedConsentData, forceRef } } -function initSubmodules(dest, submodules, consentData, forceRefresh = false) { +/** + * @param {SubmoduleContainer[]} submodules + * @param {ConsentData} consentData + * @returns {SubmoduleContainer[]} initialized submodules + */ +function initSubmodules(submodules, consentData) { // gdpr consent with purpose one is required, otherwise exit immediately let { userIdModules, hasValidated } = validateGdprEnforcement(submodules, consentData); if (!hasValidated && !hasGDPRConsent(consentData)) { @@ -877,30 +833,25 @@ function initSubmodules(dest, submodules, consentData, forceRefresh = false) { const storedConsentData = getStoredConsentData(); setStoredConsentData(consentData); - const initialized = userIdModules.reduce((carry, submodule) => { - populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh); + return userIdModules.reduce((carry, submodule) => { + populateSubmoduleId(submodule, consentData, storedConsentData, false); carry.push(submodule); return carry; }, []); - if (initialized.length) { - setPrebidServerEidPermissions(initialized); - } - initialized.forEach(updateInitializedSubmodules.bind(null, dest)); - return initialized; } -function updateInitializedSubmodules(dest, submodule) { +function updateInitializedSubmodules(submodule) { let updated = false; - for (let i = 0; i < dest.length; i++) { - if (submodule.config.name.toLowerCase() === dest[i].config.name.toLowerCase()) { + for (let i = 0; i < initializedSubmodules.length; i++) { + if (submodule.config.name.toLowerCase() === initializedSubmodules[i].config.name.toLowerCase()) { updated = true; - dest[i] = submodule; + initializedSubmodules[i] = submodule; break; } } if (!updated) { - dest.push(submodule); + initializedSubmodules.push(submodule); } } @@ -949,9 +900,8 @@ function updateSubmodules() { // do this to avoid reprocessing submodules const addedSubmodules = submoduleRegistry.filter(i => !find(submodules, j => j.name === i.name)); - submodules.splice(0, submodules.length); // find submodule and the matching configuration, if found create and append a SubmoduleContainer - addedSubmodules.map(i => { + submodules = addedSubmodules.map(i => { const submoduleConfig = find(configs, j => j.name && (j.name.toLowerCase() === i.name.toLowerCase() || (i.aliasName && j.name.toLowerCase() === i.aliasName.toLowerCase()))); if (submoduleConfig && i.name !== submoduleConfig.name) submoduleConfig.name = i.name; @@ -962,8 +912,7 @@ function updateSubmodules() { callback: undefined, idObj: undefined } : null; - }).filter(submodule => submodule !== null) - .forEach((sm) => submodules.push(sm)); + }).filter(submodule => submodule !== null); if (!addedUserIdHook && submodules.length) { // priority value 40 will load after consentManagement with a priority of 50 @@ -989,17 +938,12 @@ export function attachIdSystem(submodule) { * so a callback is added to fire after the consentManagement module. * @param {{getConfig:function}} config */ -export function init(config, {delay = delayFor} = {}) { +export function init(config) { ppidSource = undefined; submodules = []; configRegistry = []; addedUserIdHook = false; - initializedSubmodules = []; - initIdSystem = idSystemInitializer({delay}); - if (configListener != null) { - configListener(); - } - submoduleRegistry = []; + initializedSubmodules = undefined; // list of browser enabled storage types validStorageTypes = [ @@ -1018,7 +962,7 @@ export function init(config, {delay = delayFor} = {}) { } // listen for config userSyncs to be set - configListener = config.getConfig('userSync', conf => { + config.getConfig('userSync', conf => { // Note: support for 'usersync' was dropped as part of Prebid.js 4.0 const userSync = conf.userSync; ppidSource = userSync.ppid; @@ -1027,7 +971,6 @@ export function init(config, {delay = delayFor} = {}) { syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY; auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY; updateSubmodules(); - initIdSystem({ready: true}); } }); @@ -1037,7 +980,6 @@ export function init(config, {delay = delayFor} = {}) { (getGlobal()).getEncryptedEidsForSource = getEncryptedEidsForSource; (getGlobal()).registerSignalSources = registerSignalSources; (getGlobal()).refreshUserIds = refreshUserIds; - (getGlobal()).getUserIdsAsync = getUserIdsAsync; (getGlobal()).getUserIdsAsEidBySource = getUserIdsAsEidBySource; } diff --git a/modules/vibrantmediaBidAdapter.js b/modules/vibrantmediaBidAdapter.js index 0613f722af8..b6fe51c43bc 100644 --- a/modules/vibrantmediaBidAdapter.js +++ b/modules/vibrantmediaBidAdapter.js @@ -6,14 +6,13 @@ * Note: Only BANNER and VIDEO are currently supported by the prebid server. */ -import {logError, triggerPixel} from '../src/utils.js'; +import {logError, logInfo} from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {OUTSTREAM} from '../src/video.js'; const BIDDER_CODE = 'vibrantmedia'; const VIBRANT_MEDIA_PREBID_URL = 'https://prebid.intellitxt.com/prebid'; -const VALID_PIXEL_URL_REGEX = /^https?:\/\/[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+([/?].*)?$/; const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE, VIDEO]; /** @@ -52,10 +51,6 @@ const isBaseUrl = function(url) { return (endOfDomain === -1) || (endOfDomain === (urlMinusScheme.length - 1)); }; -const isValidPixelUrl = function (candidateUrl) { - return VALID_PIXEL_URL_REGEX.test(candidateUrl); -}; - /** * Returns transformed bid requests that are in a format native to the prebid server. * @@ -218,9 +213,7 @@ export const spec = { * @param {*} bidData the data associated with the won bid. See example above for data format. */ onBidWon: function(bidData) { - if (bidData && bidData.meta && isValidPixelUrl(bidData.meta.wp)) { - triggerPixel(`${bidData.meta.wp}${bidData.status}`); - } + logInfo('Bid won: ' + JSON.stringify(bidData)); } }; diff --git a/package-lock.json b/package-lock.json index c4e86036f99..e40addfc54d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "6.23.0-pre", + "version": "6.20.0-pre", "lockfileVersion": 2, "requires": true, "packages": { @@ -31,12 +31,11 @@ "@wdio/concise-reporter": "^7.5.2", "@wdio/local-runner": "^7.5.2", "@wdio/mocha-framework": "^7.5.2", - "@wdio/spec-reporter": "^7.19.0", + "@wdio/spec-reporter": "^7.5.2", "@wdio/sync": "^7.5.2", "ajv": "6.12.3", "assert": "^2.0.0", "babel-loader": "^8.0.5", - "babel-register": "^6.26.0", "body-parser": "^1.19.0", "chai": "^4.2.0", "coveralls": "^3.1.0", @@ -3278,14 +3277,14 @@ } }, "node_modules/@wdio/spec-reporter": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.19.1.tgz", - "integrity": "sha512-qnZkn3VcyBPtcorUtpyCFE8v5ubyWmR7mFETXNzyriHyvjvk+NeFCWaFcIehpXYXiAmNpAwyfnZoIY6tkKQixQ==", + "version": "7.16.14", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.16.14.tgz", + "integrity": "sha512-hpS2rLXo91lfrit5/pjDSbff2lqQe+k07/JPOJ48W+ZPSI+ib7rSldI4JFYU4YuKN1TnhkbhxRBMib3bF3Fs+Q==", "dev": true, "dependencies": { "@types/easy-table": "^0.0.33", - "@wdio/reporter": "7.19.1", - "@wdio/types": "7.19.1", + "@wdio/reporter": "7.16.14", + "@wdio/types": "7.16.14", "chalk": "^4.0.0", "easy-table": "^1.1.1", "pretty-ms": "^7.0.0" @@ -3297,58 +3296,6 @@ "@wdio/cli": "^7.0.0" } }, - "node_modules/@wdio/spec-reporter/node_modules/@wdio/reporter": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-7.19.1.tgz", - "integrity": "sha512-sWmBBV4dPCZkGk9Qq0m35T/vHGen0N10nH4osQcVP3IZJqpo2eLIH4w+X6EUbjZ2GdgOA2bLMMzb1bl9JqnGPg==", - "dev": true, - "dependencies": { - "@types/diff": "^5.0.0", - "@types/node": "^17.0.4", - "@types/object-inspect": "^1.8.0", - "@types/supports-color": "^8.1.0", - "@types/tmp": "^0.2.0", - "@wdio/types": "7.19.1", - "diff": "^5.0.0", - "fs-extra": "^10.0.0", - "object-inspect": "^1.10.3", - "supports-color": "8.1.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@wdio/spec-reporter/node_modules/@wdio/reporter/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/@wdio/spec-reporter/node_modules/@wdio/types": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.19.1.tgz", - "integrity": "sha512-mOodKlmvYxpj8P5BhjggEGpXuiRSlsyn2ClG8QqJ3lfXgOtOVEzFNfv/Ai7TkHr+lHDQNXLjllCjSqoCHhwlqg==", - "dev": true, - "dependencies": { - "@types/node": "^17.0.4", - "got": "^11.8.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "^4.6.2" - } - }, "node_modules/@wdio/spec-reporter/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4344,113 +4291,6 @@ "node": ">=0.8.0" } }, - "node_modules/babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "node_modules/babel-core/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/babel-core/node_modules/json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/babel-core/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/babel-core/node_modules/slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "dependencies": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "node_modules/babel-generator/node_modules/detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-generator/node_modules/jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, "node_modules/babel-loader": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", @@ -4496,15 +4336,6 @@ "node": ">=4.0.0" } }, - "node_modules/babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "dependencies": { - "babel-runtime": "^6.22.0" - } - }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -4561,50 +4392,6 @@ "babel-runtime": "^6.22.0" } }, - "node_modules/babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "dependencies": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "node_modules/babel-register/node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true - }, - "node_modules/babel-register/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/babel-register/node_modules/source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "dependencies": { - "source-map": "^0.5.6" - } - }, "node_modules/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -4621,81 +4408,6 @@ "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", "hasInstallScript": true }, - "node_modules/babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "node_modules/babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "node_modules/babel-traverse/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/babel-traverse/node_modules/globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-traverse/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "dependencies": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "node_modules/babel-types/node_modules/to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/babelify": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", @@ -4708,15 +4420,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true, - "bin": { - "babylon": "bin/babylon.js" - } - }, "node_modules/bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -5634,20 +5337,14 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", + "version": "1.0.30001314", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz", + "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/caseless": { "version": "0.12.0", @@ -13068,19 +12765,6 @@ "node": "*" } }, - "node_modules/home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -13410,15 +13094,6 @@ "node": ">= 0.10" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -15904,18 +15579,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -16974,9 +16637,9 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "node_modules/minimist-options": { @@ -18072,15 +17735,6 @@ "readable-stream": "^2.0.1" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -18677,15 +18331,6 @@ "node": ">=0.8" } }, - "node_modules/private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -21856,15 +21501,6 @@ "node": ">=8" } }, - "node_modules/trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -21980,20 +21616,6 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/typescript-compare": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", @@ -26066,58 +25688,19 @@ } }, "@wdio/spec-reporter": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.19.1.tgz", - "integrity": "sha512-qnZkn3VcyBPtcorUtpyCFE8v5ubyWmR7mFETXNzyriHyvjvk+NeFCWaFcIehpXYXiAmNpAwyfnZoIY6tkKQixQ==", + "version": "7.16.14", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-7.16.14.tgz", + "integrity": "sha512-hpS2rLXo91lfrit5/pjDSbff2lqQe+k07/JPOJ48W+ZPSI+ib7rSldI4JFYU4YuKN1TnhkbhxRBMib3bF3Fs+Q==", "dev": true, "requires": { "@types/easy-table": "^0.0.33", - "@wdio/reporter": "7.19.1", - "@wdio/types": "7.19.1", + "@wdio/reporter": "7.16.14", + "@wdio/types": "7.16.14", "chalk": "^4.0.0", "easy-table": "^1.1.1", "pretty-ms": "^7.0.0" }, "dependencies": { - "@wdio/reporter": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-7.19.1.tgz", - "integrity": "sha512-sWmBBV4dPCZkGk9Qq0m35T/vHGen0N10nH4osQcVP3IZJqpo2eLIH4w+X6EUbjZ2GdgOA2bLMMzb1bl9JqnGPg==", - "dev": true, - "requires": { - "@types/diff": "^5.0.0", - "@types/node": "^17.0.4", - "@types/object-inspect": "^1.8.0", - "@types/supports-color": "^8.1.0", - "@types/tmp": "^0.2.0", - "@wdio/types": "7.19.1", - "diff": "^5.0.0", - "fs-extra": "^10.0.0", - "object-inspect": "^1.10.3", - "supports-color": "8.1.1" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@wdio/types": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.19.1.tgz", - "integrity": "sha512-mOodKlmvYxpj8P5BhjggEGpXuiRSlsyn2ClG8QqJ3lfXgOtOVEzFNfv/Ai7TkHr+lHDQNXLjllCjSqoCHhwlqg==", - "dev": true, - "requires": { - "@types/node": "^17.0.4", - "got": "^11.8.1" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -26913,105 +26496,6 @@ } } }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, "babel-loader": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", @@ -27046,15 +26530,6 @@ } } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, "babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -27102,47 +26577,6 @@ "babel-runtime": "^6.22.0" } }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -27159,79 +26593,6 @@ } } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, "babelify": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", @@ -27239,12 +26600,6 @@ "dev": true, "requires": {} }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, "bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -27968,9 +27323,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", + "version": "1.0.30001314", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz", + "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==", "dev": true }, "caseless": { @@ -33914,16 +33269,6 @@ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -34172,15 +33517,6 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -36137,15 +35473,6 @@ "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -36952,9 +36279,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "minimist-options": { @@ -37834,12 +37161,6 @@ "readable-stream": "^2.0.1" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -38280,12 +37601,6 @@ "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", "dev": true }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -40848,12 +40163,6 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -40946,13 +40255,6 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true, - "peer": true - }, "typescript-compare": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", diff --git a/package.json b/package.json index 9e5d68ac5e8..47bcc94404f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "6.23.0-pre", + "version": "6.20.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { @@ -43,12 +43,11 @@ "@wdio/concise-reporter": "^7.5.2", "@wdio/local-runner": "^7.5.2", "@wdio/mocha-framework": "^7.5.2", - "@wdio/spec-reporter": "^7.19.0", + "@wdio/spec-reporter": "^7.5.2", "@wdio/sync": "^7.5.2", "ajv": "6.12.3", "assert": "^2.0.0", "babel-loader": "^8.0.5", - "babel-register": "^6.26.0", "body-parser": "^1.19.0", "chai": "^4.2.0", "coveralls": "^3.1.0", diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 382c93b0d25..87bc7a45491 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -14,7 +14,6 @@ import { ADPOD } from '../mediaTypes.js'; import { getHook, hook } from '../hook.js'; import { getCoreStorageManager } from '../storageManager.js'; import {auctionManager} from '../auctionManager.js'; -import { bidderSettings } from '../bidderSettings.js'; export const storage = getCoreStorageManager('bidderFactory'); @@ -236,11 +235,6 @@ export function newBidder(spec) { onBid: (bid) => { const bidRequest = bidRequestMap[bid.requestId]; if (bidRequest) { - bid.adapterCode = bidRequest.bidder; - if (isInvalidAlternateBidder(bid.bidderCode, bidRequest.bidder)) { - logWarn(`${bid.bidderCode} is not a registered partner or known bidder of ${bidRequest.bidder}, hence continuing without bid. If you wish to support this bidder, please mark allowAlternateBidderCodes as true in bidderSettings.`); - return; - } // creating a copy of original values as cpm and currency are modified later bid.originalCpm = bid.cpm; bid.originalCurrency = bid.currency; @@ -256,17 +250,6 @@ export function newBidder(spec) { } }); - function isInvalidAlternateBidder(responseBidder, requestBidder) { - let allowAlternateBidderCodes = bidderSettings.get(requestBidder, 'allowAlternateBidderCodes'); - let alternateBiddersList = bidderSettings.get(requestBidder, 'allowedAlternateBidderCodes'); - if (!!responseBidder && !!requestBidder && requestBidder !== responseBidder) { - if ((allowAlternateBidderCodes !== undefined && !allowAlternateBidderCodes) || (isArray(alternateBiddersList) && (alternateBiddersList[0] !== '*' && !alternateBiddersList.includes(responseBidder)))) { - return true; - } - } - return false; - } - function registerSyncs(responses, gdprConsent, uspConsent) { registerSyncInner(spec, responses, gdprConsent, uspConsent); } diff --git a/src/auction.js b/src/auction.js index c55334bcd3d..ae5c3c6156b 100644 --- a/src/auction.js +++ b/src/auction.js @@ -848,7 +848,13 @@ function groupByPlacement(bidsByPlacement, bid) { function getTimedOutBids(bidderRequests, timelyBidders) { const timedOutBids = bidderRequests .map(bid => (bid.bids || []).filter(bid => !timelyBidders.has(bid.bidder))) - .reduce(flatten, []); + .reduce(flatten, []) + .map(bid => ({ + bidId: bid.bidId, + bidder: bid.bidder, + adUnitCode: bid.adUnitCode, + auctionId: bid.auctionId, + })); return timedOutBids; } diff --git a/test/fake-server/bundle.js b/test/fake-server/bundle.js deleted file mode 100644 index b0430458083..00000000000 --- a/test/fake-server/bundle.js +++ /dev/null @@ -1,41 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const makeBundle = require('../../gulpfile.js'); -const argv = require('yargs').argv; -const host = argv.host || 'localhost'; -const port = argv.port || 4444; -const dev = argv.dev || false; - -const REPLACE = { - 'https://ib.adnxs.com/ut/v3/prebid': `http://${host}:${port}/appnexus` -}; - -const replaceStrings = (() => { - const rules = Object.entries(REPLACE).map(([orig, repl]) => { - return [new RegExp(orig, 'g'), repl]; - }); - return function(text) { - return rules.reduce((text, [pat, repl]) => text.replace(pat, repl), text); - } -})(); - -const getBundle = (() => { - const cache = {}; - return function (modules = []) { - modules = Array.isArray(modules) ? [...modules] : [modules]; - modules.sort(); - const key = modules.join(','); - if (!cache.hasOwnProperty(key)) { - cache[key] = makeBundle(modules, dev).then(replaceStrings); - } - return cache[key]; - } -})(); - -module.exports = function (req, res, next) { - res.type('text/javascript'); - getBundle(req.query.modules).then((bundle) => { - res.write(bundle); - next(); - }).catch(next); -} diff --git a/test/fake-server/fake-responder.js b/test/fake-server/fake-responder.js index a44d02260e7..c884b00ca9c 100644 --- a/test/fake-server/fake-responder.js +++ b/test/fake-server/fake-responder.js @@ -6,6 +6,9 @@ const path = require('path'); // path to the fixture directory const fixturesPath = path.join(__dirname, 'fixtures'); +// An object storing 'Request-Response' pairs. +let REQ_RES_MAP = generateFixtures(fixturesPath); + /** * Matches 'req.body' with the responseBody pair * @param {object} requestBody - `req.body` of incoming request hitting middleware 'fakeResponder'. @@ -13,8 +16,8 @@ const fixturesPath = path.join(__dirname, 'fixtures'); */ const matchResponse = function (requestBody) { let actualUuids = []; - let reqResMap = generateFixtures(fixturesPath); - const requestResponsePairs = Object.keys(reqResMap).map(testName => reqResMap[testName]); + + const requestResponsePairs = Object.keys(REQ_RES_MAP).map(testName => REQ_RES_MAP[testName]); // delete 'uuid' property requestBody.tags.forEach(body => { @@ -35,22 +38,8 @@ const matchResponse = function (requestBody) { requestResponsePairs .forEach(reqRes => { reqRes.request.httpRequest && reqRes.request.httpRequest.body.tags.forEach(body => body.uuid && delete body.uuid) }); - const match = requestResponsePairs.filter(reqRes => reqRes.request.httpRequest && deepEqual(reqRes.request.httpRequest.body.tags, requestBody.tags)); - - try { - if (match.length === 0) { - throw new Error('No mock response found'); - } else if (match.length > 1) { - throw new Error('More than one mock response found') - } - } catch (e) { - console.error(e); - console.error('Tags:', JSON.stringify(requestBody.tags, null, 2)); - throw e; - } - // match the 'actual' requestBody with the 'expected' requestBody and find the 'responseBody' - const responseBody = match[0].response.httpResponse.body; + const responseBody = requestResponsePairs.filter(reqRes => reqRes.request.httpRequest && deepEqual(reqRes.request.httpRequest.body.tags, requestBody.tags))[0].response.httpResponse.body; // ENABLE THE FOLLOWING CODE FOR TROUBLE-SHOOTING FAKED REQUESTS; COMMENT AGAIN WHEN DONE // console.log('value found for responseBody:', responseBody); diff --git a/test/fake-server/fixtures/basic-banner/request.json b/test/fake-server/fixtures/basic-banner/request.json index 6b355cd24c0..ea85b5a6842 100644 --- a/test/fake-server/fixtures/basic-banner/request.json +++ b/test/fake-server/fixtures/basic-banner/request.json @@ -58,4 +58,4 @@ "user": {} } } -} +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/request.json b/test/fake-server/fixtures/basic-outstream/request.json index e9f3302ab4c..611a518fc2d 100644 --- a/test/fake-server/fixtures/basic-outstream/request.json +++ b/test/fake-server/fixtures/basic-outstream/request.json @@ -20,7 +20,7 @@ "disable_psa": true, "video": { "skippable": true, - "playback_method": 2 + "playback_method": ["auto_play_sound_off"] }, "hb_source": 1 }, { @@ -40,11 +40,11 @@ "disable_psa": true, "video": { "skippable": true, - "playback_method": 2 + "playback_method": ["auto_play_sound_off"] }, "hb_source": 1 }], "user": {} } } -} +} \ No newline at end of file diff --git a/test/fake-server/index.js b/test/fake-server/index.js index e93bcfd465f..752648c6746 100644 --- a/test/fake-server/index.js +++ b/test/fake-server/index.js @@ -5,9 +5,8 @@ const morgan = require('morgan'); const bodyParser = require('body-parser'); const argv = require('yargs').argv; const fakeResponder = require('./fake-responder.js'); -const bundleMaker = require('./bundle.js'); -const PORT = argv.port || '4444'; +const PORT = argv.port || '3000'; // Initialize express app const app = express(); @@ -25,11 +24,7 @@ app.use(function(req, res, next) { next(); }); -app.get('/bundle', bundleMaker, (req, res) => { - res.send(); -}); - -app.post('/appnexus', fakeResponder, (req, res) => { +app.post('/', fakeResponder, (req, res) => { res.send(); }); diff --git a/test/helpers/consentData.js b/test/helpers/consentData.js deleted file mode 100644 index 17ddc583f88..00000000000 --- a/test/helpers/consentData.js +++ /dev/null @@ -1,6 +0,0 @@ -import {gdprDataHandler} from 'src/adapterManager.js'; - -export function mockGdprConsent(sandbox, getConsentData = () => null) { - sandbox.stub(gdprDataHandler, 'promise').get(() => Promise.resolve(getConsentData())); - sandbox.stub(gdprDataHandler, 'getConsentData').callsFake(getConsentData) -} diff --git a/test/helpers/testing-utils.js b/test/helpers/testing-utils.js index 81f22ca471d..76e2b652a79 100644 --- a/test/helpers/testing-utils.js +++ b/test/helpers/testing-utils.js @@ -1,51 +1,13 @@ /* eslint-disable no-console */ -const {expect} = require('chai'); -const utils = { +module.exports = { host: (process.env.TEST_SERVER_HOST) ? process.env.TEST_SERVER_HOST : 'localhost', protocol: (process.env.TEST_SERVER_PROTOCOL) ? 'https' : 'http', - testPageURL: function(name) { - return `${utils.protocol}://${utils.host}:9999/test/pages/${name}` - }, waitForElement: function(elementRef, time = 2000) { let element = $(elementRef); element.waitForExist({timeout: time}); }, - switchFrame: function(frameRef) { + switchFrame: function(frameRef, frameName) { let iframe = $(frameRef); browser.switchToFrame(iframe); - }, - loadAndWaitForElement(url, selector, pause = 3000, timeout = 2000, retries = 3, attempt = 1) { - browser.url(url); - browser.pause(pause); - if (selector != null) { - try { - utils.waitForElement(selector, timeout); - } catch (e) { - if (attempt < retries) { - utils.loadAndWaitForElement(url, selector, pause, timeout, retries, attempt + 1); - } - } - } - }, - setupTest({url, waitFor, expectGAMCreative = null, pause = 3000, timeout = 2000, retries = 3}, name, fn) { - describe(name, function () { - this.retries(retries); - before(() => utils.loadAndWaitForElement(url, waitFor, pause, timeout, retries)); - fn.call(this); - if (expectGAMCreative) { - expectGAMCreative = expectGAMCreative === true ? waitFor : expectGAMCreative; - it(`should render GAM creative`, () => { - utils.switchFrame(expectGAMCreative); - const creative = [ - '> a > img', // banner - '> div[class="card"]' // native - ].map((child) => `body > div[class="GoogleActiveViewElement"] ${child}`) - .join(', '); - expect($(creative).isExisting()).to.be.true; - }); - } - }); } } - -module.exports = utils; diff --git a/test/pages/banner.html b/test/pages/banner.html index 2e88d356647..75993cefb39 100644 --- a/test/pages/banner.html +++ b/test/pages/banner.html @@ -7,7 +7,7 @@ Prebid.js Banner Example - + diff --git a/test/pages/bidderSettings.html b/test/pages/bidderSettings.html index 205fc250be1..015ad3ca45f 100644 --- a/test/pages/bidderSettings.html +++ b/test/pages/bidderSettings.html @@ -1,7 +1,7 @@ - + + + - + - +