|
| 1 | +import { deepAccess, generateUUID, isFn, parseSizesInput, parseUrl } from '../../src/utils.js'; |
| 2 | +import { config } from '../../src/config.js'; |
| 3 | +import { find, includes } from '../../src/polyfill.js'; |
| 4 | + |
| 5 | +export const DEFAULT_MIMES = ['video/mp4', 'application/javascript']; |
| 6 | + |
| 7 | +export function isBannerBid(bid) { |
| 8 | + return deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid); |
| 9 | +} |
| 10 | + |
| 11 | +export function isVideoBid(bid) { |
| 12 | + return deepAccess(bid, 'mediaTypes.video'); |
| 13 | +} |
| 14 | + |
| 15 | +export function getBannerBidFloor(bid) { |
| 16 | + let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'banner', size: '*' }) : {}; |
| 17 | + return floorInfo.floor || getBannerBidParam(bid, 'bidfloor'); |
| 18 | +} |
| 19 | + |
| 20 | +export function getVideoBidFloor(bid) { |
| 21 | + let floorInfo = isFn(bid.getFloor) ? bid.getFloor({ currency: 'USD', mediaType: 'video', size: '*' }) : {}; |
| 22 | + return floorInfo.floor || getVideoBidParam(bid, 'bidfloor'); |
| 23 | +} |
| 24 | + |
| 25 | +export function isVideoBidValid(bid) { |
| 26 | + return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement'); |
| 27 | +} |
| 28 | + |
| 29 | +export function isBannerBidValid(bid) { |
| 30 | + return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement'); |
| 31 | +} |
| 32 | + |
| 33 | +export function getVideoBidParam(bid, key) { |
| 34 | + return deepAccess(bid, 'params.video.' + key) || deepAccess(bid, 'params.' + key); |
| 35 | +} |
| 36 | + |
| 37 | +export function getBannerBidParam(bid, key) { |
| 38 | + return deepAccess(bid, 'params.banner.' + key) || deepAccess(bid, 'params.' + key); |
| 39 | +} |
| 40 | + |
| 41 | +export function isMobile() { |
| 42 | + return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); |
| 43 | +} |
| 44 | + |
| 45 | +export function isConnectedTV() { |
| 46 | + return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); |
| 47 | +} |
| 48 | + |
| 49 | +export function getDoNotTrack() { |
| 50 | + return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes'; |
| 51 | +} |
| 52 | + |
| 53 | +export function findAndFillParam(o, key, value) { |
| 54 | + try { |
| 55 | + if (typeof value === 'function') { |
| 56 | + o[key] = value(); |
| 57 | + } else { |
| 58 | + o[key] = value; |
| 59 | + } |
| 60 | + } catch (ex) {} |
| 61 | +} |
| 62 | + |
| 63 | +export function getOsVersion() { |
| 64 | + let clientStrings = [ |
| 65 | + { s: 'Android', r: /Android/ }, |
| 66 | + { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, |
| 67 | + { s: 'Mac OS X', r: /Mac OS X/ }, |
| 68 | + { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, |
| 69 | + { s: 'Linux', r: /(Linux|X11)/ }, |
| 70 | + { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, |
| 71 | + { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, |
| 72 | + { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, |
| 73 | + { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, |
| 74 | + { s: 'Windows Vista', r: /Windows NT 6.0/ }, |
| 75 | + { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, |
| 76 | + { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, |
| 77 | + { s: 'UNIX', r: /UNIX/ }, |
| 78 | + { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ } |
| 79 | + ]; |
| 80 | + let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent)); |
| 81 | + return cs ? cs.s : 'unknown'; |
| 82 | +} |
| 83 | + |
| 84 | +export function getFirstSize(sizes) { |
| 85 | + return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined }; |
| 86 | +} |
| 87 | + |
| 88 | +export function parseSizes(sizes) { |
| 89 | + return parseSizesInput(sizes).map(size => { |
| 90 | + let [ width, height ] = size.split('x'); |
| 91 | + return { |
| 92 | + w: parseInt(width, 10) || undefined, |
| 93 | + h: parseInt(height, 10) || undefined |
| 94 | + }; |
| 95 | + }); |
| 96 | +} |
| 97 | + |
| 98 | +export function getVideoSizes(bid) { |
| 99 | + return parseSizes(deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes); |
| 100 | +} |
| 101 | + |
| 102 | +export function getBannerSizes(bid) { |
| 103 | + return parseSizes(deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes); |
| 104 | +} |
| 105 | + |
| 106 | +export function getTopWindowReferrer(bidderRequest) { |
| 107 | + return bidderRequest?.refererInfo?.ref || ''; |
| 108 | +} |
| 109 | + |
| 110 | +export function getTopWindowLocation(bidderRequest) { |
| 111 | + return parseUrl(bidderRequest?.refererInfo?.page, {decodeSearchAsString: true}); |
| 112 | +} |
| 113 | + |
| 114 | +export function getVideoTargetingParams(bid, VIDEO_TARGETING) { |
| 115 | + const result = {}; |
| 116 | + const excludeProps = ['playerSize', 'context', 'w', 'h']; |
| 117 | + Object.keys(Object(bid.mediaTypes.video)) |
| 118 | + .filter(key => !includes(excludeProps, key)) |
| 119 | + .forEach(key => { |
| 120 | + result[ key ] = bid.mediaTypes.video[ key ]; |
| 121 | + }); |
| 122 | + Object.keys(Object(bid.params.video)) |
| 123 | + .filter(key => includes(VIDEO_TARGETING, key)) |
| 124 | + .forEach(key => { |
| 125 | + result[ key ] = bid.params.video[ key ]; |
| 126 | + }); |
| 127 | + return result; |
| 128 | +} |
| 129 | + |
| 130 | +export function createRequestData(bid, bidderRequest, isVideo, getBidParam, getSizes, getBidFloor, BIDDER_CODE, ADAPTER_VERSION) { |
| 131 | + let topLocation = getTopWindowLocation(bidderRequest); |
| 132 | + let topReferrer = getTopWindowReferrer(bidderRequest); |
| 133 | + let paramSize = getBidParam(bid, 'size'); |
| 134 | + let sizes = []; |
| 135 | + let coppa = config.getConfig('coppa'); |
| 136 | + |
| 137 | + if (typeof paramSize !== 'undefined' && paramSize != '') { |
| 138 | + sizes = parseSizes(paramSize); |
| 139 | + } else { |
| 140 | + sizes = getSizes(bid); |
| 141 | + } |
| 142 | + |
| 143 | + const firstSize = getFirstSize(sizes); |
| 144 | + let floor = getBidFloor(bid) || (isVideo ? 0.5 : 0.1); |
| 145 | + const o = { |
| 146 | + 'device': { |
| 147 | + 'langauge': (global.navigator.language).split('-')[0], |
| 148 | + 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0), |
| 149 | + 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2, |
| 150 | + 'js': 1, |
| 151 | + 'os': getOsVersion() |
| 152 | + }, |
| 153 | + 'at': 2, |
| 154 | + 'site': {}, |
| 155 | + 'tmax': Math.min(3000, bidderRequest.timeout), |
| 156 | + 'cur': ['USD'], |
| 157 | + 'id': bid.bidId, |
| 158 | + 'imp': [], |
| 159 | + 'regs': { |
| 160 | + 'ext': {} |
| 161 | + }, |
| 162 | + 'user': { |
| 163 | + 'ext': {} |
| 164 | + } |
| 165 | + }; |
| 166 | + |
| 167 | + o.site['page'] = topLocation.href; |
| 168 | + o.site['domain'] = topLocation.hostname; |
| 169 | + o.site['search'] = topLocation.search; |
| 170 | + o.site['ref'] = topReferrer; |
| 171 | + o.site['mobile'] = isMobile() ? 1 : 0; |
| 172 | + const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0; |
| 173 | + o.device['dnt'] = getDoNotTrack() ? 1 : 0; |
| 174 | + |
| 175 | + findAndFillParam(o.site, 'name', function() { |
| 176 | + return global.top.document.title; |
| 177 | + }); |
| 178 | + |
| 179 | + findAndFillParam(o.device, 'h', function() { |
| 180 | + return global.screen.height; |
| 181 | + }); |
| 182 | + findAndFillParam(o.device, 'w', function() { |
| 183 | + return global.screen.width; |
| 184 | + }); |
| 185 | + |
| 186 | + let placement = getBidParam(bid, 'placement'); |
| 187 | + let impType = isVideo ? { |
| 188 | + 'video': Object.assign({ |
| 189 | + 'id': generateUUID(), |
| 190 | + 'pos': 0, |
| 191 | + 'w': firstSize.w, |
| 192 | + 'h': firstSize.h, |
| 193 | + 'mimes': DEFAULT_MIMES |
| 194 | + }, getVideoTargetingParams(bid)) |
| 195 | + } : { |
| 196 | + 'banner': { |
| 197 | + 'id': generateUUID(), |
| 198 | + 'pos': 0, |
| 199 | + 'w': firstSize.w, |
| 200 | + 'h': firstSize.h |
| 201 | + } |
| 202 | + }; |
| 203 | + |
| 204 | + for (let j = 0; j < sizes.length; j++) { |
| 205 | + o.imp.push({ |
| 206 | + 'id': '' + j, |
| 207 | + 'displaymanager': '' + BIDDER_CODE, |
| 208 | + 'displaymanagerver': '' + ADAPTER_VERSION, |
| 209 | + 'tagId': placement, |
| 210 | + 'bidfloor': floor, |
| 211 | + 'bidfloorcur': 'USD', |
| 212 | + 'secure': secure, |
| 213 | + ...impType |
| 214 | + }); |
| 215 | + } |
| 216 | + |
| 217 | + if (coppa) { |
| 218 | + o.regs.ext = {'coppa': 1}; |
| 219 | + } |
| 220 | + |
| 221 | + if (bidderRequest && bidderRequest.gdprConsent) { |
| 222 | + let { gdprApplies, consentString } = bidderRequest.gdprConsent; |
| 223 | + o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; |
| 224 | + o.user.ext = {'consent': consentString}; |
| 225 | + } |
| 226 | + |
| 227 | + return o; |
| 228 | +} |
0 commit comments