prebid.js 7.16.0 → 7.17.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 (131) hide show
  1. package/.circleci/config.yml +0 -18
  2. package/dist/1plusXRtdProvider.js +1 -1
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/axonixBidAdapter.js +1 -1
  17. package/dist/bidglassBidAdapter.js +1 -1
  18. package/dist/big-richmediaBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/carodaBidAdapter.js +1 -0
  22. package/dist/concertBidAdapter.js +1 -1
  23. package/dist/connectadBidAdapter.js +1 -1
  24. package/dist/consumableBidAdapter.js +1 -1
  25. package/dist/conversantBidAdapter.js +1 -1
  26. package/dist/craftBidAdapter.js +1 -1
  27. package/dist/criteoBidAdapter.js +1 -1
  28. package/dist/dspxBidAdapter.js +1 -1
  29. package/dist/eplanningBidAdapter.js +1 -1
  30. package/dist/finativeBidAdapter.js +1 -1
  31. package/dist/glimpseBidAdapter.js +1 -1
  32. package/dist/gmosspBidAdapter.js +1 -1
  33. package/dist/goldbachBidAdapter.js +1 -1
  34. package/dist/gridBidAdapter.js +1 -1
  35. package/dist/gridNMBidAdapter.js +1 -1
  36. package/dist/gumgumBidAdapter.js +1 -1
  37. package/dist/h12mediaBidAdapter.js +1 -1
  38. package/dist/id5IdSystem.js +1 -1
  39. package/dist/improvedigitalBidAdapter.js +1 -1
  40. package/dist/inmarBidAdapter.js +1 -1
  41. package/dist/insticatorBidAdapter.js +1 -1
  42. package/dist/ixBidAdapter.js +1 -1
  43. package/dist/justpremiumBidAdapter.js +1 -1
  44. package/dist/konduitAnalyticsAdapter.js +1 -1
  45. package/dist/kueezBidAdapter.js +1 -1
  46. package/dist/lassoBidAdapter.js +1 -1
  47. package/dist/lifestreetBidAdapter.js +1 -1
  48. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  49. package/dist/logicadBidAdapter.js +1 -1
  50. package/dist/loglyliftBidAdapter.js +1 -1
  51. package/dist/malltvAnalyticsAdapter.js +1 -1
  52. package/dist/marsmediaBidAdapter.js +1 -1
  53. package/dist/mediafuseBidAdapter.js +1 -1
  54. package/dist/mediagoBidAdapter.js +1 -1
  55. package/dist/mediasquareBidAdapter.js +1 -1
  56. package/dist/mgidBidAdapter.js +1 -1
  57. package/dist/minutemediaBidAdapter.js +1 -1
  58. package/dist/not-for-prod/prebid.js +108 -107
  59. package/dist/oguryBidAdapter.js +1 -1
  60. package/dist/onetagBidAdapter.js +1 -1
  61. package/dist/ooloAnalyticsAdapter.js +1 -1
  62. package/dist/outbrainBidAdapter.js +1 -1
  63. package/dist/parrableIdSystem.js +1 -1
  64. package/dist/pixfutureBidAdapter.js +1 -1
  65. package/dist/prebid-core.js +1 -1
  66. package/dist/publinkIdSystem.js +1 -1
  67. package/dist/pubmaticBidAdapter.js +1 -1
  68. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  69. package/dist/pxyzBidAdapter.js +1 -1
  70. package/dist/quantcastBidAdapter.js +1 -1
  71. package/dist/readpeakBidAdapter.js +1 -1
  72. package/dist/relaidoBidAdapter.js +1 -1
  73. package/dist/rhythmoneBidAdapter.js +1 -1
  74. package/dist/riseBidAdapter.js +1 -1
  75. package/dist/rubiconAnalyticsAdapter.js +1 -1
  76. package/dist/rubiconBidAdapter.js +1 -1
  77. package/dist/seedingAllianceBidAdapter.js +1 -1
  78. package/dist/seedtagBidAdapter.js +1 -1
  79. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  80. package/dist/sharethroughBidAdapter.js +1 -1
  81. package/dist/shinezBidAdapter.js +1 -1
  82. package/dist/smaatoBidAdapter.js +1 -1
  83. package/dist/smartadserverBidAdapter.js +1 -1
  84. package/dist/smartxBidAdapter.js +1 -1
  85. package/dist/smilewantedBidAdapter.js +1 -1
  86. package/dist/sonobiBidAdapter.js +1 -1
  87. package/dist/sovrnAnalyticsAdapter.js +1 -1
  88. package/dist/sovrnBidAdapter.js +1 -1
  89. package/dist/sspBCBidAdapter.js +1 -1
  90. package/dist/sublimeBidAdapter.js +1 -1
  91. package/dist/synacormediaBidAdapter.js +1 -1
  92. package/dist/targetVideoBidAdapter.js +1 -1
  93. package/dist/teadsBidAdapter.js +1 -1
  94. package/dist/trionBidAdapter.js +1 -1
  95. package/dist/tripleliftBidAdapter.js +1 -1
  96. package/dist/ttdBidAdapter.js +1 -1
  97. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  98. package/dist/underdogmediaBidAdapter.js +1 -1
  99. package/dist/undertoneBidAdapter.js +1 -1
  100. package/dist/vidazooBidAdapter.js +1 -1
  101. package/dist/videobyteBidAdapter.js +1 -1
  102. package/dist/visxBidAdapter.js +1 -1
  103. package/dist/vuukleBidAdapter.js +1 -1
  104. package/dist/widespaceBidAdapter.js +1 -1
  105. package/dist/winrBidAdapter.js +1 -1
  106. package/dist/yahoosspBidAdapter.js +1 -1
  107. package/dist/yieldmoBidAdapter.js +1 -1
  108. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  109. package/karma.conf.maker.js +2 -4
  110. package/modules/1plusXRtdProvider.js +27 -7
  111. package/modules/adagioBidAdapter.js +16 -2
  112. package/modules/adagioBidAdapter.md +11 -1
  113. package/modules/appnexusBidAdapter.js +24 -22
  114. package/modules/carodaBidAdapter.js +217 -0
  115. package/modules/carodaBidAdapter.md +43 -0
  116. package/modules/improvedigitalBidAdapter.js +3 -1
  117. package/modules/ixBidAdapter.js +17 -12
  118. package/modules/mediagoBidAdapter.js +15 -11
  119. package/modules/mediasquareBidAdapter.js +1 -1
  120. package/modules/rubiconAnalyticsAdapter.js +2 -2
  121. package/modules/rubiconBidAdapter.js +16 -6
  122. package/package.json +1 -1
  123. package/test/spec/modules/1plusXRtdProvider_spec.js +77 -1
  124. package/test/spec/modules/adagioBidAdapter_spec.js +23 -2
  125. package/test/spec/modules/appnexusBidAdapter_spec.js +76 -0
  126. package/test/spec/modules/carodaBidAdapter_spec.js +494 -0
  127. package/test/spec/modules/improvedigitalBidAdapter_spec.js +10 -0
  128. package/test/spec/modules/ixBidAdapter_spec.js +32 -16
  129. package/test/spec/modules/mediasquareBidAdapter_spec.js +2 -0
  130. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +7 -7
  131. package/test/spec/modules/rubiconBidAdapter_spec.js +28 -35
@@ -1109,15 +1109,25 @@ function mapSizes(sizes) {
1109
1109
 
1110
1110
  /**
1111
1111
  * Test if bid has mediaType or mediaTypes set for video.
1112
- * Also makes sure the video object is present in the rubicon bidder params
1112
+ * Also checks if the video object is present in the rubicon bidder params
1113
1113
  * @param {BidRequest} bidRequest
1114
1114
  * @returns {boolean}
1115
1115
  */
1116
- export function hasVideoMediaType(bidRequest) {
1117
- if (typeof deepAccess(bidRequest, 'params.video') !== 'object') {
1118
- return false;
1116
+ export function classifiedAsVideo(bidRequest) {
1117
+ let isVideo = typeof deepAccess(bidRequest, `mediaTypes.${VIDEO}`) !== 'undefined';
1118
+ let isBanner = typeof deepAccess(bidRequest, `mediaTypes.${BANNER}`) !== 'undefined';
1119
+ let isMissingVideoParams = typeof deepAccess(bidRequest, 'params.video') !== 'object';
1120
+ // If an ad has both video and banner types, a legacy implementation allows choosing video over banner
1121
+ // based on whether or not there is a video object defined in the params
1122
+ // Given this legacy implementation, other code depends on params.video being defined
1123
+
1124
+ if (isBanner && isMissingVideoParams) {
1125
+ isVideo = false;
1119
1126
  }
1120
- return (typeof deepAccess(bidRequest, `mediaTypes.${VIDEO}`) !== 'undefined');
1127
+ if (isVideo && isMissingVideoParams) {
1128
+ deepSetValue(bidRequest, 'params.video', {});
1129
+ }
1130
+ return isVideo;
1121
1131
  }
1122
1132
 
1123
1133
  /**
@@ -1128,7 +1138,7 @@ export function hasVideoMediaType(bidRequest) {
1128
1138
  */
1129
1139
  function bidType(bid, log = false) {
1130
1140
  // Is it considered video ad unit by rubicon
1131
- if (hasVideoMediaType(bid)) {
1141
+ if (classifiedAsVideo(bid)) {
1132
1142
  // Removed legacy mediaType support. new way using mediaTypes.video object is now required
1133
1143
  // We require either context as instream or outstream
1134
1144
  if (['outstream', 'instream'].indexOf(deepAccess(bid, `mediaTypes.${VIDEO}.context`)) === -1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "7.16.0",
3
+ "version": "7.17.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -5,7 +5,9 @@ import {
5
5
  extractConfig,
6
6
  buildOrtb2Updates,
7
7
  updateBidderConfig,
8
- setTargetingDataToConfig
8
+ setTargetingDataToConfig,
9
+ extractConsent,
10
+ getPapiUrl
9
11
  } from 'modules/1plusXRtdProvider';
10
12
 
11
13
  describe('1plusXRtdProvider', () => {
@@ -251,6 +253,80 @@ describe('1plusXRtdProvider', () => {
251
253
  })
252
254
  })
253
255
 
256
+ describe('extractConsent', () => {
257
+ it('extracts consent strings correctly if given', () => {
258
+ const consent = {
259
+ gdpr: {
260
+ gdprApplies: 1,
261
+ consentString: 'myConsent'
262
+ }
263
+ }
264
+ const output = extractConsent(consent)
265
+ const expectedOutput = {
266
+ gdpr_applies: 1,
267
+ consent_string: 'myConsent'
268
+ }
269
+ expect(expectedOutput).to.deep.include(output)
270
+ expect(output).to.deep.include(expectedOutput)
271
+ })
272
+ it('extracts null if consent object is empty', () => {
273
+ const consent1 = {}
274
+ expect(extractConsent(consent1)).to.equal(null)
275
+ })
276
+
277
+ it('throws an error if the consent is malformed', () => {
278
+ const consent1 = {
279
+ gdpr: {
280
+ gdprApplies: 1
281
+ }
282
+ }
283
+ const consent2 = {
284
+ gdpr: {
285
+ consentString: 'myConsent'
286
+ }
287
+ }
288
+ const consent3 = {
289
+ gdpr: {
290
+ gdprApplies: 1,
291
+ consentString: 3
292
+ }
293
+ }
294
+ const consent4 = {
295
+ gdpr: {
296
+ gdprApplies: 'yes',
297
+ consentString: 'myConsent'
298
+ }
299
+ }
300
+ const consent5 = {
301
+ gdprApplies: 1,
302
+ consentString: 'myConsent'
303
+ }
304
+
305
+ for (const consent in [consent1, consent2, consent3, consent4, consent5]) {
306
+ try {
307
+ extractConsent(consent)
308
+ assert(false, 'Should be throwing an exception')
309
+ } catch (e) { }
310
+ }
311
+ })
312
+ })
313
+
314
+ describe('getPapiUrl', () => {
315
+ const customer = 'acme'
316
+ const consent = {
317
+ gdpr: {
318
+ gdprApplies: 1,
319
+ consentString: 'myConsent'
320
+ }
321
+ }
322
+
323
+ it('correctly builds URLs based on consent', () => {
324
+ const url1 = getPapiUrl(customer)
325
+ const url2 = getPapiUrl(customer, extractConsent(consent))
326
+ expect(['&consent_string=myConsent&gdpr_applies=1', '&gdpr_applies=1&consent_string=myConsent']).to.contain(url2.replace(url1, ''))
327
+ })
328
+ })
329
+
254
330
  describe('updateBidderConfig', () => {
255
331
  const ortb2UpdatesAppNexus = {
256
332
  site: {
@@ -150,7 +150,9 @@ describe('Adagio bid adapter', () => {
150
150
  ext: {
151
151
  data: {
152
152
  environment: 'desktop',
153
- pagetype: 'abc'
153
+ pagetype: 'abc',
154
+ category: ['cat1', 'cat2', 'cat3'],
155
+ subcategory: []
154
156
  }
155
157
  }
156
158
  }
@@ -170,6 +172,12 @@ describe('Adagio bid adapter', () => {
170
172
 
171
173
  setExtraParam(bid, 'pagetype')
172
174
  expect(bid.params.pagetype).to.equal('article');
175
+
176
+ setExtraParam(bid, 'category');
177
+ expect(bid.params.category).to.equal('cat1'); // Only the first value is kept
178
+
179
+ setExtraParam(bid, 'subcategory');
180
+ expect(bid.params.subcategory).to.be.undefined;
173
181
  });
174
182
 
175
183
  it('should use the adUnit param unit if defined', function() {
@@ -1081,7 +1089,7 @@ describe('Adagio bid adapter', () => {
1081
1089
  impressionTrackers: [
1082
1090
  'https://eventrack.local/impression'
1083
1091
  ],
1084
- javascriptTrackers: '<script src=\"https://eventrack.local/impression\"></script>',
1092
+ javascriptTrackers: '<script async src=\"https://eventrack.local/impression\"></script>',
1085
1093
  clickTrackers: [
1086
1094
  'https://i.am.a.clicktracker.url'
1087
1095
  ],
@@ -1104,6 +1112,19 @@ describe('Adagio bid adapter', () => {
1104
1112
  expect(r[0].native).ok;
1105
1113
  expect(r[0].native).to.deep.equal(expected);
1106
1114
  });
1115
+
1116
+ it('Should handle multiple javascriptTrackers in one single string', () => {
1117
+ const serverResponseWithNativeCopy = utils.deepClone(serverResponseWithNative);
1118
+ serverResponseWithNativeCopy.body.bids[0].admNative.eventtrackers.push(
1119
+ {
1120
+ event: 1,
1121
+ method: 2,
1122
+ url: 'https://eventrack.local/impression-2'
1123
+ },)
1124
+ const r = spec.interpretResponse(serverResponseWithNativeCopy, bidRequestNative);
1125
+ const expected = '<script async src=\"https://eventrack.local/impression\"></script>\n<script async src=\"https://eventrack.local/impression-2\"></script>';
1126
+ expect(r[0].native.javascriptTrackers).to.equal(expected);
1127
+ });
1107
1128
  });
1108
1129
  });
1109
1130
 
@@ -757,6 +757,82 @@ describe('AppNexusAdapter', function () {
757
757
  });
758
758
  }
759
759
 
760
+ it('should convert keyword params (when there are no ortb keywords) to proper form and attaches to request', function () {
761
+ let bidRequest = Object.assign({},
762
+ bidRequests[0],
763
+ {
764
+ params: {
765
+ placementId: '10433394',
766
+ keywords: {
767
+ single: 'val',
768
+ singleArr: ['val'],
769
+ singleArrNum: [5],
770
+ multiValMixed: ['value1', 2, 'value3'],
771
+ singleValNum: 123,
772
+ emptyStr: '',
773
+ emptyArr: [''],
774
+ badValue: { 'foo': 'bar' } // should be dropped
775
+ }
776
+ }
777
+ }
778
+ );
779
+
780
+ const request = spec.buildRequests([bidRequest]);
781
+ const payload = JSON.parse(request.data);
782
+
783
+ expect(payload.tags[0].keywords).to.deep.equal([{
784
+ 'key': 'single',
785
+ 'value': ['val']
786
+ }, {
787
+ 'key': 'singleArr',
788
+ 'value': ['val']
789
+ }, {
790
+ 'key': 'singleArrNum',
791
+ 'value': ['5']
792
+ }, {
793
+ 'key': 'multiValMixed',
794
+ 'value': ['value1', '2', 'value3']
795
+ }, {
796
+ 'key': 'singleValNum',
797
+ 'value': ['123']
798
+ }, {
799
+ 'key': 'emptyStr'
800
+ }, {
801
+ 'key': 'emptyArr'
802
+ }]);
803
+ });
804
+
805
+ it('should convert adUnit ortb2 keywords (when there are no bid param keywords) to proper form and attaches to request', function () {
806
+ let bidRequest = Object.assign({},
807
+ bidRequests[0],
808
+ {
809
+ ortb2Imp: {
810
+ ext: {
811
+ data: {
812
+ keywords: 'ortb2=yes,ortb2test, multiValMixed=4, singleValNum=456'
813
+ }
814
+ }
815
+ }
816
+ }
817
+ );
818
+
819
+ const request = spec.buildRequests([bidRequest]);
820
+ const payload = JSON.parse(request.data);
821
+
822
+ expect(payload.tags[0].keywords).to.deep.equal([{
823
+ 'key': 'ortb2',
824
+ 'value': ['yes']
825
+ }, {
826
+ 'key': 'ortb2test'
827
+ }, {
828
+ 'key': 'multiValMixed',
829
+ 'value': ['4']
830
+ }, {
831
+ 'key': 'singleValNum',
832
+ 'value': ['456']
833
+ }]);
834
+ });
835
+
760
836
  it('should convert keyword params and adUnit ortb2 keywords to proper form and attaches to request', function () {
761
837
  let bidRequest = Object.assign({},
762
838
  bidRequests[0],