@playpilot/tpi 8.40.0-beta.5 → 8.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playpilot/tpi",
3
- "version": "8.40.0-beta.5",
3
+ "version": "8.40.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -14,3 +14,7 @@ export async function fetchConfig(): Promise<ConfigResponse | null> {
14
14
  return null
15
15
  }
16
16
  }
17
+
18
+ export function getConfigValue<K extends keyof ConfigResponse>(key: K): ConfigResponse[K] | undefined {
19
+ return window.PlayPilotLinkInjections?.config?.[key]
20
+ }
@@ -2,6 +2,7 @@ import { SupportedRegion } from '$lib/enums/Region'
2
2
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
3
3
  import { track } from '$lib/tracking'
4
4
  import { RETARGETING_REGION_KEY } from '@playpilot/retargeting-tracking'
5
+ import { getConfigValue } from './config'
5
6
 
6
7
  export async function getRegionBasedOnIp(timeout = 5000): Promise<string> {
7
8
  const savedRegion = window.PlayPilotLinkInjections?.region
@@ -23,7 +24,7 @@ export async function getRegionBasedOnIp(timeout = 5000): Promise<string> {
23
24
  } catch (error: any) {
24
25
  track(TrackingEvent.RegionRequestFailed, null, { message: error.message })
25
26
 
26
- const fallbackRegion = window.PlayPilotLinkInjections?.config?.fallback_region
27
+ const fallbackRegion = getConfigValue('fallback_region')
27
28
  return fallbackRegion || ''
28
29
  }
29
30
  }
@@ -1,16 +1,17 @@
1
1
  import { mount, unmount } from 'svelte'
2
2
  import InTextDisclaimer from '../routes/components/InTextDisclaimer.svelte'
3
+ import { getConfigValue } from './api/config'
3
4
 
4
5
  export let inTextDisclaimerInsertComponent: object | null = null
5
6
 
6
7
  export function insertInTextDisclaimer(elements: HTMLElement[]): void {
7
- if (!window.PlayPilotLinkInjections?.config?.in_text_disclaimer_enabled) return
8
+ if (!getConfigValue('in_text_disclaimer_enabled')) return
8
9
  if (inTextDisclaimerInsertComponent) return
9
10
 
10
11
  const target = document.createElement('div')
11
- const selector = window.PlayPilotLinkInjections?.config?.in_text_disclaimer_selector
12
+ const selector = getConfigValue('in_text_disclaimer_selector')
12
13
  const insertElement = (selector ? document.querySelector(selector) : null) || elements[0]
13
- const insertPosition = window.PlayPilotLinkInjections?.config?.in_text_disclaimer_insert_position || 'beforebegin'
14
+ const insertPosition = getConfigValue('in_text_disclaimer_insert_position') || 'beforebegin'
14
15
 
15
16
  target.dataset.playpilotInTextDisclaimer = 'true'
16
17
  insertElement.insertAdjacentElement(insertPosition, target)
@@ -1,5 +1,6 @@
1
1
  import { mount, unmount } from 'svelte'
2
2
  import ExploreRouter from '../routes/components/Explore/ExploreRouter.svelte'
3
+ import { getConfigValue } from './api/config'
3
4
 
4
5
  export const exploreParentSelector = '[data-playpilot-explore]'
5
6
  export const explorePreConsentSelector = '[data-playpilot-pre-consent-explore]'
@@ -68,7 +69,7 @@ export function insertExploreIntoNavigation(): boolean {
68
69
  }
69
70
 
70
71
  function insertExploreCustomStyle(): void {
71
- const customStyleString = window.PlayPilotLinkInjections.config?.explore_custom_style
72
+ const customStyleString = getConfigValue('explore_custom_style')
72
73
 
73
74
  if (!customStyleString) return
74
75
 
@@ -81,5 +82,5 @@ function insertExploreCustomStyle(): void {
81
82
  }
82
83
 
83
84
  export function useExploreRouter(): boolean {
84
- return !!window.PlayPilotLinkInjections?.config?.explore_use_router
85
+ return !!getConfigValue('explore_use_router')
85
86
  }
@@ -9,6 +9,7 @@ import { exploreModalUrl, participantUrl, titleUrl } from './routes'
9
9
  import { clearInTextWidgets, insertInTextWidgets } from './inTextWidgets'
10
10
  import { encodeHtmlEntities } from './html'
11
11
  import type { ParticipantData } from './types/participant'
12
+ import { getConfigValue } from './api/config'
12
13
 
13
14
  export const keyDataAttribute = 'data-playpilot-injection-key'
14
15
  export const keySelector = `[${keyDataAttribute}]`
@@ -219,7 +220,7 @@ function createLinkInjectionElement(injection: LinkInjection): { injectionElemen
219
220
  injectionElement.dataset.playpilotInjectionKey = injection.key
220
221
  injectionElement.dataset.playpilotInjectionType = injection.type
221
222
 
222
- const openInExplore = !!window.PlayPilotLinkInjections?.config?.open_tpi_links_in_explore
223
+ const openInExplore = !!getConfigValue('open_tpi_links_in_explore')
223
224
 
224
225
  const sid = injection.title_details?.sid || injection.participant_details?.sid
225
226
  const href = openInExplore ? exploreModalUrl(sid!) : (injection.type === 'title' ? titleUrl(injection.title_details!) : participantUrl(injection.participant_details!))
@@ -336,7 +337,7 @@ function addLinkInjectionEventListeners(injections: LinkInjection[]): void {
336
337
  window.addEventListener('mousemove', destroyLinkPopoverOnMouseleave)
337
338
 
338
339
  window.addEventListener('click', (event) => {
339
- if (window.PlayPilotLinkInjections?.config?.open_tpi_links_in_explore) return
340
+ if (getConfigValue('open_tpi_links_in_explore')) return
340
341
 
341
342
  openModalForInjectedLink(event, injections)
342
343
  })
@@ -454,15 +455,12 @@ export function limitInjectionsByCount(injections: LinkInjection[]): { injection
454
455
  for (const injection of injections) {
455
456
  if (!injection.manual) {
456
457
  const previousCount = aiInjectionSidsCount[injection.sid] || 0
458
+ const uniqueLimit = getConfigValue('unique_injection_count_limit')
459
+ const totalLimit = getConfigValue('total_participant_injection_count_limit')
457
460
 
458
- const exceedsUniqueCount =
459
- window.PlayPilotLinkInjections?.config?.unique_injection_count_limit &&
460
- previousCount >= window.PlayPilotLinkInjections?.config?.unique_injection_count_limit
461
+ const exceedsUniqueCount = uniqueLimit && previousCount >= uniqueLimit
461
462
 
462
- const exceedsTotalParticipantsCount =
463
- injection.type === 'participant' &&
464
- window.PlayPilotLinkInjections?.config?.total_participant_injection_count_limit &&
465
- aiParticipantInjectionsCount >= window.PlayPilotLinkInjections?.config?.total_participant_injection_count_limit
463
+ const exceedsTotalParticipantsCount = injection.type === 'participant' && totalLimit && aiParticipantInjectionsCount >= totalLimit
466
464
 
467
465
  if (exceedsUniqueCount || exceedsTotalParticipantsCount) {
468
466
  failedMessages[injection.key] = `Injection was withheld because it exceeded the maximum ${exceedsUniqueCount ? 'unique' : 'total'} count.`
@@ -521,9 +519,9 @@ export function getPlayPilotWrapperElement(): Element {
521
519
  export function doesParticipantMeetThreshold(injections: LinkInjection[], participant: ParticipantData): boolean {
522
520
  if (participant.popularity === null || participant.popularity === undefined) return true
523
521
 
524
- const useArticleAverage = window.PlayPilotLinkInjections?.config?.participant_injection_popularity_threshold_use_article_average ?? true
522
+ const useArticleAverage = getConfigValue('participant_injection_popularity_threshold_use_article_average') ?? true
525
523
  const defaultThreshold = 0
526
- const configThreshold = window.PlayPilotLinkInjections?.config?.participant_injection_popularity_threshold
524
+ const configThreshold = getConfigValue('participant_injection_popularity_threshold')
527
525
  const threshold = configThreshold ?? defaultThreshold
528
526
 
529
527
  if (threshold === 0) return true
@@ -1,9 +1,10 @@
1
1
  import { RETARGETING_USER_ID_KEY } from '@playpilot/retargeting-tracking'
2
2
  import { hasConsentedTo } from './consent'
3
3
  import { getUserId } from './user'
4
+ import { getConfigValue } from './api/config'
4
5
 
5
6
  export function isRetargetingAllowed(): boolean {
6
- if (!window.PlayPilotLinkInjections.config?.allow_retargeting_pixels) return false
7
+ if (!getConfigValue('allow_retargeting_pixels')) return false
7
8
 
8
9
  if (!hasConsentedTo('pixels')) return false
9
10
 
package/src/lib/routes.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { getConfigValue } from './api/config'
1
2
  import { playPilotBaseUrl } from './constants'
2
3
  import type { ParticipantData } from './types/participant'
3
4
  import type { TitleData } from './types/title'
@@ -11,5 +12,5 @@ export function participantUrl(participant: ParticipantData): string {
11
12
  }
12
13
 
13
14
  export function exploreModalUrl(sid: string): string {
14
- return window.PlayPilotLinkInjections?.config?.explore_navigation_path + `?route=modal&sid=${sid}`
15
+ return getConfigValue('explore_navigation_path') + `?route=modal&sid=${sid}`
15
16
  }
package/src/lib/user.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { getConfigValue } from './api/config'
1
2
  import { hasConsentedTo } from './consent'
2
3
  import { generateRandomHash } from './hash'
3
4
 
@@ -33,5 +34,5 @@ export function getSessionId(): string | null {
33
34
  }
34
35
 
35
36
  export function isUserTrackingAllowed(): boolean {
36
- return !!window.PlayPilotLinkInjections?.config?.allow_user_id_tracking && hasConsentedTo('tracking')
37
+ return !!getConfigValue('allow_user_id_tracking') && hasConsentedTo('tracking')
37
38
  }
@@ -7,7 +7,7 @@
7
7
  import { isCrawler } from '$lib/crawler'
8
8
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
9
9
  import { fetchAds } from '$lib/api/ads'
10
- import { fetchConfig } from '$lib/api/config'
10
+ import { fetchConfig, getConfigValue } from '$lib/api/config'
11
11
  import { insertExplore, insertExploreIntoNavigation } from '$lib/explore'
12
12
  import { authorize, getAuthToken, isEditorialModeEnabled, removeAuthCookie, setEditorialParamInUrl } from '$lib/api/auth'
13
13
  import { getPageTextAndElements } from '$lib/injectionElements'
@@ -55,7 +55,7 @@
55
55
  fireQueuedTrackingEvents()
56
56
  track(TrackingEvent.ArticlePageView)
57
57
 
58
- const explorePath = window.PlayPilotLinkInjections.config?.explore_navigation_path
58
+ const explorePath = getConfigValue('explore_navigation_path')
59
59
 
60
60
  if ((!aiInjections.length && !manualInjections.length) && !(explorePath && document.location.href.includes(explorePath))) return
61
61
 
@@ -102,7 +102,7 @@
102
102
  loading = false
103
103
 
104
104
  if (!response) return
105
- if (window.PlayPilotLinkInjections.config?.disable_public_injections && !(isEditorialMode && authorized)) return
105
+ if (getConfigValue('disable_public_injections') && !(isEditorialMode && authorized)) return
106
106
 
107
107
  setTrackingSids({ organizationSid: response.organization_sid, domainSid: response.domain_sid })
108
108
 
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { getConfigValue } from '$lib/api/config'
2
3
  import { fetchLinkInjections } from '$lib/api/externalPages'
3
4
  import { Language } from '$lib/enums/Language'
4
5
  import { SplitTest } from '$lib/enums/SplitTest'
@@ -131,7 +132,7 @@
131
132
 
132
133
  <hr />
133
134
 
134
- {#if !!(window.PlayPilotLinkInjections.config?.exclude_urls_pattern && getFullUrlPath().match(window.PlayPilotLinkInjections?.config?.exclude_urls_pattern))}
135
+ {#if !!(getConfigValue('exclude_urls_pattern') && getFullUrlPath().match(getConfigValue('exclude_urls_pattern')!))}
135
136
  <span class="error">The current URL is excluded via the config</span>
136
137
  <hr />
137
138
  {/if}
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">
2
+ import { getConfigValue } from '$lib/api/config'
2
3
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
3
4
  import { track } from '$lib/tracking'
4
5
  import IconArrow from '../Icons/IconArrow.svelte'
5
6
 
6
7
  const src = 'https://cdn.jsdelivr.net/npm/@playpilot/tpi@latest/src/lib/images/titles-list.webp'
7
- const href = window.PlayPilotLinkInjections?.config?.explore_navigation_path
8
+ const href = getConfigValue('explore_navigation_path')
8
9
  </script>
9
10
 
10
11
  <a class="call-to-action" {href} onclick={() => track(TrackingEvent.CardToExploreCta)}>
@@ -6,6 +6,7 @@
6
6
  import { exploreParentSelector } from '$lib/explore'
7
7
  import { onMount, setContext } from 'svelte'
8
8
  import { isRetargetingAllowed } from '$lib/retargeting'
9
+ import { getConfigValue } from '$lib/api/config'
9
10
  import { trackViaPixel } from '@playpilot/retargeting-tracking'
10
11
  import Modal from './Modal.svelte'
11
12
  import Title from '../Title.svelte'
@@ -24,7 +25,7 @@
24
25
 
25
26
  const topScrollAd = getFirstAdOfType('top_scroll')
26
27
  const displayAd = getFirstAdOfType('card')
27
- const insertExploreCta = window.PlayPilotLinkInjections?.config?.explore_insert_cta_in_tpi
28
+ const insertExploreCta = getConfigValue('explore_insert_cta_in_tpi')
28
29
  const useBubble = !!topScrollAd || (insertExploreCta && !document.querySelector(exploreParentSelector))
29
30
 
30
31
  let hasTrackedScrolling = false
@@ -8,6 +8,7 @@
8
8
  import { trackClickViaPixel, trackViewViaPixel } from '@playpilot/retargeting-tracking'
9
9
  import { MetaEvent, MetaSource } from '$lib/enums/TrackingEvent'
10
10
  import { isRetargetingAllowed } from '$lib/retargeting'
11
+ import { getConfigValue } from '$lib/api/config'
11
12
 
12
13
  interface Props {
13
14
  playlink: PlaylinkData
@@ -36,7 +37,7 @@
36
37
  <!-- svelte-ignore a11y_no_static_element_interactions -->
37
38
  <svelte:element
38
39
  {onclick}
39
- this={!window.PlayPilotLinkInjections?.config?.require_affiliate_consent || hasConsentedTo('affiliate') ? 'a' : 'span'}
40
+ this={!getConfigValue('require_affiliate_consent') || hasConsentedTo('affiliate') ? 'a' : 'span'}
40
41
  {@attach usePixel ? trackViewViaPixel(MetaEvent.ProviderInterest, { provider: playlink.slug, source: MetaSource.Card }) : null}
41
42
  {@attach usePixel ? trackClickViaPixel(MetaEvent.ProviderClick, { provider: playlink.slug }) : null}
42
43
  href={url}
@@ -11,6 +11,7 @@
11
11
  import Playlink from './Playlink.svelte'
12
12
  import Button from '../Button.svelte'
13
13
  import PlaylinksDisclaimer from './PlaylinksDisclaimer.svelte'
14
+ import { getConfigValue } from '$lib/api/config'
14
15
 
15
16
  type Category = PlaylinkCategory | '' | 'Other'
16
17
  type CategorizedPlaylinks = Partial<Record<Category, PlaylinkData[]>>
@@ -27,7 +28,7 @@
27
28
  const isModal = getContext('scope') === 'modal'
28
29
  const type = getContext('type')
29
30
  const displayAd = getFirstAdOfType('card')
30
- const categorize = !!window.PlayPilotLinkInjections?.config?.categorize_playlinks
31
+ const categorize = !!getConfigValue('categorize_playlinks')
31
32
 
32
33
  let outerWidth = $state(0)
33
34
  let limited = $state(!categorize)
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { getConfigValue } from '$lib/api/config'
2
3
  import { mobileBreakpoint } from '$lib/constants'
3
4
  import { onDestroy } from 'svelte'
4
5
  import { SvelteSet } from 'svelte/reactivity'
@@ -17,7 +18,7 @@
17
18
  onDestroy(destroyAllPosters)
18
19
 
19
20
  function onscroll(): void {
20
- if (window.PlayPilotLinkInjections?.config?.disable_scroll_reveal_posters) return
21
+ if (getConfigValue('disable_scroll_reveal_posters')) return
21
22
  if (!isMobile) return
22
23
 
23
24
  setScrollTimeout()
@@ -11,6 +11,7 @@
11
11
  import ParticipantImage from '../Participants/ParticipantImage.svelte'
12
12
  import Rail from './Rail.svelte'
13
13
  import { exploreModalUrl } from '$lib/routes'
14
+ import { getConfigValue } from '$lib/api/config'
14
15
 
15
16
  interface Props {
16
17
  title: TitleData
@@ -45,7 +46,7 @@
45
46
  async function onclick(event: MouseEvent, participant: ParticipantData): Promise<void> {
46
47
  track(TrackingEvent.ParticipantClick, null, { title_source: title.original_title || title.title, participant: participant.name })
47
48
 
48
- if (!window.PlayPilotLinkInjections?.config?.open_tpi_links_in_explore || window.location.href.includes(window.PlayPilotLinkInjections.config.explore_navigation_path || '')) {
49
+ if (!getConfigValue('open_tpi_links_in_explore') || window.location.href.includes(getConfigValue('explore_navigation_path') || '')) {
49
50
  const fetchedParticipant = await fetchParticipantBySid(participant.sid)
50
51
 
51
52
  openModal({ event, type: 'participant', data: fetchedParticipant })
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { getConfigValue } from '$lib/api/config'
2
3
  import { TrackingEvent } from '$lib/enums/TrackingEvent'
3
4
  import { t } from '$lib/localization'
4
5
  import { track } from '$lib/tracking'
@@ -38,7 +39,7 @@
38
39
  <TitlesRail
39
40
  {titles}
40
41
  {heading}
41
- navigateToExplore={!!window.PlayPilotLinkInjections?.config?.open_tpi_links_in_explore}
42
+ navigateToExplore={!!getConfigValue('open_tpi_links_in_explore')}
42
43
  onclick={(title) => track(TrackingEvent.WidgetArticleRailTitleClick, title)} />
43
44
  </div>
44
45
  {/if}
@@ -19,9 +19,14 @@ vi.mock('$lib/api/externalPages', () => ({
19
19
  pollLinkInjections: vi.fn(() => {}),
20
20
  }))
21
21
 
22
- vi.mock('$lib/api/config', () => ({
23
- fetchConfig: vi.fn(),
24
- }))
22
+ // @ts-ignore
23
+ vi.mock(import('$lib/api/config'), async (importOriginal) => {
24
+ const actual = await importOriginal()
25
+ return {
26
+ ...actual,
27
+ fetchConfig: vi.fn(() => {}),
28
+ }
29
+ })
25
30
 
26
31
  // @ts-ignore
27
32
  vi.mock(import('$lib/api/session'), async (importOriginal) => {