prebid.js 7.25.0 → 7.26.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 (168) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/admaticBidAdapter.js +1 -1
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/beopBidAdapter.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/captifyRtdProvider.js +1 -0
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/chtnwBidAdapter.js +1 -1
  24. package/dist/concertBidAdapter.js +1 -1
  25. package/dist/connectadBidAdapter.js +1 -1
  26. package/dist/consumableBidAdapter.js +1 -1
  27. package/dist/conversantBidAdapter.js +1 -1
  28. package/dist/craftBidAdapter.js +1 -1
  29. package/dist/criteoBidAdapter.js +1 -1
  30. package/dist/discoveryBidAdapter.js +1 -1
  31. package/dist/dspxBidAdapter.js +1 -1
  32. package/dist/eplanningBidAdapter.js +1 -1
  33. package/dist/finativeBidAdapter.js +1 -1
  34. package/dist/glimpseBidAdapter.js +1 -1
  35. package/dist/gmosspBidAdapter.js +1 -1
  36. package/dist/goldbachBidAdapter.js +1 -1
  37. package/dist/gridBidAdapter.js +1 -1
  38. package/dist/gridNMBidAdapter.js +1 -1
  39. package/dist/gumgumBidAdapter.js +1 -1
  40. package/dist/h12mediaBidAdapter.js +1 -1
  41. package/dist/id5IdSystem.js +1 -1
  42. package/dist/improvedigitalBidAdapter.js +1 -1
  43. package/dist/inmarBidAdapter.js +1 -1
  44. package/dist/insticatorBidAdapter.js +1 -1
  45. package/dist/ixBidAdapter.js +1 -1
  46. package/dist/justpremiumBidAdapter.js +1 -1
  47. package/dist/konduitAnalyticsAdapter.js +1 -1
  48. package/dist/kueezBidAdapter.js +1 -1
  49. package/dist/kueezRtbBidAdapter.js +1 -1
  50. package/dist/lassoBidAdapter.js +1 -1
  51. package/dist/lifestreetBidAdapter.js +1 -1
  52. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  53. package/dist/logicadBidAdapter.js +1 -1
  54. package/dist/loglyliftBidAdapter.js +1 -1
  55. package/dist/magniteAnalyticsAdapter.js +1 -1
  56. package/dist/malltvAnalyticsAdapter.js +1 -1
  57. package/dist/marsmediaBidAdapter.js +1 -1
  58. package/dist/mediafuseBidAdapter.js +1 -1
  59. package/dist/mediasquareBidAdapter.js +1 -1
  60. package/dist/mgidBidAdapter.js +1 -1
  61. package/dist/minutemediaBidAdapter.js +1 -1
  62. package/dist/nextMillenniumBidAdapter.js +1 -1
  63. package/dist/not-for-prod/prebid.js +152 -118
  64. package/dist/oguryBidAdapter.js +1 -1
  65. package/dist/onetagBidAdapter.js +1 -1
  66. package/dist/ooloAnalyticsAdapter.js +1 -1
  67. package/dist/outbrainBidAdapter.js +1 -1
  68. package/dist/parrableIdSystem.js +1 -1
  69. package/dist/pixfutureBidAdapter.js +1 -1
  70. package/dist/prebid-core.js +1 -1
  71. package/dist/publinkIdSystem.js +1 -1
  72. package/dist/pubmaticBidAdapter.js +1 -1
  73. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  74. package/dist/pxyzBidAdapter.js +1 -1
  75. package/dist/quantcastBidAdapter.js +1 -1
  76. package/dist/readpeakBidAdapter.js +1 -1
  77. package/dist/relaidoBidAdapter.js +1 -1
  78. package/dist/rhythmoneBidAdapter.js +1 -1
  79. package/dist/riseBidAdapter.js +1 -1
  80. package/dist/rubiconAnalyticsAdapter.js +1 -1
  81. package/dist/rubiconBidAdapter.js +1 -1
  82. package/dist/seedingAllianceBidAdapter.js +1 -1
  83. package/dist/seedtagBidAdapter.js +1 -1
  84. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  85. package/dist/sharethroughBidAdapter.js +1 -1
  86. package/dist/shinezBidAdapter.js +1 -1
  87. package/dist/smaatoBidAdapter.js +1 -1
  88. package/dist/smartadserverBidAdapter.js +1 -1
  89. package/dist/smartxBidAdapter.js +1 -1
  90. package/dist/smartytechBidAdapter.js +1 -0
  91. package/dist/smilewantedBidAdapter.js +1 -1
  92. package/dist/sonobiBidAdapter.js +1 -1
  93. package/dist/sovrnAnalyticsAdapter.js +1 -1
  94. package/dist/sovrnBidAdapter.js +1 -1
  95. package/dist/sspBCBidAdapter.js +1 -1
  96. package/dist/sublimeBidAdapter.js +1 -1
  97. package/dist/synacormediaBidAdapter.js +1 -1
  98. package/dist/taboolaBidAdapter.js +1 -1
  99. package/dist/tappxBidAdapter.js +1 -1
  100. package/dist/targetVideoBidAdapter.js +1 -1
  101. package/dist/teadsBidAdapter.js +1 -1
  102. package/dist/trionBidAdapter.js +1 -1
  103. package/dist/tripleliftBidAdapter.js +1 -1
  104. package/dist/ttdBidAdapter.js +1 -1
  105. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  106. package/dist/underdogmediaBidAdapter.js +1 -1
  107. package/dist/undertoneBidAdapter.js +1 -1
  108. package/dist/userId.js +1 -1
  109. package/dist/vidazooBidAdapter.js +1 -1
  110. package/dist/videobyteBidAdapter.js +1 -1
  111. package/dist/viqeoBidAdapter.js +1 -0
  112. package/dist/visxBidAdapter.js +1 -1
  113. package/dist/vuukleBidAdapter.js +1 -1
  114. package/dist/widespaceBidAdapter.js +1 -1
  115. package/dist/winrBidAdapter.js +1 -1
  116. package/dist/yahoosspBidAdapter.js +1 -1
  117. package/dist/yieldlabBidAdapter.js +1 -1
  118. package/dist/yieldmoBidAdapter.js +1 -1
  119. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  120. package/dist/zeta_global_sspBidAdapter.js +1 -1
  121. package/dist/zeusPrimeRtdProvider.js +31 -0
  122. package/integrationExamples/gpt/captifyRtdProvider_example.html +167 -0
  123. package/modules/.submodules.json +3 -1
  124. package/modules/admaticBidAdapter.js +108 -59
  125. package/modules/admaticBidAdapter.md +2 -2
  126. package/modules/beopBidAdapter.js +17 -2
  127. package/modules/captifyRtdProvider.js +146 -0
  128. package/modules/captifyRtdProvider.md +68 -0
  129. package/modules/discoveryBidAdapter.js +38 -17
  130. package/modules/discoveryBidAdapter.md +7 -6
  131. package/modules/gridBidAdapter.js +440 -22
  132. package/modules/nextMillenniumBidAdapter.js +19 -23
  133. package/modules/smartadserverBidAdapter.js +6 -2
  134. package/modules/smartxBidAdapter.js +10 -7
  135. package/modules/smartytechBidAdapter.js +78 -0
  136. package/modules/smartytechBidAdapter.md +44 -0
  137. package/modules/taboolaBidAdapter.js +3 -3
  138. package/modules/taboolaBidAdapter.md +0 -2
  139. package/modules/tappxBidAdapter.js +21 -6
  140. package/modules/ttdBidAdapter.js +4 -3
  141. package/modules/userId/index.js +1 -1
  142. package/modules/vidazooBidAdapter.js +15 -2
  143. package/modules/viqeoBidAdapter.js +180 -0
  144. package/modules/viqeoBidAdapter.md +56 -0
  145. package/modules/yieldlabBidAdapter.js +19 -8
  146. package/modules/yieldoneBidAdapter.js +60 -8
  147. package/modules/yieldoneBidAdapter.md +109 -9
  148. package/modules/zeta_global_sspBidAdapter.js +4 -0
  149. package/modules/zeusPrimeRtdProvider.js +357 -0
  150. package/modules/zeusPrimeRtdProvider.md +60 -0
  151. package/package.json +1 -1
  152. package/src/adloader.js +0 -1
  153. package/test/spec/modules/admaticBidAdapter_spec.js +262 -3
  154. package/test/spec/modules/beopBidAdapter_spec.js +52 -0
  155. package/test/spec/modules/captifyRtdProvider_spec.js +253 -0
  156. package/test/spec/modules/discoveryBidAdapter_spec.js +9 -8
  157. package/test/spec/modules/gridBidAdapter_spec.js +289 -1
  158. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +4 -3
  159. package/test/spec/modules/smartadserverBidAdapter_spec.js +80 -0
  160. package/test/spec/modules/smartxBidAdapter_spec.js +32 -0
  161. package/test/spec/modules/smartytechBidAdapter_spec.js +162 -0
  162. package/test/spec/modules/taboolaBidAdapter_spec.js +0 -77
  163. package/test/spec/modules/ttdBidAdapter_spec.js +13 -0
  164. package/test/spec/modules/viqeoBidAdapter_spec.js +124 -0
  165. package/test/spec/modules/yieldlabBidAdapter_spec.js +125 -0
  166. package/test/spec/modules/yieldoneBidAdapter_spec.js +30 -6
  167. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +16 -1
  168. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +410 -0
@@ -4,6 +4,17 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
4
4
  import { Renderer } from '../src/Renderer.js';
5
5
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
6
6
 
7
+ /**
8
+ * @typedef {import('../src/adapters/bidderFactory').Bid} Bid
9
+ * @typedef {import('../src/adapters/bidderFactory').BidRequest} BidRequest
10
+ * @typedef {import('../src/adapters/bidderFactory').BidderSpec} BidderSpec
11
+ * @typedef {import('../src/adapters/bidderFactory').ServerRequest} ServerRequest
12
+ * @typedef {import('../src/adapters/bidderFactory').ServerResponse} ServerResponse
13
+ * @typedef {import('../src/adapters/bidderFactory').SyncOptions} SyncOptions
14
+ * @typedef {import('../src/adapters/bidderFactory').UserSync} UserSync
15
+ * @typedef {import('../src/auction').BidderRequest} BidderRequest
16
+ */
17
+
7
18
  const BIDDER_CODE = 'yieldone';
8
19
  const ENDPOINT_URL = 'https://y.one.impact-ad.jp/h_bid';
9
20
  const USER_SYNC_URL = 'https://y.one.impact-ad.jp/push_sync';
@@ -13,13 +24,25 @@ const VIEWABLE_PERCENTAGE_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstvi
13
24
 
14
25
  const DEFAULT_VIDEO_SIZE = {w: 640, h: 360};
15
26
 
27
+ /** @type BidderSpec */
16
28
  export const spec = {
17
29
  code: BIDDER_CODE,
18
30
  aliases: ['y1'],
19
31
  supportedMediaTypes: [BANNER, VIDEO],
32
+ /**
33
+ * Determines whether or not the given bid request is valid.
34
+ * @param {BidRequest} bid The bid params to validate.
35
+ * @returns {boolean} True if this is a valid bid, and false otherwise.
36
+ */
20
37
  isBidRequestValid: function(bid) {
21
38
  return !!(bid.params.placementId);
22
39
  },
40
+ /**
41
+ * Make a server request from the list of BidRequests.
42
+ * @param {Bid[]} validBidRequests - An array of bids.
43
+ * @param {BidderRequest} bidderRequest - bidder request object.
44
+ * @returns {ServerRequest|ServerRequest[]} ServerRequest Info describing the request to the server.
45
+ */
23
46
  buildRequests: function(validBidRequests, bidderRequest) {
24
47
  return validBidRequests.map(bidRequest => {
25
48
  const params = bidRequest.params;
@@ -96,6 +119,12 @@ export const spec = {
96
119
  };
97
120
  });
98
121
  },
122
+ /**
123
+ * Unpack the response from the server into a list of bids.
124
+ * @param {ServerResponse} serverResponse - A successful response from the server.
125
+ * @param {BidRequest} bidRequests
126
+ * @returns {Bid[]} - An array of bids which were nested inside the server.
127
+ */
99
128
  interpretResponse: function(serverResponse, bidRequest) {
100
129
  const bidResponses = [];
101
130
  const response = serverResponse.body;
@@ -188,6 +217,11 @@ export const spec = {
188
217
  }
189
218
  return bidResponses;
190
219
  },
220
+ /**
221
+ * Register the user sync pixels which should be dropped after the auction.
222
+ * @param {SyncOptions} syncOptions Which user syncs are allowed?
223
+ * @returns {UserSync[]} The user syncs which should be dropped.
224
+ */
191
225
  getUserSyncs: function(syncOptions) {
192
226
  if (syncOptions.iframeEnabled) {
193
227
  return [{
@@ -202,7 +236,7 @@ export const spec = {
202
236
  * NOTE: server side does not yet support multiple formats.
203
237
  * @param {Object} bidRequest -
204
238
  * @param {boolean} [enabledOldFormat = true] - default: `true`.
205
- * @return {string|null} - `"banner"` or `"video"` or `null`.
239
+ * @returns {string|null} - `"banner"` or `"video"` or `null`.
206
240
  */
207
241
  function getMediaType(bidRequest, enabledOldFormat = true) {
208
242
  let hasBannerType = Boolean(deepAccess(bidRequest, 'mediaTypes.banner'));
@@ -239,7 +273,7 @@ function getMediaType(bidRequest, enabledOldFormat = true) {
239
273
  * @param {Object} bidRequest.banner -
240
274
  * @param {Array<string>} bidRequest.banner.sizes -
241
275
  * @param {boolean} [enabledOldFormat = true] - default: `true`.
242
- * @return {string} - strings like `"300x250"` or `"300x250,728x90"`.
276
+ * @returns {string} - strings like `"300x250"` or `"300x250,728x90"`.
243
277
  */
244
278
  function getBannerSizes(bidRequest, enabledOldFormat = true) {
245
279
  let sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes');
@@ -254,10 +288,10 @@ function getBannerSizes(bidRequest, enabledOldFormat = true) {
254
288
  /**
255
289
  * @param {Object} bidRequest -
256
290
  * @param {boolean} [enabledOldFormat = true] - default: `true`.
257
- * @param {boolean} [enabledFlux = true] - default: `true`.
258
- * @return {{w: number, h: number}} -
291
+ * @param {boolean} [enabled1x1 = true] - default: `true`.
292
+ * @returns {{w: number, h: number}} -
259
293
  */
260
- function getVideoSize(bidRequest, enabledOldFormat = true, enabledFlux = true) {
294
+ function getVideoSize(bidRequest, enabledOldFormat = true, enabled1x1 = true) {
261
295
  /**
262
296
  * @param {Array<number, number> | Array<Array<number, number>>} sizes -
263
297
  * @return {{w: number, h: number} | null} -
@@ -287,10 +321,10 @@ function getVideoSize(bidRequest, enabledOldFormat = true, enabledFlux = true) {
287
321
  playerSize = playerSize || _getPlayerSize(bidRequest.sizes);
288
322
  }
289
323
 
290
- if (enabledFlux) {
291
- // NOTE: `video.playerSize` in Flux is always [1,1].
324
+ if (enabled1x1) {
325
+ // NOTE: `video.playerSize` in 1x1 is always [1,1].
292
326
  if (playerSize && (playerSize.w === 1 && playerSize.h === 1)) {
293
- // NOTE: `params.playerSize` is a specific object to support `FLUX`.
327
+ // NOTE: `params.playerSize` is a specific object to support `1x1`.
294
328
  playerSize = _getPlayerSize(deepAccess(bidRequest, 'params.playerSize'));
295
329
  }
296
330
  }
@@ -298,6 +332,11 @@ function getVideoSize(bidRequest, enabledOldFormat = true, enabledFlux = true) {
298
332
  return playerSize || DEFAULT_VIDEO_SIZE;
299
333
  }
300
334
 
335
+ /**
336
+ * Create render for outstream video.
337
+ * @param {Object} serverResponse.body -
338
+ * @returns {Renderer} - Prebid Renderer object
339
+ */
301
340
  function newRenderer(response) {
302
341
  const renderer = Renderer.install({
303
342
  id: response.uid,
@@ -314,12 +353,21 @@ function newRenderer(response) {
314
353
  return renderer;
315
354
  }
316
355
 
356
+ /**
357
+ * Handles an outstream response after the library is loaded
358
+ * @param {Object} bid
359
+ */
317
360
  function outstreamRender(bid) {
318
361
  bid.renderer.push(() => {
319
362
  window.DACIVTPREBID.renderPrebid(bid);
320
363
  });
321
364
  }
322
365
 
366
+ /**
367
+ * Create render for cmer outstream video.
368
+ * @param {Object} serverResponse.body -
369
+ * @returns {Renderer} - Prebid Renderer object
370
+ */
323
371
  function newCmerRenderer(response) {
324
372
  const renderer = Renderer.install({
325
373
  id: response.uid,
@@ -336,6 +384,10 @@ function newCmerRenderer(response) {
336
384
  return renderer;
337
385
  }
338
386
 
387
+ /**
388
+ * Handles an outstream response after the library is loaded
389
+ * @param {Object} bid
390
+ */
339
391
  function cmerRender(bid) {
340
392
  bid.renderer.push(() => {
341
393
  window.CMERYONEPREBID.renderPrebid(bid);
@@ -13,8 +13,7 @@ Connect to YIELDONE for bids.
13
13
  THE YIELDONE adapter requires setup and approval from the YIELDONE team.
14
14
  Please reach out to your account team or y1s@platform-one.co.jp for more information.
15
15
 
16
- Note: THE YIELDONE adapter do not support "multi-format" scenario... if both
17
- banner and video are specified as mediatypes, YIELDONE will treat it as a video unit.
16
+ YIELDONE adapter supports Banner, Video and Multi-Format(video, banner) currently.
18
17
 
19
18
  # Test Parameters
20
19
  ```javascript
@@ -24,13 +23,16 @@ var adUnits = [
24
23
  code: 'banner-div',
25
24
  mediaTypes: {
26
25
  banner: {
27
- sizes: [[300, 250], [336, 280]]
26
+ sizes: [
27
+ [300, 250],
28
+ [336, 280]
29
+ ]
28
30
  }
29
31
  },
30
32
  bids: [{
31
33
  bidder: 'yieldone',
32
34
  params: {
33
- placementId: '36891'
35
+ placementId: '36891' // required
34
36
  }
35
37
  }]
36
38
  },
@@ -44,11 +46,109 @@ var adUnits = [
44
46
  },
45
47
  },
46
48
  bids: [{
47
- bidder: 'yieldone',
48
- params: {
49
- placementId: '41993'
50
- }
51
- }]
49
+ bidder: "yieldone",
50
+ params: {
51
+ placementId: "36892", // required
52
+ playerParams: { // optional
53
+ wrapperWidth: "320px", // optional
54
+ wrapperHeight: "180px" // optional
55
+ },
56
+ }
57
+ }]
58
+ },
59
+ // Video adUnit(mediaTypes.video.playerSize: [1,1])
60
+ {
61
+ code: 'video-1x1-div',
62
+ mediaTypes: {
63
+ video: {
64
+ playerSize: [[1, 1]],
65
+ context: 'outstream'
66
+ },
67
+ },
68
+ bids: [{
69
+ bidder: 'yieldone',
70
+ params: {
71
+ placementId: "36892", // required
72
+ playerSize: [640, 360], // required
73
+ playerParams: { // optional
74
+ wrapperWidth: "320px", // optional
75
+ wrapperHeight: "180px" // optional
76
+ },
77
+ }
78
+ }]
79
+ },
80
+ // Multi-Format adUnit
81
+ {
82
+ code: "multi-format-div",
83
+ mediaTypes: {
84
+ banner: {
85
+ sizes: [
86
+ [300, 250],
87
+ [1, 1]
88
+ ]
89
+ },
90
+ video: {
91
+ playerSize: [640, 360],
92
+ context: "outstream"
93
+ }
94
+ },
95
+ bids: [{
96
+ // * "video" bid object should be placed before "banner" bid object.
97
+ // This bid will request a "video" media type ad.
98
+ bidder: "yieldone",
99
+ params: {
100
+ placementId: "36892", // required
101
+ playerParams: { // required
102
+ wrapperWidth: "320px", // optional
103
+ wrapperHeight: "180px" // optional
104
+ },
105
+ }
106
+ },
107
+ {
108
+ // This bid will request a "banner" media type ad.
109
+ bidder: "yieldone",
110
+ params: {
111
+ placementId: "36891" // required
112
+ }
113
+ }
114
+ ]
115
+ },
116
+ // Multi-Format adUnit(mediaTypes.video.playerSize: [1,1])
117
+ {
118
+ code: "multi-format-1x1-div",
119
+ mediaTypes: {
120
+ banner: {
121
+ sizes: [
122
+ [300, 250],
123
+ [1, 1]
124
+ ]
125
+ },
126
+ video: {
127
+ playerSize: [1, 1],
128
+ context: "outstream"
129
+ }
130
+ },
131
+ bids: [{
132
+ // * "video" bid object should be placed before "banner" bid object.
133
+ // This bid will request a "video" media type ad.
134
+ bidder: "yieldone",
135
+ params: {
136
+ placementId: "36892", // required
137
+ playerSize: [640, 360], // required
138
+ playerParams: { // required
139
+ wrapperWidth: "320px", // optional
140
+ wrapperHeight: "180px" // optional
141
+ },
142
+ }
143
+ },
144
+ {
145
+ // This bid will request a "banner" media type ad.
146
+ bidder: "yieldone",
147
+ params: {
148
+ placementId: "36891" // required
149
+ }
150
+ }
151
+ ]
52
152
  }
53
153
  ```
54
154
 
@@ -129,6 +129,10 @@ export const spec = {
129
129
  deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent);
130
130
  }
131
131
 
132
+ if (bidderRequest?.timeout) {
133
+ payload.tmax = bidderRequest.timeout;
134
+ }
135
+
132
136
  provideEids(validBidRequests[0], payload);
133
137
  const url = params.shortname ? ENDPOINT_URL.concat('?shortname=', params.shortname) : ENDPOINT_URL;
134
138
  return {
@@ -0,0 +1,357 @@
1
+ /**
2
+ * This module adds Zeus Insights For Publishers (ZIP) provider to the real time data module
3
+ * The {@link module:modules/realTimeData} module is required
4
+ *
5
+ * This module will request the article topics for the current page and add them as page keyvalues
6
+ * for the ad requests.
7
+ *
8
+ * @module modules/zeusInsightsForPublishersRtdProvider
9
+ * @requires module:modules/realTimeData
10
+ */
11
+
12
+ import { logInfo, logError, logWarn, logMessage } from '../src/utils.js'
13
+ import { submodule } from '../src/hook.js'
14
+ import { ajaxBuilder } from '../src/ajax.js'
15
+
16
+ class Logger {
17
+ get showDebug() {
18
+ if (this._showDebug === true || this._showDebug === false) {
19
+ return this._showDebug
20
+ }
21
+
22
+ return window.zeusPrime?.debug || false
23
+ }
24
+ set showDebug(shouldShow) {
25
+ this._showDebug = shouldShow
26
+ }
27
+
28
+ get error() {
29
+ return logError.bind(this, 'zeusPrimeRtdProvider: ')
30
+ }
31
+ get warn() {
32
+ return logWarn.bind(this, 'zeusPrimeRtdProvider: ')
33
+ }
34
+ get info() {
35
+ return logInfo.bind(this, 'zeusPrimeRtdProvider: ')
36
+ }
37
+ get debug() {
38
+ if (this.showDebug) {
39
+ return logMessage.bind(this, 'zeusPrimeRtdProvider: ')
40
+ }
41
+
42
+ return () => {}
43
+ }
44
+ }
45
+
46
+ var logger = new Logger()
47
+
48
+ function loadCommandQueue() {
49
+ window.zeusPrime = window.zeusPrime || { cmd: [] }
50
+ const queue = [...window.zeusPrime.cmd]
51
+
52
+ window.zeusPrime.cmd = []
53
+ window.zeusPrime.cmd.push = (callback) => {
54
+ callback(window.zeusPrime)
55
+ }
56
+
57
+ queue.forEach((callback) => callback(window.zeusPrime))
58
+ }
59
+
60
+ function markStatusComplete(key) {
61
+ const status = window?.zeusPrime?.status
62
+ if (status) {
63
+ status[key] = true
64
+ }
65
+ }
66
+
67
+ function createStatus() {
68
+ if (window.zeusPrime && !window.zeusPrime.status) {
69
+ Object.defineProperty(window.zeusPrime, 'status', {
70
+ enumerable: false,
71
+ value: {
72
+ initComplete: false,
73
+ primeKeyValueSet: false,
74
+ insightsReqSent: false,
75
+ insightsReqReceived: false,
76
+ insightsKeyValueSet: false,
77
+ scriptComplete: false,
78
+ },
79
+ })
80
+ }
81
+ }
82
+
83
+ function loadPrimeQueryParams() {
84
+ try {
85
+ const params = new URLSearchParams(window.location.search)
86
+ params.forEach((paramValue, paramKey) => {
87
+ if (!paramKey.startsWith('zeus_prime_')) {
88
+ return
89
+ }
90
+
91
+ let key = paramKey.replace('zeus_prime_', '')
92
+ let value = paramValue.toLowerCase()
93
+
94
+ if (value === 'true' || value === '1') {
95
+ value = true
96
+ } else if (value === 'false' || value === '0') {
97
+ value = false
98
+ }
99
+
100
+ window.zeusPrime[key] = value
101
+ })
102
+ } catch (_) {}
103
+ }
104
+
105
+ const DEFAULT_API = 'https://insights.zeustechnology.com'
106
+
107
+ function init(gamId = null, options = {}) {
108
+ window.zeusPrime = window.zeusPrime || { cmd: [] }
109
+
110
+ window.zeusPrime.gamId = gamId || options.gamId || window.zeusPrime.gamId || undefined
111
+ window.zeusPrime.api = DEFAULT_API
112
+ window.zeusPrime.hostname = options.hostname || window.location?.hostname || ''
113
+ window.zeusPrime.pathname = options.pathname || window.location?.pathname || ''
114
+ window.zeusPrime.pageUrl = `${window.zeusPrime.hostname}${window.zeusPrime.pathname}`
115
+ window.zeusPrime.pageHash = options.pageHash || null
116
+ window.zeusPrime.debug = window.zeusPrime.debug || options.debug === true || false
117
+ window.zeusPrime.disabled = window.zeusPrime.disabled || options.disabled === true || false
118
+
119
+ loadPrimeQueryParams()
120
+
121
+ logger.showDebug = window.zeusPrime.debug
122
+
123
+ createStatus()
124
+ markStatusComplete('initComplete')
125
+ }
126
+
127
+ function setTargeting() {
128
+ const { gamId, hostname } = window.zeusPrime
129
+
130
+ if (typeof gamId !== 'string') {
131
+ throw new Error(`window.zeusPrime.gamId must be a string. Received: ${String(gamId)}`)
132
+ }
133
+
134
+ addKeyValueToGoogletag(`zeus_${gamId}`, hostname)
135
+ logger.debug(`Setting zeus_${gamId}=${hostname}`)
136
+ markStatusComplete('primeKeyValueSet')
137
+ }
138
+
139
+ function setPrimeAsDisabled() {
140
+ addKeyValueToGoogletag('zeus_prime', 'false')
141
+ logger.debug('Disabling prime; Setting key-value zeus_prime to false')
142
+ }
143
+
144
+ function addKeyValueToGoogletag(key, value) {
145
+ window.googletag = window.googletag || { cmd: [] }
146
+ window.googletag.cmd.push(function () {
147
+ window.googletag.pubads().setTargeting(key, value)
148
+ })
149
+ }
150
+
151
+ function isInsightsPage(pathname = '') {
152
+ const NOT_SECTIONS = [
153
+ {
154
+ test: /\/search/,
155
+ type: 'search',
156
+ },
157
+ {
158
+ test: /\/author/,
159
+ type: 'author',
160
+ },
161
+ {
162
+ test: /\/event/,
163
+ type: 'event',
164
+ },
165
+ {
166
+ test: /\/homepage/,
167
+ type: 'front',
168
+ },
169
+ {
170
+ test: /^\/?$/,
171
+ type: 'front',
172
+ },
173
+ ]
174
+
175
+ const typeObj = NOT_SECTIONS.find((pg) => pathname.match(pg.test))
176
+ return typeObj === undefined
177
+ }
178
+
179
+ async function getUrlHash(canonical) {
180
+ try {
181
+ const buf = await window.crypto.subtle.digest(
182
+ 'SHA-1',
183
+ new TextEncoder('utf-8').encode(canonical)
184
+ )
185
+ const hashed = Array.prototype.map
186
+ .call(new Uint8Array(buf), (x) => `00${x.toString(16)}`.slice(-2))
187
+ .join('')
188
+
189
+ return hashed
190
+ } catch (e) {
191
+ logger.error('Failed to load hash', e.message)
192
+ logger.debug('Exception', e)
193
+ return ''
194
+ }
195
+ }
196
+
197
+ async function sendPrebidRequest(url) {
198
+ return new Promise((resolve, reject) => {
199
+ const ajax = ajaxBuilder()
200
+ ajax(url, {
201
+ success: (responseText, response) => {
202
+ resolve({
203
+ ...response,
204
+ status: response.status,
205
+ json: () => JSON.parse(responseText),
206
+ })
207
+ },
208
+
209
+ error: (responseText, response) => {
210
+ if (!response.status) {
211
+ reject(response)
212
+ }
213
+
214
+ let json = responseText
215
+ if (responseText) {
216
+ try {
217
+ json = JSON.parse(responseText)
218
+ } catch (_) {
219
+ json = null
220
+ }
221
+ }
222
+
223
+ resolve({
224
+ status: response.status,
225
+ json: () => json || null,
226
+ responseValue: json,
227
+ })
228
+ },
229
+ })
230
+ })
231
+ }
232
+
233
+ async function requestTopics() {
234
+ const { api, hostname, pageUrl } = window.zeusPrime
235
+
236
+ if (!window.zeusPrime.pageHash) {
237
+ window.zeusPrime.pageHash = await getUrlHash(pageUrl)
238
+ }
239
+
240
+ const pageHash = window.zeusPrime.pageHash
241
+ const zeusInsightsUrl = `${api}/${hostname}/${pageHash}?article_location=${pageUrl}`
242
+
243
+ logger.debug('Requesting topics', zeusInsightsUrl)
244
+ try {
245
+ markStatusComplete('insightsReqSent')
246
+ const response = await sendPrebidRequest(zeusInsightsUrl)
247
+ if (response.status === 200) {
248
+ logger.debug('topics found')
249
+ markStatusComplete('insightsReqReceived')
250
+ return await response.json()
251
+ } else if (
252
+ response.status === 204 ||
253
+ response.status < 200 ||
254
+ (response.status >= 300 && response.status <= 399)
255
+ ) {
256
+ logger.debug('no topics found')
257
+ markStatusComplete('insightsReqReceived')
258
+ return null
259
+ } else {
260
+ logger.error(`Topics request returned error: ${response.status}`)
261
+ markStatusComplete('insightsReqReceived')
262
+ return null
263
+ }
264
+ } catch (e) {
265
+ logger.error('failed to request topics', e)
266
+ return null
267
+ }
268
+ }
269
+
270
+ function setTopicsTargeting(topics = []) {
271
+ if (topics.length === 0) {
272
+ return
273
+ }
274
+
275
+ window.googletag = window.googletag || { cmd: [] }
276
+ window.googletag.cmd.push(function () {
277
+ window.googletag.pubads().setTargeting('zeus_insights', topics)
278
+ })
279
+
280
+ markStatusComplete('insightsKeyValueSet')
281
+ }
282
+
283
+ async function startTopicsRequest() {
284
+ if (isInsightsPage(window.zeusPrime.pathname)) {
285
+ const response = await requestTopics()
286
+ if (response) {
287
+ setTopicsTargeting(response?.topics)
288
+ }
289
+ } else {
290
+ logger.debug('This page is not eligible for topics, request will be skipped')
291
+ }
292
+ }
293
+
294
+ async function run(gamId, options = {}) {
295
+ logger.showDebug = options.debug || false
296
+
297
+ try {
298
+ init(gamId, options)
299
+ loadCommandQueue()
300
+
301
+ if (window.zeusPrime.disabled) {
302
+ setPrimeAsDisabled()
303
+ } else {
304
+ setTargeting()
305
+ await startTopicsRequest()
306
+ }
307
+ } catch (e) {
308
+ logger.error('Failed to run.', e.message || e)
309
+ } finally {
310
+ markStatusComplete('scriptComplete')
311
+ }
312
+ }
313
+
314
+ /**
315
+ * @preserve
316
+ * Initializes the ZeusPrime RTD Submodule. The config provides the GamID for this
317
+ * site that is used to configure Prime.
318
+ * @param {object} config The Prebid configuration for this module.
319
+ * @param {object} config.params The parameters for this module.
320
+ * @param {string} config.params.gamId The Gam ID (or Network Code) in GAM for this site.
321
+ */
322
+ function initModule(config) {
323
+ const { params } = config || {}
324
+ const { gamId, ...rest } = params || {}
325
+ run(gamId, rest)
326
+ }
327
+
328
+ /**
329
+ * @preserve
330
+ * @type {RtdSubmodule}
331
+ */
332
+ const zeusPrimeSubmodule = {
333
+ /**
334
+ * @preserve
335
+ * The name of the plugin.
336
+ * @type {string}
337
+ */
338
+ name: 'zeusPrime',
339
+
340
+ /**
341
+ * @preserve
342
+ * ZeusPrime use
343
+ */
344
+ init: initModule,
345
+ }
346
+
347
+ /**
348
+ * @preserve
349
+ * Register the Sub Module.
350
+ */
351
+ function registerSubModule() {
352
+ submodule('realTimeData', zeusPrimeSubmodule)
353
+ }
354
+
355
+ registerSubModule()
356
+
357
+ export { zeusPrimeSubmodule }