Skip to content

Commit

Permalink
Core & multiple modules: replace deepAccess with optional chaining (#…
Browse files Browse the repository at this point in the history
…12544)

* Replace `deepAccess` with optional chaining

Closes #12543

* Revert changes containing variable lookups that may dynamically contain "."

* Use optional chaining

Adding these changes back after review discovered the missing optional chain which was causing test failure in a previous commit.

* revert bidderSettings & add test case

---------

Co-authored-by: Demetrio Girardi <[email protected]>
  • Loading branch information
gwhigs and dgirardi authored Dec 6, 2024
1 parent 272d67c commit f9327ff
Show file tree
Hide file tree
Showing 20 changed files with 86 additions and 98 deletions.
2 changes: 1 addition & 1 deletion libraries/appnexusUtils/anKeywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export function getANMapFromOrtbSegments(ortb2) {
let ortbSegsArrObj = deepAccess(ortb2, path) || [];
ortbSegsArrObj.forEach(segObj => {
// only read segment data from known sources
const segtax = ORTB_SEGTAX_KEY_MAP[deepAccess(segObj, 'ext.segtax')];
const segtax = ORTB_SEGTAX_KEY_MAP[segObj?.ext?.segtax];
if (segtax) {
segObj.segment.forEach(seg => {
// if source was in multiple locations of ortb or had multiple segments in same area, stack them together into an array
Expand Down
4 changes: 1 addition & 3 deletions libraries/fpdUtils/pageInfo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as utils from '../../src/utils.js';

/**
* get page title
* @returns {string}
Expand Down Expand Up @@ -67,7 +65,7 @@ export function getReferrer(bidRequest = {}, bidderRequest = {}) {
if (bidRequest.params && bidRequest.params.referrer) {
pageUrl = bidRequest.params.referrer;
} else {
pageUrl = utils.deepAccess(bidderRequest, 'refererInfo.page');
pageUrl = bidderRequest?.refererInfo?.page;
}
return pageUrl;
}
3 changes: 1 addition & 2 deletions libraries/ortbConverter/processors/banner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
createTrackPixelHtml,
deepAccess,
inIframe,
mergeDeep,
sizesToSizeTuples,
Expand All @@ -15,7 +14,7 @@ import {BANNER} from '../../../src/mediaTypes.js';
export function fillBannerImp(imp, bidRequest, context) {
if (context.mediaType && context.mediaType !== BANNER) return;

const bannerParams = deepAccess(bidRequest, 'mediaTypes.banner');
const bannerParams = bidRequest?.mediaTypes?.banner;
if (bannerParams) {
const banner = {
topframe: inIframe() === true ? 0 : 1
Expand Down
6 changes: 3 additions & 3 deletions libraries/ortbConverter/processors/video.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {deepAccess, isEmpty, logWarn, mergeDeep, sizesToSizeTuples, sizeTupleToRtbSize} from '../../../src/utils.js';
import {isEmpty, logWarn, mergeDeep, sizesToSizeTuples, sizeTupleToRtbSize} from '../../../src/utils.js';
import {VIDEO} from '../../../src/mediaTypes.js';

import {ORTB_VIDEO_PARAMS} from '../../../src/video.js';

export function fillVideoImp(imp, bidRequest, context) {
if (context.mediaType && context.mediaType !== VIDEO) return;

const videoParams = deepAccess(bidRequest, 'mediaTypes.video');
const videoParams = bidRequest?.mediaTypes?.video;
if (!isEmpty(videoParams)) {
const video = Object.fromEntries(
// Parameters that share the same name & semantics between pbjs adUnits and imp.video
Expand All @@ -27,7 +27,7 @@ export function fillVideoImp(imp, bidRequest, context) {

export function fillVideoResponse(bidResponse, seatbid, context) {
if (bidResponse.mediaType === VIDEO) {
if (deepAccess(context.imp, 'video.w') && deepAccess(context.imp, 'video.h')) {
if (context?.imp?.video?.w && context?.imp?.video?.h) {
[bidResponse.playerWidth, bidResponse.playerHeight] = [context.imp.video.w, context.imp.video.h];
}

Expand Down
34 changes: 17 additions & 17 deletions modules/criteoBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {deepAccess, deepSetValue, isArray, logError, logWarn, parseUrl, triggerPixel} from '../src/utils.js';
import {deepSetValue, isArray, logError, logWarn, parseUrl, triggerPixel} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import {getStorageManager} from '../src/storageManager.js';
Expand Down Expand Up @@ -92,7 +92,7 @@ function imp(buildImp, bidRequest, context) {
}
deepSetValue(imp, 'video.ext', {
context: bidRequest.mediaTypes.video.context,
playersizes: parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize'), parseSize),
playersizes: parseSizes(bidRequest?.mediaTypes?.video?.playerSize, parseSize),
plcmt: bidRequest.mediaTypes.video.plcmt,
poddur: bidRequest.mediaTypes.video.adPodDurationSec,
rqddurs: bidRequest.mediaTypes.video.durationRangeSec,
Expand Down Expand Up @@ -156,7 +156,7 @@ function request(buildRequest, imps, bidderRequest, context) {
* @returns {*}
*/
function bidResponse(buildBidResponse, bid, context) {
context.mediaType = deepAccess(bid, 'ext.mediatype');
context.mediaType = bid?.ext?.mediatype;
if (context.mediaType === NATIVE && typeof bid.adm_native !== 'undefined') {
bid.adm = bid.adm_native;
delete bid.adm_native;
Expand All @@ -165,22 +165,22 @@ function bidResponse(buildBidResponse, bid, context) {
let bidResponse = buildBidResponse(bid, context);
const {bidRequest} = context;

bidResponse.currency = deepAccess(bid, 'ext.cur')
bidResponse.currency = bid?.ext?.cur;

if (typeof deepAccess(bid, 'ext.meta') !== 'undefined') {
if (typeof bid?.ext?.meta !== 'undefined') {
deepSetValue(bidResponse, 'meta', {
...bidResponse.meta,
...bid.ext.meta
});
}
if (typeof deepAccess(bid, 'ext.paf.content_id') !== 'undefined') {
if (typeof bid?.ext?.paf?.content_id !== 'undefined') {
deepSetValue(bidResponse, 'meta.paf.content_id', bid.ext.paf.content_id)
}

if (bidResponse.mediaType === VIDEO) {
bidResponse.vastUrl = bid.ext?.displayurl;
// if outstream video, add a default render for it.
if (deepAccess(bidRequest, 'mediaTypes.video.context') === OUTSTREAM) {
if (bidRequest?.mediaTypes?.video?.context === OUTSTREAM) {
bidResponse.renderer = createOutstreamVideoRenderer(bid);
}
}
Expand All @@ -200,9 +200,9 @@ function bidResponse(buildBidResponse, bid, context) {
function response(buildResponse, bidResponses, ortbResponse, context) {
let response = buildResponse(bidResponses, ortbResponse, context);

const pafTransmission = deepAccess(ortbResponse, 'ext.paf.transmission');
const pafTransmission = ortbResponse?.ext?.paf?.transmission;
response.bids.forEach(bid => {
if (typeof pafTransmission !== 'undefined' && typeof deepAccess(bid, 'meta.paf.content_id') !== 'undefined') {
if (typeof pafTransmission !== 'undefined' && typeof bid?.meta?.paf?.content_id !== 'undefined') {
deepSetValue(bid, 'meta.paf.transmission', pafTransmission);
} else {
delete bid.meta.paf;
Expand Down Expand Up @@ -362,7 +362,7 @@ export const spec = {
// We support native request without assets requirements because we can fill them later on.
// This is a trick to fool oRTB converter isOpenRTBBidRequestValid(ortb) fn because it needs
// nativeOrtbRequest.assets to be non-empty.
if (deepAccess(bidRequest, 'nativeOrtbRequest.assets') == null) {
if (bidRequest?.nativeOrtbRequest?.assets == null) {
logWarn(LOG_PREFIX + 'native asset requirements are missing');
deepSetValue(bidRequest, 'nativeOrtbRequest.assets', [{}]);
}
Expand Down Expand Up @@ -391,7 +391,7 @@ export const spec = {
const interpretedResponse = CONVERTER.fromORTB({response: response.body, request: request.data});
const bids = interpretedResponse.bids || [];

const fledgeAuctionConfigs = deepAccess(response.body, 'ext.igi')?.filter(igi => isArray(igi?.igs))
const fledgeAuctionConfigs = response.body?.ext?.igi?.filter(igi => isArray(igi?.igs))
.flatMap(igi => igi.igs);
if (fledgeAuctionConfigs?.length) {
return {
Expand Down Expand Up @@ -548,11 +548,11 @@ function parseSize(size) {
}

function hasVideoMediaType(bidRequest) {
return deepAccess(bidRequest, 'mediaTypes.video') !== undefined;
return bidRequest?.mediaTypes?.video !== undefined;
}

function hasNativeMediaType(bidRequest) {
return deepAccess(bidRequest, 'mediaTypes.native') !== undefined;
return bidRequest?.mediaTypes?.native !== undefined;
}

function hasValidVideoMediaType(bidRequest) {
Expand All @@ -562,12 +562,12 @@ function hasValidVideoMediaType(bidRequest) {

requiredMediaTypesParams.forEach(function (param) {
if (param === 'placement') {
if (deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined && deepAccess(bidRequest, 'params.video.' + param) === undefined && deepAccess(bidRequest, 'mediaTypes.video.plcmt') === undefined && deepAccess(bidRequest, 'params.video.plcmt') === undefined) {
if (bidRequest?.mediaTypes?.video?.[param] === undefined && bidRequest?.params?.video?.[param] === undefined && bidRequest?.mediaTypes?.video?.plcmt === undefined && bidRequest?.params?.video?.plcmt === undefined) {
isValid = false;
logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' or mediaTypes.video.plcmt is required');
}
} else {
if (deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined && deepAccess(bidRequest, 'params.video.' + param) === undefined) {
if (bidRequest?.mediaTypes?.video?.[param] === undefined && bidRequest?.params?.video?.[param] === undefined) {
isValid = false;
logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required');
}
Expand Down Expand Up @@ -604,13 +604,13 @@ function getFloors(bidRequest) {
if (getFloor) {
if (bidRequest.mediaTypes?.banner) {
floors.banner = {};
const bannerSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes'))
const bannerSizes = parseSizes(bidRequest?.mediaTypes?.banner?.sizes)
bannerSizes.forEach(bannerSize => floors.banner[parseSize(bannerSize).toString()] = getFloor.call(bidRequest, { size: bannerSize, mediaType: BANNER }));
}

if (bidRequest.mediaTypes?.video) {
floors.video = {};
const videoSizes = parseSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize'))
const videoSizes = parseSizes(bidRequest?.mediaTypes?.video?.playerSize)
videoSizes.forEach(videoSize => floors.video[parseSize(videoSize).toString()] = getFloor.call(bidRequest, { size: videoSize, mediaType: VIDEO }));
}

Expand Down
7 changes: 3 additions & 4 deletions modules/dfpAdServerVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { getRefererInfo } from '../src/refererDetection.js';
import { targeting } from '../src/targeting.js';
import {
buildUrl,
deepAccess,
formatQS,
isEmpty,
isNumber,
Expand Down Expand Up @@ -90,7 +89,7 @@ export function buildDfpVideoUrl(options) {

const derivedParams = {
correlator: Date.now(),
sz: parseSizesInput(deepAccess(adUnit, 'mediaTypes.video.playerSize')).join('|'),
sz: parseSizesInput(adUnit?.mediaTypes?.video?.playerSize).join('|'),
url: encodeURIComponent(location.href),
};

Expand Down Expand Up @@ -208,7 +207,7 @@ function buildUrlFromAdserverUrlComponents(components, bid, options) {
* @return {string | undefined} The encoded vast url if it exists, or undefined
*/
function getDescriptionUrl(bid, components, prop) {
return deepAccess(components, `${prop}.description_url`) || encodeURIComponent(dep.ri().page);
return components?.[prop]?.description_url || encodeURIComponent(dep.ri().page);
}

/**
Expand Down Expand Up @@ -240,7 +239,7 @@ function getCustParams(bid, options, urlCustParams) {
events.emit(EVENTS.SET_TARGETING, {[adUnit.code]: prebidTargetingSet});

// merge the prebid + publisher targeting sets
const publisherTargetingSet = deepAccess(options, 'params.cust_params');
const publisherTargetingSet = options?.params?.cust_params;
const targetingSet = Object.assign({}, prebidTargetingSet, publisherTargetingSet);
let encodedParams = encodeURIComponent(formatQS(targetingSet));
if (urlCustParams) {
Expand Down
5 changes: 2 additions & 3 deletions modules/prebidServerBidAdapter/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Adapter from '../../src/adapter.js';
import {
deepAccess,
deepClone,
flatten,
generateUUID,
Expand Down Expand Up @@ -450,7 +449,7 @@ export function PrebidServer() {

/* Prebid executes this function when the page asks to send out bid requests */
baseAdapter.callBids = function(s2sBidRequest, bidRequests, addBidResponse, done, ajax) {
const adapterMetrics = s2sBidRequest.metrics = useMetrics(deepAccess(bidRequests, '0.metrics'))
const adapterMetrics = s2sBidRequest.metrics = useMetrics(bidRequests?.[0]?.metrics)
.newMetrics()
.renameWith((n) => [`adapter.s2s.${n}`, `adapters.s2s.${s2sBidRequest.s2sConfig.defaultVendor}.${n}`])
done = adapterMetrics.startTiming('total').stopBefore(done);
Expand Down Expand Up @@ -568,7 +567,7 @@ export const processPBSRequest = hook('sync', function (s2sBidRequest, bidReques
const requestJson = request && JSON.stringify(request);
logInfo('BidRequest: ' + requestJson);
const endpointUrl = getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent);
const customHeaders = deepAccess(s2sBidRequest, 's2sConfig.customHeaders', {});
const customHeaders = s2sBidRequest?.s2sConfig?.customHeaders ?? {};
if (request && requestJson && endpointUrl) {
const networkDone = s2sBidRequest.metrics.startTiming('net');
ajax(
Expand Down
6 changes: 3 additions & 3 deletions modules/prebidServerBidAdapter/ortbConverter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ortbConverter} from '../../libraries/ortbConverter/converter.js';
import {deepAccess, deepSetValue, getBidRequest, logError, logWarn, mergeDeep, timestamp} from '../../src/utils.js';
import {deepSetValue, getBidRequest, logError, logWarn, mergeDeep, timestamp} from '../../src/utils.js';
import {config} from '../../src/config.js';
import {S2S, STATUS} from '../../src/constants.js';
import {createBid} from '../../src/bidfactory.js';
Expand Down Expand Up @@ -183,7 +183,7 @@ const PBS_CONVERTER = ortbConverter({
},
sourceExtSchain(orig, ortbRequest, proxyBidderRequest, context) {
// pass schains in ext.prebid.schains
let chains = (deepAccess(ortbRequest, 'ext.prebid.schains') || []);
let chains = ortbRequest?.ext?.prebid?.schains || [];
const chainBidders = new Set(chains.flatMap((item) => item.bidders));

chains = Object.values(
Expand All @@ -192,7 +192,7 @@ const PBS_CONVERTER = ortbConverter({
.filter((req) => !chainBidders.has(req.bidderCode)) // schain defined in s2sConfig.extPrebid takes precedence
.map((req) => ({
bidders: [req.bidderCode],
schain: deepAccess(req, 'bids.0.schain')
schain: req?.bids?.[0]?.schain
})))
.filter(({bidders, schain}) => bidders?.length > 0 && schain)
.reduce((chains, {bidders, schain}) => {
Expand Down
4 changes: 2 additions & 2 deletions modules/taboolaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
import {deepAccess, deepSetValue, getWindowSelf, replaceAuctionPrice, isArray, safeJSONParse, isPlainObject} from '../src/utils.js';
import {deepSetValue, getWindowSelf, replaceAuctionPrice, isArray, safeJSONParse, isPlainObject} from '../src/utils.js';
import {getStorageManager} from '../src/storageManager.js';
import {ajax} from '../src/ajax.js';
import {ortbConverter} from '../libraries/ortbConverter/converter.js';
Expand Down Expand Up @@ -347,7 +347,7 @@ function fillTaboolaImpData(bid, imp) {
imp.bidfloor = bidfloor;
imp.bidfloorcur = bidfloorcur;
}
deepSetValue(imp, 'ext.gpid', deepAccess(bid, 'ortb2Imp.ext.gpid'));
deepSetValue(imp, 'ext.gpid', bid?.ortb2Imp?.ext?.gpid);
}

function getBanners(bid, pos) {
Expand Down
26 changes: 13 additions & 13 deletions modules/teadsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {getValue, logError, deepAccess, parseSizesInput, isArray, getBidIdParameter} from '../src/utils.js';
import {logError, deepAccess, parseSizesInput, isArray, getBidIdParameter} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {getStorageManager} from '../src/storageManager.js';
import {isAutoplayEnabled} from '../libraries/autoplayDetection/autoplay.js';
Expand Down Expand Up @@ -34,8 +34,8 @@ export const spec = {
isBidRequestValid: function(bid) {
let isValid = false;
if (typeof bid.params !== 'undefined') {
let isValidPlacementId = _validateId(getValue(bid.params, 'placementId'));
let isValidPageId = _validateId(getValue(bid.params, 'pageId'));
let isValidPlacementId = _validateId(bid.params.placementId);
let isValidPageId = _validateId(bid.params.pageId);
isValid = isValidPlacementId && isValidPageId;
}

Expand Down Expand Up @@ -113,12 +113,12 @@ export const spec = {
payload.us_privacy = bidderRequest.uspConsent;
}

const userAgentClientHints = deepAccess(firstBidRequest, 'ortb2.device.sua');
const userAgentClientHints = firstBidRequest?.ortb2?.device?.sua;
if (userAgentClientHints) {
payload.userAgentClientHints = userAgentClientHints;
}

const dsa = deepAccess(bidderRequest, 'ortb2.regs.ext.dsa');
const dsa = bidderRequest?.ortb2?.regs?.ext?.dsa;
if (dsa) {
payload.dsa = dsa;
}
Expand Down Expand Up @@ -287,10 +287,10 @@ function findGdprStatus(gdprApplies, gdprData) {

function buildRequestObject(bid) {
const reqObj = {};
let placementId = getValue(bid.params, 'placementId');
let pageId = getValue(bid.params, 'pageId');
const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid');
const videoPlcmt = deepAccess(bid, 'mediaTypes.video.plcmt');
let placementId = bid.params.placementId;
let pageId = bid.params.pageId;
const gpid = bid?.ortb2Imp?.ext?.gpid;
const videoPlcmt = bid?.mediaTypes?.video?.plcmt;

reqObj.sizes = getSizes(bid);
reqObj.bidId = getBidIdParameter('bidId', bid);
Expand All @@ -309,9 +309,9 @@ function getSizes(bid) {
}

function concatSizes(bid) {
let playerSize = deepAccess(bid, 'mediaTypes.video.playerSize');
let videoSizes = deepAccess(bid, 'mediaTypes.video.sizes');
let bannerSizes = deepAccess(bid, 'mediaTypes.banner.sizes');
let playerSize = bid?.mediaTypes?.video?.playerSize;
let videoSizes = bid?.mediaTypes?.video?.sizes;
let bannerSizes = bid?.mediaTypes?.banner?.sizes;

if (isArray(bannerSizes) || isArray(playerSize) || isArray(videoSizes)) {
let mediaTypesSizes = [bannerSizes, videoSizes, playerSize];
Expand Down Expand Up @@ -343,7 +343,7 @@ function _validateId(id) {
* @returns `{} | {firstPartyCookieTeadsId: string}`
*/
function getFirstPartyTeadsIdParameter(validBidRequests) {
const firstPartyTeadsIdFromUserIdModule = deepAccess(validBidRequests, '0.userId.teadsId');
const firstPartyTeadsIdFromUserIdModule = validBidRequests?.[0]?.userId?.teadsId;

if (firstPartyTeadsIdFromUserIdModule) {
return {firstPartyCookieTeadsId: firstPartyTeadsIdFromUserIdModule};
Expand Down
3 changes: 1 addition & 2 deletions modules/userId/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ import {
STORAGE_TYPE_LOCALSTORAGE
} from '../../src/storageManager.js';
import {
deepAccess,
deepSetValue,
delayExecution,
isArray,
Expand Down Expand Up @@ -659,7 +658,7 @@ let initIdSystem;
function getPPID(eids = getUserIdsAsEids() || []) {
// userSync.ppid should be one of the 'source' values in getUserIdsAsEids() eg pubcid.org or id5-sync.com
const matchingUserId = ppidSource && eids.find(userID => userID.source === ppidSource);
if (matchingUserId && typeof deepAccess(matchingUserId, 'uids.0.id') === 'string') {
if (matchingUserId && typeof matchingUserId?.uids?.[0]?.id === 'string') {
const ppidValue = matchingUserId.uids[0].id.replace(/[\W_]/g, '');
if (ppidValue.length >= 32 && ppidValue.length <= 150) {
return ppidValue;
Expand Down
Loading

0 comments on commit f9327ff

Please sign in to comment.