• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prebid / Prebid.js / 19176070562

07 Nov 2025 05:26PM UTC coverage: 96.231% (+0.003%) from 96.228%
19176070562

push

github

web-flow
Adagio Bid Adapter: enable gzip compression (#14110)

* AdagioBidAdapter: add endpoint "orgid" query param

* AdagioBidAdapter: enable gzip compression

52862 of 64751 branches covered (81.64%)

9 of 9 new or added lines in 1 file covered. (100.0%)

11 existing lines in 7 files now uncovered.

202066 of 209980 relevant lines covered (96.23%)

124.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.41
/modules/rtdModule/index.ts
1
import {config} from '../../src/config.js';
4✔
2
import {getHook, module} from '../../src/hook.js';
3
import {logError, logInfo, logWarn, mergeDeep} from '../../src/utils.js';
4
import * as events from '../../src/events.js';
5
import { EVENTS, JSON_MAPPING } from '../../src/constants.js';
6
import adapterManager, {gdprDataHandler, uspDataHandler, gppDataHandler} from '../../src/adapterManager.js';
7
import {timedAuctionHook} from '../../src/utils/perfMetrics.js';
8
import {GDPR_GVLIDS} from '../../src/consentHandler.js';
9
import {MODULE_TYPE_RTD} from '../../src/activities/modules.js';
10
import {guardOrtb2Fragments} from '../../libraries/objectGuard/ortbGuard.js';
11
import {activityParamsBuilder} from '../../src/activities/params.js';
12
import type {StartAuctionOptions} from "../../src/prebid.ts";
13
import type {ProviderConfig, RTDProvider, RTDProviderConfig} from "./spec.ts";
14

15
const activityParams = activityParamsBuilder((al) => adapterManager.resolveAlias(al));
4✔
16

17
/** @type {string} */
18
const MODULE_NAME = 'realTimeData';
4✔
19
const registeredSubModules = [];
4✔
20
export let subModules = [];
4✔
21
let _moduleConfig: RealTimeDataConfig;
22
let _dataProviders = [];
4✔
23
let _userConsent;
24

25
/**
26
 * Register a Real-Time Data (RTD) submodule.
27
 *
28
 * @param {Object} submodule The RTD submodule to register.
29
 * @param {string} submodule.name The name of the RTD submodule.
30
 * @param {number} [submodule.gvlid] The Global Vendor List ID (GVLID) of the RTD submodule.
31
 * @returns {function(): void} A de-registration function that will unregister the module when called.
32
 */
33
export function attachRealTimeDataProvider(submodule) {
34
  registeredSubModules.push(submodule);
117✔
35
  GDPR_GVLIDS.register(MODULE_TYPE_RTD, submodule.name, submodule.gvlid)
117✔
36
  return function detach() {
117✔
37
    const idx = registeredSubModules.indexOf(submodule)
61✔
38
    if (idx >= 0) {
61✔
39
      registeredSubModules.splice(idx, 1);
55✔
40
      initSubModules();
55✔
41
    }
42
  }
43
}
44

45
/**
46
 * call each sub module event function by config order
47
 */
48
const setEventsListeners = (function () {
4✔
49
  let registered = false;
4✔
50
  return function setEventsListeners() {
4✔
51
    if (!registered) {
19✔
52
      Object.entries({
1✔
53
        [EVENTS.AUCTION_INIT]: ['onAuctionInitEvent'],
54
        [EVENTS.AUCTION_END]: ['onAuctionEndEvent', getAdUnitTargeting],
55
        [EVENTS.BID_RESPONSE]: ['onBidResponseEvent'],
56
        [EVENTS.BID_REQUESTED]: ['onBidRequestEvent'],
57
        [EVENTS.BID_ACCEPTED]: ['onBidAcceptedEvent']
58
      }).forEach(([ev, [handler, preprocess]]) => {
5✔
59
        events.on(ev as any, (args) => {
5✔
60
          preprocess && (preprocess as any)(args);
9✔
61
          subModules.forEach(sm => {
9✔
62
            try {
18✔
63
              sm[handler as string] && sm[handler as string](args, sm.config, _userConsent)
18✔
64
            } catch (e) {
65
              logError(`RTD provider '${sm.name}': error in '${handler}':`, e);
4✔
66
            }
67
          });
68
        })
69
      });
70
      registered = true;
1✔
71
    }
72
  }
73
})();
74

75
type RealTimeDataConfig = {
76
  dataProviders: (RTDProviderConfig<keyof ProviderConfig> | RTDProviderConfig<RTDProvider>)[];
77
  /**
78
   * Maximum amount of time (in milliseconds) to delay auctions while waiting for RTD providers.
79
   */
80
  auctionDelay?: number;
81
}
82

83
declare module '../../src/config' {
84
  interface Config {
85
    [MODULE_NAME]?: RealTimeDataConfig;
86
  }
87
}
88

89
export function init(config) {
90
  const confListener = config.getConfig(MODULE_NAME, ({realTimeData}) => {
23✔
91
    if (!realTimeData.dataProviders) {
19!
92
      logError('missing parameters for real time module');
×
93
      return;
×
94
    }
95
    confListener(); // unsubscribe config listener
19✔
96
    _moduleConfig = realTimeData;
19✔
97
    _dataProviders = realTimeData.dataProviders;
19✔
98
    setEventsListeners();
19✔
99
    getHook('startAuction').before(setBidRequestsData, 20); // RTD should run before FPD
19✔
100
    adapterManager.callDataDeletionRequest.before(onDataDeletionRequest);
19✔
101
    initSubModules();
19✔
102
  });
103
}
104

105
function getConsentData() {
106
  return {
77✔
107
    gdpr: gdprDataHandler.getConsentData(),
108
    usp: uspDataHandler.getConsentData(),
109
    gpp: gppDataHandler.getConsentData(),
110
    coppa: !!(config.getConfig('coppa'))
111
  }
112
}
113

114
/**
115
 * call each sub module init function by config order
116
 * if no init function / init return failure / module not configured - remove it from submodules list
117
 */
118
function initSubModules() {
119
  _userConsent = getConsentData();
74✔
120
  const subModulesByOrder = [];
74✔
121
  _dataProviders.forEach(provider => {
74✔
122
    const sm = ((registeredSubModules) || []).find(s => s.name === provider.name);
4,955!
123
    const initResponse = sm && sm.init && sm.init(provider, _userConsent);
220✔
124
    if (initResponse) {
220✔
125
      subModulesByOrder.push(Object.assign(sm, {config: provider}));
74✔
126
    }
127
  });
128
  subModules = subModulesByOrder;
74✔
129
  logInfo(`Real time data module enabled, using submodules: ${subModules.map((m) => m.name).join(', ')}`);
74✔
130
}
131

132
/**
133
 * loop through configured data providers If the data provider has registered getBidRequestData,
134
 * call it, providing reqBidsConfigObj, consent data and module params
135
 * this allows submodules to modify bidders
136
 * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
137
 * @param {function} fn required; The next function in the chain, used by hook.ts
138
 */
139
export const setBidRequestsData = timedAuctionHook('rtd', function setBidRequestsData(fn, reqBidsConfigObj: StartAuctionOptions) {
4✔
140
  _userConsent = getConsentData();
3✔
141

142
  const relevantSubModules = [];
3✔
143
  const prioritySubModules = [];
3✔
144
  subModules.forEach(sm => {
3✔
145
    if (typeof sm.getBidRequestData !== 'function') {
6!
146
      return;
×
147
    }
148
    relevantSubModules.push(sm);
6✔
149
    const config = sm.config;
6✔
150
    if (config && config.waitForIt) {
6✔
151
      prioritySubModules.push(sm);
3✔
152
    }
153
  });
154

155
  const shouldDelayAuction = prioritySubModules.length && _moduleConfig?.auctionDelay > 0;
3!
156
  let callbacksExpected = prioritySubModules.length;
3✔
157
  let isDone = false;
3✔
158
  let waitTimeout;
159

160
  if (!relevantSubModules.length) {
3!
UNCOV
161
    return exitHook();
×
162
  }
163

164
  const timeout = shouldDelayAuction ? _moduleConfig.auctionDelay : 0;
3!
165
  waitTimeout = setTimeout(exitHook, timeout);
3✔
166

167
  relevantSubModules.forEach(sm => {
3✔
168
    const fpdGuard = guardOrtb2Fragments(reqBidsConfigObj.ortb2Fragments || {}, activityParams(MODULE_TYPE_RTD, sm.name));
6✔
169
    sm.getBidRequestData({...reqBidsConfigObj, ortb2Fragments: fpdGuard}, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent, timeout);
6✔
170
  });
171

172
  function onGetBidRequestDataCallback() {
173
    if (isDone) {
4✔
174
      return;
1✔
175
    }
176
    if (this.config && this.config.waitForIt) {
3✔
177
      callbacksExpected--;
2✔
178
    }
179
    if (callbacksExpected === 0) {
3✔
180
      setTimeout(exitHook, 0);
3✔
181
    }
182
  }
183

184
  function exitHook() {
185
    if (isDone) {
4✔
186
      return;
1✔
187
    }
188
    isDone = true;
3✔
189
    clearTimeout(waitTimeout);
3✔
190
    fn.call(this, reqBidsConfigObj);
3✔
191
  }
192
});
193

194
/**
195
 * loop through configured data providers If the data provider has registered getTargetingData,
196
 * call it, providing ad unit codes, consent data and module params
197
 * the sub mlodle will return data to set on the ad unit
198
 * this function used to place key values on primary ad server per ad unit
199
 * @param {Object} auction object received on auction end event
200
 */
201
export function getAdUnitTargeting(auction) {
202
  const relevantSubModules = subModules.filter(sm => typeof sm.getTargetingData === 'function');
10✔
203
  if (!relevantSubModules.length) {
5✔
204
    return;
2✔
205
  }
206

207
  // get data
208
  const adUnitCodes = auction.adUnitCodes;
3✔
209
  if (!adUnitCodes) {
3!
UNCOV
210
    return;
×
211
  }
212
  const targeting = [];
3✔
213
  for (let i = relevantSubModules.length - 1; i >= 0; i--) {
3✔
214
    const smTargeting = relevantSubModules[i].getTargetingData(adUnitCodes, relevantSubModules[i].config, _userConsent, auction);
6✔
215
    if (smTargeting && typeof smTargeting === 'object') {
6✔
216
      targeting.push(smTargeting);
4✔
217
    } else {
218
      logWarn('invalid getTargetingData response for sub module', relevantSubModules[i].name);
2✔
219
    }
220
  }
221
  // place data on auction adUnits
222
  const mergedTargeting = mergeDeep({}, ...targeting);
3✔
223
  auction.adUnits.forEach(adUnit => {
3✔
224
    const kv = adUnit.code && mergedTargeting[adUnit.code];
5✔
225
    if (!kv) {
5✔
226
      return
1✔
227
    }
228
    logInfo('RTD set ad unit targeting of', kv, 'for', adUnit);
4✔
229
    adUnit[JSON_MAPPING.ADSERVER_TARGETING] = Object.assign(adUnit[JSON_MAPPING.ADSERVER_TARGETING] || {}, kv);
4✔
230
  });
231
  return auction.adUnits;
3✔
232
}
233

234
export function onDataDeletionRequest(next, ...args) {
6✔
235
  subModules.forEach((sm) => {
3✔
236
    if (typeof sm.onDataDeletionRequest === 'function') {
6✔
237
      try {
5✔
238
        sm.onDataDeletionRequest(sm.config);
5✔
239
      } catch (e) {
240
        logError(`Error executing ${sm.name}.onDataDeletionRequest`, e)
1✔
241
      }
242
    }
243
  });
3✔
244
  next.apply(this, args);
3✔
245
}
246

247
module('realTimeData', attachRealTimeDataProvider);
4✔
248
init(config);
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc