Skip to content

Commit

Permalink
json-deep-clone (#11768)
Browse files Browse the repository at this point in the history
  • Loading branch information
bbaresic committed Jun 12, 2024
1 parent a96643f commit f61da87
Show file tree
Hide file tree
Showing 20 changed files with 116 additions and 61 deletions.
4 changes: 2 additions & 2 deletions modules/aidemBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {deepAccess, deepSetValue, isBoolean, isNumber, isStr, logError, logInfo} from '../src/utils.js';
import {deepAccess, deepClone, deepSetValue, isBoolean, isNumber, isStr, logError, logInfo} from '../src/utils.js';
import {config} from '../src/config.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
Expand Down Expand Up @@ -132,7 +132,7 @@ function getRegs(bidderRequest) {
}

function setPrebidRequestEnvironment(payload) {
const __navigator = JSON.parse(JSON.stringify(recur(navigator)));
const __navigator = deepClone(recur(navigator));
delete __navigator.plugins;
deepSetValue(payload, 'environment.ri', getRefererInfo());
deepSetValue(payload, 'environment.hl', window.history.length);
Expand Down
4 changes: 2 additions & 2 deletions modules/apacdexBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn, logError } from '../src/utils.js';
import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn, logError, deepClone } from '../src/utils.js';
import { config } from '../src/config.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import {hasPurpose1Consent} from '../src/utils/gpdr.js';
Expand Down Expand Up @@ -85,7 +85,7 @@ export const spec = {
bidReq.bidFloor = bidFloor;
}

bids.push(JSON.parse(JSON.stringify(bidReq)));
bids.push(deepClone(bidReq));
});

const payload = {};
Expand Down
10 changes: 5 additions & 5 deletions modules/asteriobidAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateUUID, getParameterByName, logError, logInfo, parseUrl } from '../src/utils.js'
import { generateUUID, getParameterByName, logError, logInfo, parseUrl, deepClone, hasNonSerializableProperty } from '../src/utils.js'
import { ajaxBuilder } from '../src/ajax.js'
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'
import adapterManager from '../src/adapterManager.js'
Expand Down Expand Up @@ -192,10 +192,10 @@ function handleEvent(eventType, eventArgs) {
return
}

try {
eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {}
} catch (e) {
// keep eventArgs as is
if (eventArgs) {
eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs)
} else {
eventArgs = {}
}

const pmEvent = {}
Expand Down
3 changes: 2 additions & 1 deletion modules/bidwatchAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import adapterManager from '../src/adapterManager.js';
import { EVENTS } from '../src/constants.js';
import { ajax } from '../src/ajax.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { deepClone } from '../src/utils.js';

const analyticsType = 'endpoint';
const url = 'URL_TO_SERVER_ENDPOINT';
Expand Down Expand Up @@ -113,7 +114,7 @@ function addTimeout(args) {
let stringArgs = JSON.parse(dereferenceWithoutRenderer(args));
argsDereferenced = stringArgs;
argsDereferenced.forEach((attr) => {
argsCleaned.push(filterAttributes(JSON.parse(JSON.stringify(attr)), false));
argsCleaned.push(filterAttributes(deepClone(attr), false));
});
if (auctionEnd[eventType] == undefined) { auctionEnd[eventType] = [] }
auctionEnd[eventType].push(argsCleaned);
Expand Down
8 changes: 4 additions & 4 deletions modules/debugging/bidInterceptor.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
deepAccess,
deepClone,
deepEqual,
delayExecution,
mergeDeep
mergeDeep,
hasNonSerializableProperty
} from '../../src/utils.js';

/**
Expand All @@ -22,9 +22,9 @@ Object.assign(BidInterceptor.prototype, {
},
serializeConfig(ruleDefs) {
const isSerializable = (ruleDef, i) => {
const serializable = deepEqual(ruleDef, JSON.parse(JSON.stringify(ruleDef)), {checkTypes: true});
const serializable = !hasNonSerializableProperty(ruleDef);
if (!serializable && !deepAccess(ruleDef, 'options.suppressWarnings')) {
this.logger.logWarn(`Bid interceptor rule definition #${i + 1} is not serializable and will be lost after a refresh. Rule definition: `, ruleDef);
this.logger.logWarn(`Bid interceptor rule definition #${i + 1} contains non-serializable properties and will be lost after a refresh. Rule definition: `, ruleDef);
}
return serializable;
}
Expand Down
4 changes: 2 additions & 2 deletions modules/etargetBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deepSetValue, isFn, isPlainObject } from '../src/utils.js';
import { deepClone, deepSetValue, isFn, isPlainObject } from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';

Expand Down Expand Up @@ -28,7 +28,7 @@ export const spec = {
buildRequests: function (validBidRequests, bidderRequest) {
var i, l, bid, reqParams, netRevenue, gdprObject;
var request = [];
var bids = JSON.parse(JSON.stringify(validBidRequests));
var bids = deepClone(validBidRequests);
var lastCountry = 'sk';
var floors = [];
for (i = 0, l = bids.length; i < l; i++) {
Expand Down
2 changes: 1 addition & 1 deletion modules/growthCodeAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ let analyticsType = 'endpoint';

let growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}), {
track({eventType, args}) {
let eventData = args ? JSON.parse(JSON.stringify(args)) : {};
let eventData = args ? utils.deepClone(args) : {};
let data = {};
if (!trackEvents.includes(eventType)) return;
switch (eventType) {
Expand Down
2 changes: 1 addition & 1 deletion modules/hadronAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ let analyticsType = 'endpoint';

let hadronAnalyticsAdapter = Object.assign(adapter({url: HADRON_ANALYTICS_URL, analyticsType}), {
track({eventType, args}) {
args = args ? JSON.parse(JSON.stringify(args)) : {};
args = args ? utils.deepClone(args) : {};
var data = {};
if (!eventsToTrack.includes(eventType)) return;
switch (eventType) {
Expand Down
22 changes: 11 additions & 11 deletions modules/interactiveOffersBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {isNumber, logWarn} from '../src/utils.js';
import {deepClone, isNumber, logWarn} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';

Expand Down Expand Up @@ -80,7 +80,7 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) {
let pageURL = window.location.href;
let domain = window.location.hostname;
let secure = (window.location.protocol == 'https:' ? 1 : 0);
let openRTBRequest = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequest']));
let openRTBRequest = deepClone(DEFAULT['OpenRTBBidRequest']);
openRTBRequest.id = bidderRequest.bidderRequestId;
openRTBRequest.ext = {
// TODO: please do not send internal data structures over the network
Expand All @@ -89,36 +89,36 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) {
auctionId: prebidRequest.auctionId
};

openRTBRequest.site = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSite']));
openRTBRequest.site = deepClone(DEFAULT['OpenRTBBidRequestSite']);
openRTBRequest.site.id = domain;
openRTBRequest.site.name = domain;
openRTBRequest.site.domain = domain;
openRTBRequest.site.page = pageURL;
openRTBRequest.site.ref = prebidRequest.refererInfo.ref;

openRTBRequest.site.publisher = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSitePublisher']));
openRTBRequest.site.publisher = deepClone(DEFAULT['OpenRTBBidRequestSitePublisher']);
openRTBRequest.site.publisher.id = 0;
openRTBRequest.site.publisher.name = prebidRequest.refererInfo.domain;
openRTBRequest.site.publisher.domain = domain;
openRTBRequest.site.publisher.domain = domain;

openRTBRequest.site.content = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSiteContent']));
openRTBRequest.site.content = deepClone(DEFAULT['OpenRTBBidRequestSiteContent']);

openRTBRequest.source = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestSource']));
openRTBRequest.source = deepClone(DEFAULT['OpenRTBBidRequestSource']);
openRTBRequest.source.fd = 0;
openRTBRequest.source.tid = prebidRequest.ortb2?.source?.tid;
openRTBRequest.source.pchain = '';

openRTBRequest.device = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestDevice']));
openRTBRequest.device = deepClone(DEFAULT['OpenRTBBidRequestDevice']);

openRTBRequest.user = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestUser']));
openRTBRequest.user = deepClone(DEFAULT['OpenRTBBidRequestUser']);

openRTBRequest.imp = [];
prebidRequest.bids.forEach(function(bid) {
if (!ret.partnerId) {
ret.partnerId = bid.params.partnerId;
}
let imp = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestImp']));
let imp = deepClone(DEFAULT['OpenRTBBidRequestImp']);
imp.id = bid.bidId;
imp.secure = secure;
imp.tagid = bid.adUnitCode;
Expand All @@ -131,7 +131,7 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) {

Object.keys(bid.mediaTypes).forEach(function(mediaType) {
if (mediaType == 'banner') {
imp.banner = JSON.parse(JSON.stringify(DEFAULT['OpenRTBBidRequestImpBanner']));
imp.banner = deepClone(DEFAULT['OpenRTBBidRequestImpBanner']);
imp.banner.w = 0;
imp.banner.h = 0;
imp.banner.format = [];
Expand All @@ -156,7 +156,7 @@ function parseResponseOpenRTBToPrebidjs(openRTBResponse) {
response.seatbid.forEach(function(seatbid) {
if (seatbid.bid && seatbid.bid.forEach) {
seatbid.bid.forEach(function(bid) {
let prebid = JSON.parse(JSON.stringify(DEFAULT['PrebidBid']));
let prebid = deepClone(DEFAULT['PrebidBid']);
prebid.requestId = bid.impid;
prebid.ad = bid.adm;
prebid.creativeId = bid.crid;
Expand Down
9 changes: 7 additions & 2 deletions modules/invisiblyAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ajaxBuilder } from '../src/ajax.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';

import { generateUUID, logInfo } from '../src/utils.js';
import { deepClone, hasNonSerializableProperty, generateUUID, logInfo } from '../src/utils.js';
import { EVENTS } from '../src/constants.js';

const DEFAULT_EVENT_URL = 'https://api.pymx5.com/v1/' + 'sites/events';
Expand Down Expand Up @@ -133,7 +133,12 @@ function flush() {
}

function handleEvent(eventType, eventArgs) {
eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {};
if (eventArgs) {
eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs)
} else {
eventArgs = {}
}

let invisiblyEvent = {};

switch (eventType) {
Expand Down
11 changes: 6 additions & 5 deletions modules/newspassidBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
deepClone,
logInfo,
logError,
deepAccess,
Expand Down Expand Up @@ -33,12 +34,12 @@ export const spec = {
},
loadConfiguredData(bid) {
if (this.propertyBag.config) { return; }
this.propertyBag.config = JSON.parse(JSON.stringify(this.config_defaults));
this.propertyBag.config = deepClone(this.config_defaults);
let bidder = bid.bidder || 'newspassid';
this.propertyBag.config.logId = bidder.toUpperCase();
this.propertyBag.config.bidder = bidder;
let bidderConfig = config.getConfig(bidder) || {};
logInfo('got bidderConfig: ', JSON.parse(JSON.stringify(bidderConfig)));
logInfo('got bidderConfig: ', deepClone(bidderConfig));
let arrGetParams = this.getGetParametersAsObject();
if (bidderConfig.endpointOverride) {
if (bidderConfig.endpointOverride.origin) {
Expand Down Expand Up @@ -131,7 +132,7 @@ export const spec = {
buildRequests(validBidRequests, bidderRequest) {
this.loadConfiguredData(validBidRequests[0]);
this.propertyBag.buildRequestsStart = new Date().getTime();
logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${NEWSPASSVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest)));
logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${NEWSPASSVERSION} validBidRequests`, deepClone(validBidRequests), 'bidderRequest', deepClone(bidderRequest));
if (this.blockTheRequest()) {
return [];
}
Expand Down Expand Up @@ -281,7 +282,7 @@ export const spec = {
data: JSON.stringify(npRequest),
bidderRequest: bidderRequest
};
logInfo('buildRequests request data for single = ', JSON.parse(JSON.stringify(npRequest)));
logInfo('buildRequests request data for single = ', deepClone(npRequest));
this.propertyBag.buildRequestsEnd = new Date().getTime();
logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret);
return ret;
Expand Down Expand Up @@ -309,7 +310,7 @@ export const spec = {
if (request && request.bidderRequest && request.bidderRequest.bids) { this.loadConfiguredData(request.bidderRequest.bids[0]); }
let startTime = new Date().getTime();
logInfo(`interpretResponse time: ${startTime}. buildRequests done -> interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`);
logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request)));
logInfo(`serverResponse, request`, deepClone(serverResponse), deepClone(request));
serverResponse = serverResponse.body || {};
let aucId = serverResponse.id; // this will be correct for single requests and non-single
if (!serverResponse.hasOwnProperty('seatbid')) {
Expand Down
2 changes: 1 addition & 1 deletion modules/nobidAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ window.nobidCarbonizer = {
adunit.bids = allowedBidders;
}
for (const adunit of adunits) {
if (!nobidAnalytics.originalAdUnits[adunit.code]) nobidAnalytics.originalAdUnits[adunit.code] = JSON.parse(JSON.stringify(adunit));
if (!nobidAnalytics.originalAdUnits[adunit.code]) nobidAnalytics.originalAdUnits[adunit.code] = deepClone(adunit);
};
if (this.isActive()) {
// 5% of the time do not block;
Expand Down
3 changes: 2 additions & 1 deletion modules/oxxionAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import adapterManager from '../src/adapterManager.js';
import { EVENTS } from '../src/constants.js';
import { ajax } from '../src/ajax.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { deepClone } from '../src/utils.js';

const analyticsType = 'endpoint';
const url = 'URL_TO_SERVER_ENDPOINT';
Expand Down Expand Up @@ -125,7 +126,7 @@ function addTimeout(args) {
let stringArgs = JSON.parse(dereferenceWithoutRenderer(args));
argsDereferenced = stringArgs;
argsDereferenced.forEach((attr) => {
argsCleaned.push(filterAttributes(JSON.parse(JSON.stringify(attr)), false));
argsCleaned.push(filterAttributes(deepClone(attr), false));
});
if (auctionEnd[eventType] == undefined) { auctionEnd[eventType] = [] }
auctionEnd[eventType].push(argsCleaned);
Expand Down
17 changes: 9 additions & 8 deletions modules/ozoneBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
deepClone,
logInfo,
logError,
deepAccess,
Expand Down Expand Up @@ -42,12 +43,12 @@ export const spec = {
},
loadWhitelabelData(bid) {
if (this.propertyBag.whitelabel) { return; }
this.propertyBag.whitelabel = JSON.parse(JSON.stringify(this.whitelabel_defaults));
this.propertyBag.whitelabel = deepClone(this.whitelabel_defaults);
let bidder = bid.bidder || 'ozone'; // eg. ozone
this.propertyBag.whitelabel.logId = bidder.toUpperCase();
this.propertyBag.whitelabel.bidder = bidder;
let bidderConfig = config.getConfig(bidder) || {};
logInfo('got bidderConfig: ', JSON.parse(JSON.stringify(bidderConfig)));
logInfo('got bidderConfig: ', deepClone(bidderConfig));
if (bidderConfig.kvpPrefix) {
this.propertyBag.whitelabel.keyPrefix = bidderConfig.kvpPrefix;
}
Expand Down Expand Up @@ -177,7 +178,7 @@ export const spec = {
this.propertyBag.buildRequestsStart = new Date().getTime();
let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone
let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix;
logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest)));
logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, deepClone(validBidRequests), 'bidderRequest', deepClone(bidderRequest));
if (this.blockTheRequest()) {
return [];
}
Expand Down Expand Up @@ -403,7 +404,7 @@ export const spec = {
data: JSON.stringify(ozoneRequest),
bidderRequest: bidderRequest
};
logInfo('buildRequests request data for single = ', JSON.parse(JSON.stringify(ozoneRequest)));
logInfo('buildRequests request data for single = ', deepClone(ozoneRequest));
this.propertyBag.buildRequestsEnd = new Date().getTime();
logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret);
return ret;
Expand Down Expand Up @@ -444,7 +445,7 @@ export const spec = {
if (mediaTypesSizes.native) {
ret.native = bidRequestRef.getFloor({mediaType: 'native', currency: 'USD', size: mediaTypesSizes.native});
}
logInfo('getFloorObjectForAuction returning : ', JSON.parse(JSON.stringify(ret)));
logInfo('getFloorObjectForAuction returning : ', deepClone(ret));
return ret;
},
interpretResponse(serverResponse, request) {
Expand All @@ -453,7 +454,7 @@ export const spec = {
let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone
let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix;
logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`);
logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request)));
logInfo(`serverResponse, request`, deepClone(serverResponse), deepClone(request));
serverResponse = serverResponse.body || {};
let aucId = serverResponse.id; // this will be correct for single requests and non-single
if (!serverResponse.hasOwnProperty('seatbid')) {
Expand Down Expand Up @@ -573,7 +574,7 @@ export const spec = {
}
let endTime = new Date().getTime();
logInfo(`interpretResponse going to return at time ${endTime} (took ${endTime - startTime}ms) Time from buildRequests Start -> interpretRequests End = ${endTime - this.propertyBag.buildRequestsStart}ms`);
logInfo('interpretResponse arrAllBids (serialised): ', JSON.parse(JSON.stringify(arrAllBids))); // this is ok to log because the renderer has not been attached yet
logInfo('interpretResponse arrAllBids (serialised): ', deepClone(arrAllBids)); // this is ok to log because the renderer has not been attached yet
return arrAllBids;
},
setBidMediaTypeIfNotExist(thisBid, mediaType) {
Expand Down Expand Up @@ -1039,7 +1040,7 @@ function newRenderer(adUnitCode, rendererOptions = {}) {
}
function outstreamRender(bid) {
logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid = (first static, then reference)');
logInfo(JSON.parse(JSON.stringify(spec.getLoggableBidObject(bid))));
logInfo(deepClone(spec.getLoggableBidObject(bid)));
bid.renderer.push(() => {
logInfo('Going to execute window.ozoneVideo.outstreamRender');
window.ozoneVideo.outstreamRender(bid);
Expand Down
10 changes: 5 additions & 5 deletions modules/prebidmanagerAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateUUID, getParameterByName, logError, parseUrl, logInfo } from '../src/utils.js';
import { deepClone, generateUUID, getParameterByName, hasNonSerializableProperty, logError, parseUrl, logInfo } from '../src/utils.js';
import {ajaxBuilder} from '../src/ajax.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
Expand Down Expand Up @@ -199,10 +199,10 @@ function trimBidderRequest(bidderRequest) {
}

function handleEvent(eventType, eventArgs) {
try {
eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {};
} catch (e) {
// keep eventArgs as is
if (eventArgs) {
eventArgs = hasNonSerializableProperty(eventArgs) ? eventArgs : deepClone(eventArgs)
} else {
eventArgs = {}
}

const pmEvent = {};
Expand Down
Loading

0 comments on commit f61da87

Please sign in to comment.