From e7e3e67c750064e5be0890e3a5fff308391011f8 Mon Sep 17 00:00:00 2001 From: Christiaan Scheermeijer Date: Wed, 31 Jul 2024 16:58:57 +0200 Subject: [PATCH] refactor: fix delivery api ad schedule typings --- packages/common/src/services/ApiService.ts | 6 +- packages/common/src/services/ConfigService.ts | 12 ---- packages/common/types/ad-schedule.ts | 55 +++++++++++++++++++ packages/hooks-react/src/useAds.ts | 5 +- .../ui-react/src/components/Player/Player.tsx | 4 +- 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/packages/common/src/services/ApiService.ts b/packages/common/src/services/ApiService.ts index 167c524cc..2f312bad9 100644 --- a/packages/common/src/services/ApiService.ts +++ b/packages/common/src/services/ApiService.ts @@ -8,7 +8,7 @@ import { filterMediaOffers } from '../utils/entitlements'; import { useConfigStore as ConfigStore } from '../stores/ConfigStore'; import type { GetPlaylistParams, Playlist, PlaylistItem } from '../../types/playlist'; import type { ContentList, GetContentSearchParams } from '../../types/content-list'; -import type { AdSchedule } from '../../types/ad-schedule'; +import type { DeliveryAdSchedule } from '../../types/ad-schedule'; import type { EpisodeInSeries, EpisodesRes, EpisodesWithPagination, GetSeriesParams, Series } from '../../types/series'; import env from '../env'; import { logError } from '../logger'; @@ -255,7 +255,7 @@ export default class ApiService { return this.transformEpisodes(episodesRes, seasonNumber); }; - getAdSchedule = async (id: string | undefined | null): Promise => { + getAdSchedule = async (id: string | undefined | null): Promise => { if (!id) { throw new Error('Ad Schedule ID is required'); } @@ -263,7 +263,7 @@ export default class ApiService { const url = env.APP_API_BASE_URL + `/v2/advertising/schedules/${id}.json`; const response = await fetch(url, { credentials: 'omit' }); - return (await getDataOrThrow(response)) as AdSchedule; + return (await getDataOrThrow(response)) as DeliveryAdSchedule; }; /** diff --git a/packages/common/src/services/ConfigService.ts b/packages/common/src/services/ConfigService.ts index c775a87c8..7237a45dc 100644 --- a/packages/common/src/services/ConfigService.ts +++ b/packages/common/src/services/ConfigService.ts @@ -7,8 +7,6 @@ import { AppError } from '../utils/error'; import type { Config } from '../../types/config'; import env from '../env'; -import ApiService from './ApiService'; - /** * Set config setup changes in both config.service.ts and config.d.ts * */ @@ -35,12 +33,6 @@ export default class ConfigService { features: {}, }; - private readonly apiService: ApiService; - - constructor(apiService: ApiService) { - this.apiService = apiService; - } - private enrichConfig = (config: Config): Config => { const { content, siteName } = config; const updatedContent = content.map((content) => Object.assign({ featured: false }, content)); @@ -70,10 +62,6 @@ export default class ConfigService { return source; }; - loadAdSchedule = async (adScheduleId: string | undefined | null) => { - return this.apiService.getAdSchedule(adScheduleId); - }; - loadConfig = async (configLocation: string | undefined) => { const i18n = getI18n(); diff --git a/packages/common/types/ad-schedule.ts b/packages/common/types/ad-schedule.ts index d01c00c1e..1b2c055b2 100644 --- a/packages/common/types/ad-schedule.ts +++ b/packages/common/types/ad-schedule.ts @@ -10,3 +10,58 @@ export type AdScheduleUrls = { }; export type AdDeliveryMethod = 'csai' | 'ssai'; + +type DeliverySchedule = { + tag: string[]; + type: 'linear' | 'nonlinear'; + offset: 'pre' | 'post' | string; // seconds, timestamp, percentage + skipoffset?: number; +}; + +type DeliveryRules = { + startOnSeek: 'pre' | 'none' | 'mid'; + timeBetweenAds: number; + startOn?: number; + frequency?: number; +}; + +type DeliveryBids = { + settings: { + bidTimeout: number; + floorPriceCents: number; + mediationLayerAdServer: 'dfp' | 'jwp' | 'jwpdfp' | 'jwpspotx'; + disableConsentManagementOnNoCmp?: boolean; + sendAllBids: boolean; + buckets: { min?: number; max?: number; increment?: number }[]; // anyOf + consentManagement: { + usp: { + cmpApi: 'iab' | 'static'; + timeout: number; + }; + gdpr: { + cmpApi: 'iab' | 'static'; + timeout: number; + defaultGdprScope: boolean; + allowAuctionWithoutConsent: boolean; + rules?: { + purpose: 'basicAds' | 'storage' | 'measurement'; + enforcePurpose: boolean; + enforceVendor: boolean; + vendorExceptions?: string[]; + }[]; + }; + }; + }; + ortbParams: { + plcmt: number; + }; +}; + +export type DeliveryAdSchedule = { + rules: DeliveryRules; + schedule: DeliverySchedule[]; + bids: DeliveryBids; + client: 'vast' | 'googima'; + vpaidmode?: 'enabled' | 'disabled' | 'insecure'; + adscheduleid: string; +}; diff --git a/packages/hooks-react/src/useAds.ts b/packages/hooks-react/src/useAds.ts index f5249d8d4..20178d392 100644 --- a/packages/hooks-react/src/useAds.ts +++ b/packages/hooks-react/src/useAds.ts @@ -3,6 +3,7 @@ import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore'; import ApiService from '@jwp/ott-common/src/services/ApiService'; import { getModule } from '@jwp/ott-common/src/modules/container'; import { createURL } from '@jwp/ott-common/src/utils/urlFormatting'; +import type { AdSchedule } from '@jwp/ott-common/types/ad-schedule'; const CACHE_TIME = 60 * 1000 * 20; @@ -33,12 +34,12 @@ export const useAds = ({ mediaId }: { mediaId: string }) => { const { data: adSchedule, isLoading: isAdScheduleLoading } = useLegacyStandaloneAds({ adScheduleId, enabled: !!adScheduleId }); const adConfig = useAdConfigFlow - ? { + ? ({ client: 'vast', schedule: createURL(adScheduleUrls?.xml || '', { media_id: mediaId, }), - } + } as AdSchedule) : undefined; return { diff --git a/packages/ui-react/src/components/Player/Player.tsx b/packages/ui-react/src/components/Player/Player.tsx index 3d2a27503..740a141bb 100644 --- a/packages/ui-react/src/components/Player/Player.tsx +++ b/packages/ui-react/src/components/Player/Player.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; -import type { AdSchedule } from '@jwp/ott-common/types/ad-schedule'; +import type { AdSchedule, DeliveryAdSchedule } from '@jwp/ott-common/types/ad-schedule'; import type { PlaylistItem } from '@jwp/ott-common/types/playlist'; import { useConfigStore } from '@jwp/ott-common/src/stores/ConfigStore'; import { deepCopy } from '@jwp/ott-common/src/utils/collection'; @@ -20,7 +20,7 @@ type Props = { item: PlaylistItem; startTime?: number; autostart?: boolean; - adsData?: AdSchedule; + adsData?: AdSchedule | DeliveryAdSchedule; onReady?: (player?: JWPlayer) => void; onPlay?: () => void; onPause?: () => void;