UNPKG

video-ad-sdk

Version:

VAST/VPAID SDK that allows video ads to be played on top of any player

252 lines (209 loc) 7.38 kB
import {get, getFirstChild, getText, getAttribute} from '../xml' import type { ParsedXML, ParsedAd, VastChain, VastChainDetails, MediaFile, Optional } from '../types' import {getLinearCreative} from '../vastSelectors/helpers/getLinearCreative' import { isInline, getClickThrough, getCreativeData, isWrapper, getMediaFiles, getInteractiveFiles } from '../vastSelectors' import {parseTime} from '../vastSelectors/helpers/parseTime' const getAdSystem = (ad: ParsedAd): Optional<string> => { const adTypeElement = getFirstChild(ad) const element = adTypeElement && get(adTypeElement, 'AdSystem') return element && getText(element) } const getSubElementValue = ( parentElement: ParsedXML, tagName: string ): Optional<string> => { const element = parentElement && get(parentElement, tagName) return element && getText(element) } const getPricingElement = (ad: ParsedAd): Optional<ParsedXML> => { const adTypeElement = getFirstChild(ad) return adTypeElement && get(adTypeElement, 'Pricing') } interface Pricing { pricing?: string pricingCurrency?: string pricingModel?: string } const getPricing = (vastChain: VastChain): Pricing => { const [{ad}] = vastChain const pricingElement = ad && getPricingElement(ad) if (pricingElement) { return { pricing: getText(pricingElement), pricingCurrency: getAttribute(pricingElement, 'currency'), pricingModel: getAttribute(pricingElement, 'model') } } if (vastChain.length > 1) { return getPricing(vastChain.slice(1)) } return {} } interface Category { category?: string categoryAuthority?: string } const getCategory = (ad?: ParsedAd): Category => { const inLineElement = ad && get(ad, 'InLine') const categoryElement = inLineElement && get(inLineElement, 'Category') if (categoryElement) { return { category: getText(categoryElement), categoryAuthority: getAttribute(categoryElement, 'authority') } } return {} } const getVastVersion = (parsedVast?: ParsedXML): Optional<string> => { const vastElement = parsedVast && get(parsedVast, 'VAST') if (vastElement) { return getAttribute(vastElement, 'version') } return 'unknown' } const getAdIds = (vastChain: VastChain): string[] => vastChain.map(({ad}) => ad && getAttribute(ad, 'id')).filter(Boolean) const getAdSystems = (vastChain: VastChain): string[] => vastChain.map(({ad}) => ad && getAdSystem(ad)).filter(Boolean) const getCreatives = (vastChain: VastChain): ParsedXML[] => vastChain.map(({ad}) => ad && getLinearCreative(ad)).filter(Boolean) const getCreativeIds = (creatives: ParsedXML[]): string[] => creatives .map((creative) => creative && getAttribute(creative, 'id')) .filter(Boolean) const getCreativeAdIds = (creatives: ParsedXML[]): string[] => creatives .map((creative) => creative && getAttribute(creative, 'adId')) .filter(Boolean) const getAdTypeElement = (ad?: ParsedXML): Optional<ParsedXML> => ad && getFirstChild(ad) const getCreativeElement = (ad?: ParsedXML): Optional<ParsedXML> => ad && getLinearCreative(ad) const getLinearElement = (creativeElement?: ParsedXML): Optional<ParsedXML> => creativeElement && get(creativeElement, 'Linear') const getAdServingId = (adTypeElement?: ParsedXML): Optional<string> => adTypeElement && getSubElementValue(adTypeElement, 'AdServingId') const getAdvertiser = (adTypeElement?: ParsedXML): Optional<string> => adTypeElement && getSubElementValue(adTypeElement, 'Advertiser') const getAdTitle = (adTypeElement?: ParsedXML): Optional<string> => adTypeElement && getSubElementValue(adTypeElement, 'AdTitle') const getDescription = (adTypeElement?: ParsedXML): Optional<string> => adTypeElement && getSubElementValue(adTypeElement, 'Description') const getDuration = (linearElement?: ParsedXML): Optional<string> => linearElement && getSubElementValue(linearElement, 'Duration') const getDurationInMs = (duration?: string): Optional<number> => duration ? parseTime(duration) : undefined const getUniversalIdElement = ( creativeElement?: ParsedXML ): Optional<ParsedXML> => creativeElement && get(creativeElement, 'UniversalAdId') /** * Returns a summary of the passed {@link VastChain}. * * @param vastChain the {@link VastChain} from which we want the details. * @returns Returns a {@link VastChainDetails} object from the passed {@link VastChain}. */ export const getDetails = (vastChain: VastChain): VastChainDetails => { const adIds = getAdIds(vastChain) const adSystems = getAdSystems(vastChain) const creatives = getCreatives(vastChain) const creativeIds = getCreativeIds(creatives) const creativeAdIds = getCreativeAdIds(creatives) const [{ad, parsedXML, XML}] = vastChain const {pricing, pricingCurrency, pricingModel} = getPricing(vastChain) const {category, categoryAuthority} = getCategory(ad) const adTypeElement = getAdTypeElement(ad) const creativeElement = getCreativeElement(ad) const linearElement = getLinearElement(creativeElement) const adServingId = getAdServingId(adTypeElement) const vastVersion = getVastVersion(parsedXML) const advertiser = getAdvertiser(adTypeElement) const adTitle = getAdTitle(adTypeElement) const description = getDescription(adTypeElement) const duration = getDuration(linearElement) const durationInMs = getDurationInMs(duration) let adId let adWrapperIds: string[] = [] let adSystem let adWrapperSystems: string[] = [] let creativeId let adWrapperCreativeIds: string[] = [] let creativeAdId let adWrapperCreativeAdIds: string[] = [] let clickThroughUrl let creativeData let universalAdId let universalAdIdRegistry let mediaFiles: MediaFile[] = [] let vpaid let skippable let skipOffset let skipOffsetInMs if (isInline(ad)) { ;[adId, ...adWrapperIds] = adIds ;[adSystem, ...adWrapperSystems] = adSystems ;[creativeId, ...adWrapperCreativeIds] = creativeIds ;[creativeAdId, ...adWrapperCreativeAdIds] = creativeAdIds clickThroughUrl = ad && getClickThrough(ad) creativeData = XML ? getCreativeData(XML) : undefined const universalIdElement = getUniversalIdElement(creativeElement) universalAdId = universalIdElement && getText(universalIdElement) universalAdIdRegistry = universalIdElement && getAttribute(universalIdElement, 'idRegistry') mediaFiles = (ad && getMediaFiles(ad)) || [] vpaid = Boolean(ad && getInteractiveFiles(ad)) skipOffset = linearElement && getAttribute(linearElement, 'skipoffset') skipOffsetInMs = skipOffset ? parseTime(skipOffset) : undefined skippable = Boolean(skipOffset) } else if (isWrapper(vastChain[0].ad)) { adWrapperIds = adIds adWrapperSystems = adSystems adWrapperCreativeIds = creativeIds adWrapperCreativeAdIds = creativeAdIds } return { adId, adServingId, adSystem, adTitle, advertiser, adWrapperCreativeAdIds, adWrapperCreativeIds, adWrapperIds, adWrapperSystems, category, categoryAuthority, clickThroughUrl, creativeAdId, creativeData, creativeId, description, duration, durationInMs, mediaFiles, pricing, pricingCurrency, pricingModel, skipOffset, skipOffsetInMs, skippable, universalAdId, universalAdIdRegistry, vastVersion, vpaid } }