prebid.js 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/gulpfile.js +87 -74
  3. package/karma.conf.maker.js +1 -1
  4. package/modules/adkernelBidAdapter.js +146 -61
  5. package/modules/adlooxAdServerVideo.js +2 -2
  6. package/modules/adlooxAnalyticsAdapter.js +4 -4
  7. package/modules/adomikAnalyticsAdapter.js +6 -0
  8. package/modules/aniviewBidAdapter.js +1 -1
  9. package/modules/beopBidAdapter.js +1 -1
  10. package/modules/bidViewability.js +3 -3
  11. package/modules/bidViewabilityIO.js +3 -3
  12. package/modules/compassBidAdapter.js +201 -0
  13. package/modules/compassBidAdapter.md +79 -0
  14. package/modules/currency.js +2 -2
  15. package/modules/dailyhuntBidAdapter.js +435 -0
  16. package/modules/dailyhuntBidAdapter.md +4 -0
  17. package/modules/engageyaBidAdapter.js +1 -1
  18. package/modules/feedadBidAdapter.js +2 -2
  19. package/modules/feedadBidAdapter.md +4 -2
  20. package/modules/gridBidAdapter.js +4 -3
  21. package/modules/improvedigitalBidAdapter.js +19 -3
  22. package/modules/instreamTracking.js +4 -4
  23. package/modules/invibesBidAdapter.js +49 -5
  24. package/modules/invibesBidAdapter.md +2 -1
  25. package/modules/ixBidAdapter.js +24 -6
  26. package/modules/livewrappedBidAdapter.js +8 -2
  27. package/modules/nextMillenniumBidAdapter.js +8 -6
  28. package/modules/pubgeniusBidAdapter.js +1 -1
  29. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  30. package/modules/rubiconBidAdapter.js +21 -11
  31. package/modules/telariaBidAdapter.js +2 -2
  32. package/modules/trustxBidAdapter.js +8 -16
  33. package/package.json +1 -1
  34. package/src/auction.js +2 -2
  35. package/test/helpers/prebidGlobal.js +1 -0
  36. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  37. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +6 -0
  38. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  39. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  40. package/test/spec/modules/bidViewability_spec.js +4 -4
  41. package/test/spec/modules/compassBidAdapter_spec.js +397 -0
  42. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  43. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  44. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -1
  45. package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
  46. package/test/spec/modules/ixBidAdapter_spec.js +8 -0
  47. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  48. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +9 -2
  49. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  50. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  51. package/test/spec/modules/rubiconBidAdapter_spec.js +48 -9
  52. package/test/test_deps.js +3 -0
  53. package/test/test_index.js +1 -3
@@ -52,7 +52,7 @@ aliases:
52
52
  - &unit_test_steps
53
53
  - checkout
54
54
  - restore_cache: *restore_dep_cache
55
- - run: npm install
55
+ - run: npm ci
56
56
  - save_cache: *save_dep_cache
57
57
  - run: *install
58
58
  - run: *setup_browserstack
package/gulpfile.js CHANGED
@@ -115,32 +115,6 @@ function viewReview(done) {
115
115
 
116
116
  viewReview.displayName = 'view-review';
117
117
 
118
- // Watch Task with Live Reload
119
- function watch(done) {
120
- var mainWatcher = gulp.watch([
121
- 'src/**/*.js',
122
- 'modules/**/*.js',
123
- 'test/spec/**/*.js',
124
- '!test/spec/loaders/**/*.js'
125
- ]);
126
- var loaderWatcher = gulp.watch([
127
- 'loaders/**/*.js',
128
- 'test/spec/loaders/**/*.js'
129
- ]);
130
-
131
- connect.server({
132
- https: argv.https,
133
- port: port,
134
- host: FAKE_SERVER_HOST,
135
- root: './',
136
- livereload: true
137
- });
138
-
139
- mainWatcher.on('all', gulp.series(clean, gulp.parallel(lint, 'build-bundle-dev', test)));
140
- loaderWatcher.on('all', gulp.series(lint));
141
- done();
142
- };
143
-
144
118
  function makeDevpackPkg() {
145
119
  var cloned = _.cloneDeep(webpackConfig);
146
120
  cloned.devtool = 'source-map';
@@ -247,60 +221,68 @@ function bundle(dev, moduleArr) {
247
221
  // If --browsers is given, browsers can be chosen explicitly. e.g. --browsers=chrome,firefox,ie9
248
222
  // If --notest is given, it will immediately skip the test task (useful for developing changes with `gulp serve --notest`)
249
223
 
250
- function test(done) {
251
- if (argv.notest) {
252
- done();
253
- } else if (argv.e2e) {
254
- let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio');
255
- let wdioConf = path.join(__dirname, 'wdio.conf.js');
256
- let wdioOpts;
257
-
258
- if (argv.file) {
259
- wdioOpts = [
260
- wdioConf,
261
- `--spec`,
262
- `${argv.file}`
263
- ]
264
- } else {
265
- wdioOpts = [
266
- wdioConf
267
- ];
268
- }
224
+ function testTaskMaker(options = {}) {
225
+ ['watch', 'e2e', 'file', 'browserstack', 'notest'].forEach(opt => {
226
+ options[opt] = options[opt] || argv[opt];
227
+ })
269
228
 
270
- // run fake-server
271
- const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]);
272
- fakeServer.stdout.on('data', (data) => {
273
- console.log(`stdout: ${data}`);
274
- });
275
- fakeServer.stderr.on('data', (data) => {
276
- console.log(`stderr: ${data}`);
277
- });
229
+ return function test(done) {
230
+ if (options.notest) {
231
+ done();
232
+ } else if (options.e2e) {
233
+ let wdioCmd = path.join(__dirname, 'node_modules/.bin/wdio');
234
+ let wdioConf = path.join(__dirname, 'wdio.conf.js');
235
+ let wdioOpts;
236
+
237
+ if (options.file) {
238
+ wdioOpts = [
239
+ wdioConf,
240
+ `--spec`,
241
+ `${options.file}`
242
+ ]
243
+ } else {
244
+ wdioOpts = [
245
+ wdioConf
246
+ ];
247
+ }
278
248
 
279
- execa(wdioCmd, wdioOpts, { stdio: 'inherit' })
280
- .then(stdout => {
281
- // kill fake server
282
- fakeServer.kill('SIGINT');
283
- done();
284
- process.exit(0);
285
- })
286
- .catch(err => {
287
- // kill fake server
288
- fakeServer.kill('SIGINT');
289
- done(new Error(`Tests failed with error: ${err}`));
290
- process.exit(1);
249
+ // run fake-server
250
+ const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]);
251
+ fakeServer.stdout.on('data', (data) => {
252
+ console.log(`stdout: ${data}`);
253
+ });
254
+ fakeServer.stderr.on('data', (data) => {
255
+ console.log(`stderr: ${data}`);
291
256
  });
292
- } else {
293
- var karmaConf = karmaConfMaker(false, argv.browserstack, argv.watch, argv.file);
294
257
 
295
- var browserOverride = helpers.parseBrowserArgs(argv);
296
- if (browserOverride.length > 0) {
297
- karmaConf.browsers = browserOverride;
298
- }
258
+ execa(wdioCmd, wdioOpts, { stdio: 'inherit' })
259
+ .then(stdout => {
260
+ // kill fake server
261
+ fakeServer.kill('SIGINT');
262
+ done();
263
+ process.exit(0);
264
+ })
265
+ .catch(err => {
266
+ // kill fake server
267
+ fakeServer.kill('SIGINT');
268
+ done(new Error(`Tests failed with error: ${err}`));
269
+ process.exit(1);
270
+ });
271
+ } else {
272
+ var karmaConf = karmaConfMaker(false, options.browserstack, options.watch, options.file);
299
273
 
300
- new KarmaServer(karmaConf, newKarmaCallback(done)).start();
274
+ var browserOverride = helpers.parseBrowserArgs(argv);
275
+ if (browserOverride.length > 0) {
276
+ karmaConf.browsers = browserOverride;
277
+ }
278
+
279
+ new KarmaServer(karmaConf, newKarmaCallback(done)).start();
280
+ }
301
281
  }
302
282
  }
303
283
 
284
+ const test = testTaskMaker();
285
+
304
286
  function newKarmaCallback(done) {
305
287
  return function (exitCode) {
306
288
  if (exitCode) {
@@ -377,6 +359,35 @@ function startFakeServer() {
377
359
  });
378
360
  }
379
361
 
362
+ // Watch Task with Live Reload
363
+ function watchTaskMaker(options = {}) {
364
+ if (options.livereload == null) {
365
+ options.livereload = true;
366
+ }
367
+ options.alsoWatch = options.alsoWatch || [];
368
+
369
+ return function watch(done) {
370
+ var mainWatcher = gulp.watch([
371
+ 'src/**/*.js',
372
+ 'modules/**/*.js',
373
+ ].concat(options.alsoWatch));
374
+
375
+ connect.server({
376
+ https: argv.https,
377
+ port: port,
378
+ host: FAKE_SERVER_HOST,
379
+ root: './',
380
+ livereload: options.livereload
381
+ });
382
+
383
+ mainWatcher.on('all', options.task());
384
+ done();
385
+ }
386
+ }
387
+
388
+ const watch = watchTaskMaker({alsoWatch: ['test/**/*.js'], task: () => gulp.series(clean, gulp.parallel(lint, 'build-bundle-dev', test))});
389
+ const watchFast = watchTaskMaker({livereload: false, task: () => gulp.series('build-bundle-dev')});
390
+
380
391
  // support tasks
381
392
  gulp.task(lint);
382
393
  gulp.task(watch);
@@ -389,7 +400,8 @@ gulp.task('build-bundle-dev', gulp.series(makeDevpackPkg, gulpBundle.bind(null,
389
400
  gulp.task('build-bundle-prod', gulp.series(makeWebpackPkg, gulpBundle.bind(null, false)));
390
401
 
391
402
  // public tasks (dependencies are needed for each task since they can be ran on their own)
392
- gulp.task('test', gulp.series(clean, lint, test));
403
+ gulp.task('test-only', test);
404
+ gulp.task('test', gulp.series(clean, lint, 'test-only'));
393
405
 
394
406
  gulp.task('test-coverage', gulp.series(clean, testCoverage));
395
407
  gulp.task(viewCoverage);
@@ -400,7 +412,8 @@ gulp.task('build', gulp.series(clean, 'build-bundle-prod'));
400
412
  gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid));
401
413
 
402
414
  gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test)));
403
- gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', watch)));
415
+ gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast)));
416
+ gulp.task('serve-and-test', gulp.series(clean, gulp.parallel('build-bundle-dev', watchFast, testTaskMaker({watch: true}))));
404
417
  gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer));
405
418
 
406
419
  gulp.task('default', gulp.series(clean, makeWebpackPkg));
@@ -111,7 +111,7 @@ module.exports = function(codeCoverage, browserstack, watchMode, file) {
111
111
  var webpackConfig = newWebpackConfig(codeCoverage);
112
112
  var plugins = newPluginsArray(browserstack);
113
113
 
114
- var files = file ? ['test/helpers/prebidGlobal.js', file] : ['test/test_index.js'];
114
+ var files = file ? ['test/test_deps.js', file] : ['test/test_index.js'];
115
115
  // This file opens the /debug.html tab automatically.
116
116
  // It has no real value unless you're running --watch, and intend to do some debugging in the browser.
117
117
  if (watchMode) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isStr, isArray, isPlainObject, deepSetValue, isNumber, deepAccess, getAdUnitSizes, parseGPTSingleSizeArrayToRtbSize,
3
- cleanObj, contains, getDNT, parseUrl, createTrackPixelHtml, _each, isArrayOfNums
3
+ cleanObj, contains, getDNT, parseUrl, createTrackPixelHtml, _each, isArrayOfNums, mergeDeep, isEmpty, inIframe
4
4
  } from '../src/utils.js';
5
5
  import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
6
6
  import {registerBidder} from '../src/adapters/bidderFactory.js';
@@ -103,17 +103,16 @@ export const spec = {
103
103
  * @returns {ServerRequest[]}
104
104
  */
105
105
  buildRequests: function (bidRequests, bidderRequest) {
106
- let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo);
106
+ let impGroups = groupImpressionsByHostZone(bidRequests, bidderRequest.refererInfo);
107
107
  let requests = [];
108
108
  let schain = bidRequests[0].schain;
109
- Object.keys(impDispatch).forEach(host => {
110
- Object.keys(impDispatch[host]).forEach(zoneId => {
111
- const request = buildRtbRequest(impDispatch[host][zoneId], bidderRequest, schain);
112
- requests.push({
113
- method: 'POST',
114
- url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`,
115
- data: JSON.stringify(request)
116
- });
109
+ _each(impGroups, impGroup => {
110
+ let {host, zoneId, imps} = impGroup;
111
+ const request = buildRtbRequest(imps, bidderRequest, schain);
112
+ requests.push({
113
+ method: 'POST',
114
+ url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`,
115
+ data: JSON.stringify(request)
117
116
  });
118
117
  });
119
118
  return requests;
@@ -209,17 +208,19 @@ registerBidder(spec);
209
208
  * @param bidRequests {BidRequest[]}
210
209
  * @param refererInfo {refererInfo}
211
210
  */
212
- function dispatchImps(bidRequests, refererInfo) {
211
+ function groupImpressionsByHostZone(bidRequests, refererInfo) {
213
212
  let secure = (refererInfo && refererInfo.referer.indexOf('https:') === 0);
214
- return bidRequests.map(bidRequest => buildImp(bidRequest, secure))
215
- .reduce((acc, curr, index) => {
216
- let bidRequest = bidRequests[index];
217
- let {zoneId, host} = bidRequest.params;
218
- acc[host] = acc[host] || {};
219
- acc[host][zoneId] = acc[host][zoneId] || [];
220
- acc[host][zoneId].push(curr);
221
- return acc;
222
- }, {});
213
+ return Object.values(
214
+ bidRequests.map(bidRequest => buildImp(bidRequest, secure))
215
+ .reduce((acc, curr, index) => {
216
+ let bidRequest = bidRequests[index];
217
+ let {zoneId, host} = bidRequest.params;
218
+ let key = `${host}_${zoneId}`;
219
+ acc[key] = acc[key] || {host: host, zoneId: zoneId, imps: []};
220
+ acc[key].imps.push(curr);
221
+ return acc;
222
+ }, {})
223
+ );
223
224
  }
224
225
 
225
226
  function getBidFloor(bid, mediaType, sizes) {
@@ -365,57 +366,142 @@ function getAllowedSyncMethod(bidderCode) {
365
366
  }
366
367
 
367
368
  /**
368
- * Builds complete rtb request
369
- * @param imps {Object} Collection of rtb impressions
370
- * @param bidderRequest {BidderRequest}
371
- * @param schain {Object=} Supply chain config
372
- * @return {Object} Complete rtb request
369
+ * Create device object from fpd and host-collected data
370
+ * @param fpd {Object}
371
+ * @returns {{device: Object}}
373
372
  */
374
- function buildRtbRequest(imps, bidderRequest, schain) {
375
- let {bidderCode, gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest;
376
- let coppa = config.getConfig('coppa');
377
- let req = {
378
- 'id': auctionId,
379
- 'imp': imps,
380
- 'site': createSite(refererInfo),
381
- 'at': 1,
382
- 'device': {
383
- 'ip': 'caller',
384
- 'ipv6': 'caller',
385
- 'ua': 'caller',
386
- 'js': 1,
387
- 'language': getLanguage()
388
- },
389
- 'tmax': parseInt(timeout)
390
- };
373
+ function makeDevice(fpd) {
374
+ let device = mergeDeep({
375
+ 'ip': 'caller',
376
+ 'ipv6': 'caller',
377
+ 'ua': 'caller',
378
+ 'js': 1,
379
+ 'language': getLanguage()
380
+ }, fpd.device || {});
391
381
  if (getDNT()) {
392
- req.device.dnt = 1;
382
+ device.dnt = 1;
383
+ }
384
+ return {device: device};
385
+ }
386
+
387
+ /**
388
+ * Create site or app description object
389
+ * @param bidderRequest {BidderRequest}
390
+ * @param fpd {Object}
391
+ * @returns {{site: Object}|{app: Object}}
392
+ */
393
+ function makeSiteOrApp(bidderRequest, fpd) {
394
+ let {refererInfo} = bidderRequest;
395
+ let appConfig = config.getConfig('app');
396
+ if (isEmpty(appConfig)) {
397
+ return {site: createSite(refererInfo, fpd)}
398
+ } else {
399
+ return {app: appConfig};
393
400
  }
401
+ }
402
+
403
+ /**
404
+ * Create user description object
405
+ * @param bidderRequest {BidderRequest}
406
+ * @param fpd {Object}
407
+ * @returns {{user: Object} | undefined}
408
+ */
409
+ function makeUser(bidderRequest, fpd) {
410
+ let {gdprConsent} = bidderRequest;
411
+ let user = fpd.user || {};
412
+ if (gdprConsent && gdprConsent.consentString !== undefined) {
413
+ deepSetValue(user, 'ext.consent', gdprConsent.consentString);
414
+ }
415
+ let eids = getExtendedUserIds(bidderRequest);
416
+ if (eids) {
417
+ deepSetValue(user, 'ext.eids', eids);
418
+ }
419
+ if (!isEmpty(user)) { return {user: user}; }
420
+ }
421
+
422
+ /**
423
+ * Create privacy regulations object
424
+ * @param bidderRequest {BidderRequest}
425
+ * @returns {{regs: Object} | undefined}
426
+ */
427
+ function makeRegulations(bidderRequest) {
428
+ let {gdprConsent, uspConsent} = bidderRequest;
429
+ let regs = {};
394
430
  if (gdprConsent) {
395
431
  if (gdprConsent.gdprApplies !== undefined) {
396
- deepSetValue(req, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies);
397
- }
398
- if (gdprConsent.consentString !== undefined) {
399
- deepSetValue(req, 'user.ext.consent', gdprConsent.consentString);
432
+ deepSetValue(regs, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies);
400
433
  }
401
434
  }
402
435
  if (uspConsent) {
403
- deepSetValue(req, 'regs.ext.us_privacy', uspConsent);
436
+ deepSetValue(regs, 'regs.ext.us_privacy', uspConsent);
437
+ }
438
+ if (config.getConfig('coppa')) {
439
+ deepSetValue(regs, 'regs.coppa', 1);
404
440
  }
405
- if (coppa) {
406
- deepSetValue(req, 'regs.coppa', 1);
441
+ if (!isEmpty(regs)) {
442
+ return regs;
407
443
  }
444
+ }
445
+
446
+ /**
447
+ * Create top-level request object
448
+ * @param bidderRequest {BidderRequest}
449
+ * @param imps {Object} Impressions
450
+ * @param fpd {Object} First party data
451
+ * @returns
452
+ */
453
+ function makeBaseRequest(bidderRequest, imps, fpd) {
454
+ let {auctionId, timeout} = bidderRequest;
455
+ let request = {
456
+ 'id': auctionId,
457
+ 'imp': imps,
458
+ 'at': 1,
459
+ 'tmax': parseInt(timeout)
460
+ };
461
+ if (!isEmpty(fpd.bcat)) {
462
+ request.bcat = fpd.bcat;
463
+ }
464
+ if (!isEmpty(fpd.badv)) {
465
+ request.badv = fpd.badv;
466
+ }
467
+ return request;
468
+ }
469
+
470
+ /**
471
+ * Initialize sync capabilities
472
+ * @param bidderRequest {BidderRequest}
473
+ */
474
+ function makeSyncInfo(bidderRequest) {
475
+ let {bidderCode} = bidderRequest;
408
476
  let syncMethod = getAllowedSyncMethod(bidderCode);
409
477
  if (syncMethod) {
410
- deepSetValue(req, 'ext.adk_usersync', syncMethod);
478
+ let res = {};
479
+ deepSetValue(res, 'ext.adk_usersync', syncMethod);
480
+ return res;
411
481
  }
482
+ }
483
+
484
+ /**
485
+ * Builds complete rtb request
486
+ * @param imps {Object} Collection of rtb impressions
487
+ * @param bidderRequest {BidderRequest}
488
+ * @param schain {Object=} Supply chain config
489
+ * @return {Object} Complete rtb request
490
+ */
491
+ function buildRtbRequest(imps, bidderRequest, schain) {
492
+ let fpd = config.getConfig('ortb2') || {};
493
+
494
+ let req = mergeDeep(
495
+ makeBaseRequest(bidderRequest, imps, fpd),
496
+ makeDevice(fpd),
497
+ makeSiteOrApp(bidderRequest, fpd),
498
+ makeUser(bidderRequest, fpd),
499
+ makeRegulations(bidderRequest),
500
+ makeSyncInfo(bidderRequest)
501
+ );
412
502
  if (schain) {
413
503
  deepSetValue(req, 'source.ext.schain', schain);
414
504
  }
415
- let eids = getExtendedUserIds(bidderRequest);
416
- if (eids) {
417
- deepSetValue(req, 'user.ext.eids', eids);
418
- }
419
505
  return req;
420
506
  }
421
507
 
@@ -431,18 +517,17 @@ function getLanguage() {
431
517
  /**
432
518
  * Creates site description object
433
519
  */
434
- function createSite(refInfo) {
520
+ function createSite(refInfo, fpd) {
435
521
  let url = parseUrl(refInfo.referer);
436
522
  let site = {
437
523
  'domain': url.hostname,
438
524
  'page': `${url.protocol}://${url.hostname}${url.pathname}`
439
525
  };
440
- if (self === top && document.referrer) {
526
+ mergeDeep(site, fpd.site);
527
+ if (!inIframe() && document.referrer) {
441
528
  site.ref = document.referrer;
442
- }
443
- let keywords = document.getElementsByTagName('meta')['keywords'];
444
- if (keywords && keywords.content) {
445
- site.keywords = keywords.content;
529
+ } else {
530
+ delete site.ref;
446
531
  }
447
532
  return site;
448
533
  }
@@ -9,7 +9,7 @@
9
9
  import { registerVideoSupport } from '../src/adServerManager.js';
10
10
  import { command as analyticsCommand, COMMAND } from './adlooxAnalyticsAdapter.js';
11
11
  import { ajax } from '../src/ajax.js';
12
- import { EVENTS } from '../src/constants.json';
12
+ import CONSTANTS from '../src/constants.json';
13
13
  import { targeting } from '../src/targeting.js';
14
14
  import { logInfo, isFn, logError, isPlainObject, isStr, isBoolean, deepSetValue, deepClone, timestamp, logWarn } from '../src/utils.js';
15
15
 
@@ -74,7 +74,7 @@ function track(options, callback) {
74
74
  bid.ext.adloox.video.adserver = false;
75
75
 
76
76
  analyticsCommand(COMMAND.TRACK, {
77
- eventType: EVENTS.BID_WON,
77
+ eventType: CONSTANTS.EVENTS.BID_WON,
78
78
  args: bid
79
79
  });
80
80
  }
@@ -9,7 +9,7 @@ import adapter from '../src/AnalyticsAdapter.js';
9
9
  import { loadExternalScript } from '../src/adloader.js';
10
10
  import { auctionManager } from '../src/auctionManager.js';
11
11
  import { AUCTION_COMPLETED } from '../src/auction.js';
12
- import { EVENTS } from '../src/constants.json';
12
+ import CONSTANTS from '../src/constants.json';
13
13
  import find from 'core-js-pure/features/array/find.js';
14
14
  import {
15
15
  deepAccess, logInfo, isPlainObject, logError, isStr, isNumber, getGptSlotInfoForAdUnitCode,
@@ -199,9 +199,9 @@ analyticsAdapter.url = function(url, args, bid) {
199
199
  return url + a2qs(args);
200
200
  }
201
201
 
202
- analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) {
202
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.AUCTION_END}`] = function(auctionDetails) {
203
203
  if (!(auctionDetails.auctionStatus == AUCTION_COMPLETED && auctionDetails.bidsReceived.length > 0)) return;
204
- analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = NOOP;
204
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.AUCTION_END}`] = NOOP;
205
205
 
206
206
  logMessage(MODULE, 'preloading verification JS');
207
207
 
@@ -214,7 +214,7 @@ analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) {
214
214
  insertElement(link);
215
215
  }
216
216
 
217
- analyticsAdapter[`handle_${EVENTS.BID_WON}`] = function(bid) {
217
+ analyticsAdapter[`handle_${CONSTANTS.EVENTS.BID_WON}`] = function(bid) {
218
218
  if (deepAccess(bid, 'ext.adloox.video.adserver')) {
219
219
  logMessage(MODULE, `measuring '${bid.mediaType}' ad unit code '${bid.adUnitCode}' via Ad Server module`);
220
220
  return;
@@ -76,6 +76,8 @@ adomikAdapter.sendTypedEvent = function() {
76
76
  const groupedTypedEvents = adomikAdapter.buildTypedEvents();
77
77
 
78
78
  const bulkEvents = {
79
+ testId: adomikAdapter.currentContext.testId,
80
+ testValue: adomikAdapter.currentContext.testValue,
79
81
  uid: adomikAdapter.currentContext.uid,
80
82
  ahbaid: adomikAdapter.currentContext.id,
81
83
  hostname: window.location.hostname,
@@ -126,6 +128,8 @@ adomikAdapter.sendTypedEvent = function() {
126
128
  };
127
129
 
128
130
  adomikAdapter.sendWonEvent = function (wonEvent) {
131
+ let keyValues = { testId: adomikAdapter.currentContext.testId, testValue: adomikAdapter.currentContext.testValue }
132
+ wonEvent = {...wonEvent, ...keyValues}
129
133
  const stringWonEvent = JSON.stringify(wonEvent)
130
134
  logInfo('Won event sent to adomik prebid analytic ' + stringWonEvent);
131
135
 
@@ -205,6 +209,8 @@ adomikAdapter.enableAnalytics = function (config) {
205
209
  adomikAdapter.currentContext = {
206
210
  uid: initOptions.id,
207
211
  url: initOptions.url,
212
+ testId: initOptions.testId,
213
+ testValue: initOptions.testValue,
208
214
  id: '',
209
215
  timeouted: false,
210
216
  }
@@ -309,7 +309,7 @@ function getUserSyncs(syncOptions, serverResponses) {
309
309
  export const spec = {
310
310
  code: BIDDER_CODE,
311
311
  gvlid: GVLID,
312
- aliases: ['avantisvideo', 'selectmediavideo', 'vidcrunch', 'openwebvideo'],
312
+ aliases: ['avantisvideo', 'selectmediavideo', 'vidcrunch', 'openwebvideo', 'didnavideo'],
313
313
  supportedMediaTypes: [VIDEO, BANNER],
314
314
  isBidRequestValid,
315
315
  buildRequests,
@@ -36,7 +36,7 @@ export const spec = {
36
36
  */
37
37
  buildRequests: function(validBidRequests, bidderRequest) {
38
38
  const slots = validBidRequests.map(beOpRequestSlotsMaker);
39
- let pageUrl = deepAccess(bidderRequest, 'refererInfo.canonicalUrl') || config.getConfig('pageUrl') || deepAccess(window, 'location.href');
39
+ let pageUrl = deepAccess(window, 'location.href') || deepAccess(bidderRequest, 'refererInfo.canonicalUrl') || config.getConfig('pageUrl');
40
40
  let fpd = config.getLegacyFpd(config.getConfig('ortb2'));
41
41
  let gdpr = bidderRequest.gdprConsent;
42
42
  let firstSlot = slots[0];
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { config } from '../src/config.js';
6
6
  import * as events from '../src/events.js';
7
- import { EVENTS } from '../src/constants.json';
7
+ import CONSTANTS from '../src/constants.json';
8
8
  import { logWarn, isFn, triggerPixel } from '../src/utils.js';
9
9
  import { getGlobal } from '../src/prebidGlobal.js';
10
10
  import adapterManager, { gdprDataHandler, uspDataHandler } from '../src/adapterManager.js';
@@ -70,12 +70,12 @@ export let impressionViewableHandler = (globalModuleConfig, slot, event) => {
70
70
  // trigger respective bidder's onBidViewable handler
71
71
  adapterManager.callBidViewableBidder(respectiveBid.bidder, respectiveBid);
72
72
  // emit the BID_VIEWABLE event with bid details, this event can be consumed by bidders and analytics pixels
73
- events.emit(EVENTS.BID_VIEWABLE, respectiveBid);
73
+ events.emit(CONSTANTS.EVENTS.BID_VIEWABLE, respectiveBid);
74
74
  }
75
75
  };
76
76
 
77
77
  export let init = () => {
78
- events.on(EVENTS.AUCTION_INIT, () => {
78
+ events.on(CONSTANTS.EVENTS.AUCTION_INIT, () => {
79
79
  // read the config for the module
80
80
  const globalModuleConfig = config.getConfig(MODULE_NAME) || {};
81
81
  // do nothing if module-config.enabled is not set to true
@@ -1,7 +1,7 @@
1
1
  import { logMessage } from '../src/utils.js';
2
2
  import { config } from '../src/config.js';
3
3
  import * as events from '../src/events.js';
4
- import { EVENTS } from '../src/constants.json';
4
+ import CONSTANTS from '../src/constants.json';
5
5
 
6
6
  const MODULE_NAME = 'bidViewabilityIO';
7
7
  const CONFIG_ENABLED = 'enabled';
@@ -42,7 +42,7 @@ export let getViewableOptions = (bid) => {
42
42
  export let markViewed = (bid, entry, observer) => {
43
43
  return () => {
44
44
  observer.unobserve(entry.target);
45
- events.emit(EVENTS.BID_VIEWABLE, bid);
45
+ events.emit(CONSTANTS.EVENTS.BID_VIEWABLE, bid);
46
46
  _logMessage(`id: ${entry.target.getAttribute('id')} code: ${bid.adUnitCode} was viewed`);
47
47
  }
48
48
  }
@@ -77,7 +77,7 @@ export let init = () => {
77
77
  if (conf[MODULE_NAME][CONFIG_ENABLED] && CLIENT_SUPPORTS_IO) {
78
78
  // if the module is enabled and the browser supports Intersection Observer,
79
79
  // then listen to AD_RENDER_SUCCEEDED to setup IO's for supported mediaTypes
80
- events.on(EVENTS.AD_RENDER_SUCCEEDED, ({doc, bid, id}) => {
80
+ events.on(CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED, ({doc, bid, id}) => {
81
81
  if (isSupportedMediaType(bid)) {
82
82
  let viewable = new IntersectionObserver(viewCallbackFactory(bid), getViewableOptions(bid));
83
83
  let element = document.getElementById(bid.adUnitCode);