diff --git a/modules/magniteBidAdapter.js b/modules/magniteBidAdapter.ts similarity index 78% rename from modules/magniteBidAdapter.js rename to modules/magniteBidAdapter.ts index 9f300f3b3a..c220096d4f 100644 --- a/modules/magniteBidAdapter.js +++ b/modules/magniteBidAdapter.ts @@ -1,6 +1,13 @@ import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { + type AdapterRequest, + type BidderSpec, + type ServerResponse, + registerBidder +} from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { type SyncType } from '../src/userSync.js'; +import { type BidRequest, type ClientBidderRequest } from '../src/adapterManager.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js'; import { convertTypes } from '../libraries/transformParamsUtils/convertTypes.js'; @@ -20,7 +27,16 @@ export const REQUEST_URL = 'https://fastlane.rubiconproject.com/a/api/prebid-exc export const SYNC_URL = 'https://eus.rubiconproject.com/usync.html'; const DEFAULT_INTEGRATION = 'pbjs'; -let mgniConf = {}; +type MgniConfig = { + int_type?: string; + rendererUrl?: string; + rendererConfig?: Record; + impLimit?: number; + bidEndpoint?: string; + syncEndpoint?: string; +}; + +let mgniConf: MgniConfig = {}; // For transition period we need to listen to both rubicon and magnite configs ['magnite', 'rubicon'].forEach(confName => { @@ -36,7 +52,19 @@ export function resetMgniConf() { mgniConf = {}; } -export const spec = { +type GetUserSyncsArgs = Parameters['getUserSyncs']>>; + +type LegacyGetUserSyncs = (...args: GetUserSyncsArgs) => { + type: SyncType; + url: string; +} | void; + +type MagniteSpec = Omit, 'getUserSyncs'> & { + getUserSyncs: LegacyGetUserSyncs; + transformBidParams: (params: Record) => Record; +}; + +export const spec: MagniteSpec = { code: 'magnite', gvlid: GVL_ID, supportedMediaTypes: [BANNER, NATIVE, VIDEO], @@ -47,13 +75,13 @@ export const spec = { transformBidParams }; -registerBidder(spec); +registerBidder(spec as unknown as BidderSpec<'magnite'>); /** * Lets Prebid-Core know if the bid is valid before sending it to the adapter * @param {object} bid */ -function isBidRequestValid(bid) { +function isBidRequestValid(bid: any) { return ['accountId', 'siteId', 'zoneId'].every(param => !Number.isNaN(Number.parseInt(bid?.params?.[param]))); } @@ -62,14 +90,14 @@ const posMap = { btf: 3 }; -export function masSizeOrdering(sizes) { +export function masSizeOrdering(sizes: Array<{ w: number; h: number }>) { const MAS_SIZE_PRIORITY = [ { w: 300, h: 250 }, { w: 728, h: 90 }, { w: 160, h: 600 } ]; - const compareSizes = (left, right) => left.w === right.w && left.h === right.h; + const compareSizes = (left: { w: number; h: number }, right: { w: number; h: number }) => left.w === right.w && left.h === right.h; return sizes.sort((first, second) => { // sort by MAS_SIZE_PRIORITY priority order @@ -88,7 +116,7 @@ export function masSizeOrdering(sizes) { }); } -function getPpuidFromEids(eids) { +function getPpuidFromEids(eids: any[]) { for (const eid of eids) { const ppId = eid.uids.find(uid => uid?.ext?.stype === 'ppuid' && uid?.id); if (ppId) { @@ -97,7 +125,7 @@ function getPpuidFromEids(eids) { } } -function getPpuid(req) { +function getPpuid(req: { user?: { id?: string; ext?: { eids?: any[] } } }) { const user = req.user; if (user?.id) { return user.id; @@ -112,7 +140,7 @@ function getPpuid(req) { return getPpuidFromEids(eids); } -function cleanFpd(fpdObj) { +function cleanFpd(fpdObj: Record) { // DV+ wants first party data as object of keys / val where val is array Object.entries(fpdObj || {}).forEach(([key, val]) => { // if not array, wrap in array @@ -129,9 +157,9 @@ const converter = ortbConverter({ currency: 'USD' }, processors: pbsExtensions, - imp(buildImp, bidRequest, context) { + imp(buildImp: any, bidRequest: any, context: any) { // Building imps of request - const imp = buildImp(bidRequest, context); + const imp: any = buildImp(bidRequest, context); // remove any mediaTypes on imp that are not in our context [BANNER, NATIVE, VIDEO].forEach(mediaType => { @@ -173,7 +201,7 @@ const converter = ortbConverter({ return imp; }, request(buildRequest, imps, bidderRequest, context) { - const req = buildRequest(imps, bidderRequest, context); + const req: any = buildRequest(imps, bidderRequest, context); // Do not send in tmax delete req.tmax; @@ -208,14 +236,14 @@ const converter = ortbConverter({ return req; }, - bidResponse(buildBidResponse, bid, context) { + bidResponse(buildBidResponse: any, bid: any, context: any) { // Move adm_native to adm for native responses so the ortbConverter can process it if (context.mediaType === NATIVE && bid.adm_native) { bid.adm = bid.adm_native; delete bid.adm_native; } - const bidResponse = buildBidResponse(bid, context); + const bidResponse: any = buildBidResponse(bid, context); bidResponse.bidderCode = context.bidRequest.bidder; @@ -248,9 +276,9 @@ const converter = ortbConverter({ }, overrides: { imp: { - bidfloor(setBidFloor, imp, bidRequest, context) { + bidfloor(setBidFloor: any, imp: any, bidRequest: any, context: any) { // Floors should always be in USD - const floor = {}; + const floor: any = {}; setBidFloor(floor, bidRequest, { ...context, currency: 'USD' }); if (floor.bidfloorcur === 'USD') { Object.assign(imp, floor); @@ -260,7 +288,7 @@ const converter = ortbConverter({ } }); -function transformBidParams(params) { +function transformBidParams(params: Record) { return convertTypes({ 'accountId': 'number', 'siteId': 'number', @@ -268,7 +296,7 @@ function transformBidParams(params) { }, params); } -function shouldAddBid(bid, mediaType) { +function shouldAddBid(bid: any, mediaType: string) { const enabledTypes = bid.params?.enabledMediaTypes; return !Array.isArray(enabledTypes) || enabledTypes.includes(mediaType); } @@ -281,8 +309,8 @@ function shouldAddBid(bid, mediaType) { * @param bidderRequest * @returns Array of HTTP Request Objects */ -function buildRequests(bids, bidderRequest) { - const bidsMap = {}; +function buildRequests(bids: BidRequest<'magnite'>[], bidderRequest: ClientBidderRequest<'magnite'>): AdapterRequest[] { + const bidsMap: Record = {}; // Loop through all bids and group them by accountId, siteId, and mediaType for (const bid of bids) { @@ -316,35 +344,38 @@ function buildRequests(bids, bidderRequest) { return requests; } -function createRequest(bidRequests, bidderRequest, acctSite, mediaType) { +function createRequest( + bidRequests: BidRequest<'magnite'>[], + bidderRequest: ClientBidderRequest<'magnite'>, + acctSite: string, + mediaType: string, +): AdapterRequest { return { method: 'POST', url: `${(mgniConf.bidEndpoint || REQUEST_URL)}?as=${acctSite}&m=${mediaType}&s=${bidRequests.length}`, - data: converter.toORTB({ bidRequests, bidderRequest, context: { mediaType } }) + data: converter.toORTB({ bidRequests, bidderRequest, context: { mediaType: mediaType as any } }) } } -function interpretResponse(resp, req) { +function interpretResponse(resp: ServerResponse, req: AdapterRequest) { if (!resp.body) { resp.body = { nbr: 0 }; } - return converter.fromORTB({ request: req.data, response: resp.body })?.bids; + return (converter.fromORTB({ request: req.data, response: resp.body }) as any)?.bids; } /** - * @param syncOptions - * @param responses - * @param gdprConsent - * @param uspConsent - * @param gppConsent + * @param args * @return {{type: (string), url: (*|string)}[]} */ -function getUserSyncs(syncOptions, responses, gdprConsent, uspConsent, gppConsent) { +function getUserSyncs(...args: GetUserSyncsArgs): ReturnType { + const [syncOptions, responses, gdprConsent, uspConsent, gppConsent] = args; + void responses; if (!syncOptions.iframeEnabled) { return; } - const params = {}; + const params: Record = {}; if (gdprConsent && typeof gdprConsent.gdprApplies === 'boolean') { params['gdpr'] = Number(gdprConsent.gdprApplies); diff --git a/test/spec/modules/magniteBidAdapter_spec.js b/test/spec/modules/magniteBidAdapter_spec.js index fb9c2f46c1..d7c789978e 100644 --- a/test/spec/modules/magniteBidAdapter_spec.js +++ b/test/spec/modules/magniteBidAdapter_spec.js @@ -5,7 +5,7 @@ import { SYNC_URL, masSizeOrdering, resetMgniConf -} from 'modules/magniteBidAdapter.js'; +} from 'modules/magniteBidAdapter.ts'; import {newBidder} from 'src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from 'src/mediaTypes.js'; import {config} from 'src/config.js';