-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core: ORTB video params validation (work on dupe) #11970
Changes from 2 commits
569438f
335f25f
110bf0b
5e0c359
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,52 @@ | ||
import {deepAccess, logError} from './utils.js'; | ||
import {deepAccess, isArrayOfNums, isInteger, isNumber, isStr, logError, logWarn} from './utils.js'; | ||
import {config} from '../src/config.js'; | ||
import {hook} from './hook.js'; | ||
import {auctionManager} from './auctionManager.js'; | ||
|
||
export const OUTSTREAM = 'outstream'; | ||
export const INSTREAM = 'instream'; | ||
|
||
/** | ||
* Basic validation of OpenRTB 2.x video object properties. | ||
* Not included: `companionad`, `durfloors`, `ext` | ||
* reference: https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/main/2.6.md | ||
*/ | ||
export const ORTB_VIDEO_PARAMS = new Map([ | ||
[ 'mimes', { validate: (value) => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string') } ], | ||
[ 'minduration', { validate: (value) => isInteger(value) } ], | ||
[ 'maxduration', { validate: (value) => isInteger(value) } ], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be more compact ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea was to make a map that was not a strict "validation map", it is easier to plug-in something else later, but honestly I don't know how to extend it right now. Tell me if you prefer I use the "compact" way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think compact is better because in terms of bundle size, N maps are still smaller than a map where each node has N things in it. |
||
[ 'startdelay', { validate: (value) => isInteger(value) } ], | ||
[ 'maxseq', { validate: (value) => isInteger(value) } ], | ||
[ 'poddur', { validate: (value) => isInteger(value) } ], | ||
[ 'protocols', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'w', { validate: (value) => isInteger(value) } ], | ||
[ 'h', { validate: (value) => isInteger(value) } ], | ||
[ 'podid', { validate: (value) => isStr(value) } ], | ||
[ 'podseq', { validate: (value) => isInteger(value) } ], | ||
[ 'rqddurs', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'placement', { validate: (value) => isInteger(value) } ], // deprecated, see plcmt | ||
[ 'plcmt', { validate: (value) => isInteger(value) } ], | ||
[ 'linearity', { validate: (value) => isInteger(value) } ], | ||
[ 'skip', { validate: (value) => [1, 0].includes(value) } ], | ||
[ 'skipmin', { validate: (value) => isInteger(value) } ], | ||
[ 'skipafter', { validate: (value) => isInteger(value) } ], | ||
[ 'sequence', { validate: (value) => isInteger(value) } ], // deprecated | ||
[ 'slotinpod', { validate: (value) => isInteger(value) } ], | ||
[ 'mincpmpersec', { validate: (value) => isNumber(value) } ], | ||
[ 'battr', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'maxextended', { validate: (value) => isInteger(value) } ], | ||
[ 'minbitrate', { validate: (value) => isInteger(value) } ], | ||
[ 'maxbitrate', { validate: (value) => isInteger(value) } ], | ||
[ 'boxingallowed', { validate: (value) => isInteger(value) } ], | ||
[ 'playbackmethod', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'playbackend', { validate: (value) => isInteger(value) } ], | ||
[ 'delivery', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'pos', { validate: (value) => isInteger(value) } ], | ||
[ 'api', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'companiontype', { validate: (value) => isArrayOfNums(value) } ], | ||
[ 'poddedupe', { validate: (value) => isArrayOfNums(value) } ], | ||
]); | ||
|
||
export function fillVideoDefaults(adUnit) { | ||
const video = adUnit?.mediaTypes?.video; | ||
if (video != null && video.plcmt == null) { | ||
|
@@ -17,6 +58,28 @@ export function fillVideoDefaults(adUnit) { | |
} | ||
} | ||
|
||
/** | ||
* validateOrtbVideoFields mutates the `videoParams` object by removing invalid ortb properties. | ||
* Other properties are ignored and kept as is. | ||
* | ||
* @param {object} videoParams | ||
* @returns {void} | ||
*/ | ||
export function validateOrtbVideoFields(videoParams) { | ||
if (videoParams != null) { | ||
Object.entries(videoParams) | ||
.forEach(([key, value]) => { | ||
if (ORTB_VIDEO_PARAMS.has(key)) { | ||
const valid = ORTB_VIDEO_PARAMS.get(key).validate(value); | ||
if (!valid) { | ||
delete videoParams[key]; | ||
logWarn(`Invalid value for mediaTypes.video.${key} ORTB property. The property has been removed.`); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this enough info to track down the issue - should we log the offending adUnit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This way, I should update the function to In 1st attempt I would like to keep the function scoped on the videoParams object, but perhaps it makes no sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tend to agree that the scope should be as small as possible, but I'm not sure code aesthetics will convince someone with a complicated setup and a bunch of cryptic warning messages :) You could also do something like |
||
} | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* @typedef {object} VideoBid | ||
* @property {string} adId id of the bid | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this feels like a lot to add to core, so many prominent bid adapters do exactly this that it would likely be a net code reduction, very exciting