this repo has no description
at main 177 lines 5.0 kB view raw
1import type { 2 ArticlePage, 3 ChartsHubPage, 4 GenericPage, 5 SearchLandingPage, 6 SearchResultsPage, 7 ShelfBasedProductPage, 8 TopChartsPage, 9 TodayPage, 10 SeeAllPage, 11} from '@jet-app/app-store/api/models'; 12import { StaticMessagePage } from '~/jet/models/static-message-page'; 13import { isObject } from '~/utils/types'; 14import { ErrorPage } from './error-page'; 15import type { WebRenderablePage } from 'node_modules/@jet-app/app-store/src/api/models/web-renderable-page'; 16 17/** 18 * The union of every type of page that the App Store Onyx app can render 19 */ 20export type Page = ( 21 | ArticlePage 22 | ChartsHubPage 23 | GenericPage 24 | SearchLandingPage 25 | SearchResultsPage 26 | ShelfBasedProductPage 27 | StaticMessagePage 28 | TopChartsPage 29 | TodayPage 30 | ErrorPage 31) & 32 // TS needs to be told this explicitly, even though all the above implement this 33 WebRenderablePage; 34 35/** 36 * Detects if {@linkcode page} is actually an {@linkcode AppEventDetailPage} 37 */ 38export function isAppEventDetailPage(page: Page): page is GenericPage { 39 return ( 40 'shelves' in page && 41 page.shelves.some(({ contentType }) => contentType === 'appEventDetail') 42 ); 43} 44 45/** 46 * Detects if {@linkcode page} is actually an {@linkcode ArticlePage} 47 */ 48export function isArticlePage(page: Page): page is ArticlePage { 49 return 'card' in page && 'shelves' in page; 50} 51 52/** 53 * Detects if {@linkcode page} is actually a {@linkcode ChartsHubPage} 54 */ 55export function isChartsHubPage(page: Page): page is ChartsHubPage { 56 return 'charts' in page; 57} 58 59/** 60 * Detects if {@linkcode page} is actually a {@linkcode GenericPage} 61 */ 62export function isGenericPage(page: Page): page is GenericPage { 63 return 'shelves' in page; 64} 65 66/** 67 * Detects if {@linkcode page} is actually a {@linkcode ShelfBasedProductPage} 68 */ 69export function isShelfBasedProductPage( 70 page: Page, 71): page is ShelfBasedProductPage { 72 return 'shelfMapping' in page && !('seeAllType' in page); 73} 74 75/** 76 * Detects if {@linkcode page} is actually a {@linkcode SeeAllPage} 77 */ 78export function isSeeAllPage(page: Page): page is SeeAllPage { 79 return 'seeAllType' in page; 80} 81 82/** 83 * Detects if {@linkcode page} is actually a {@linkcode SearchLandingPage} 84 */ 85export function isSearchLandingPage(page: Page): page is SearchLandingPage { 86 return 'adIncidents' in page; 87} 88 89/** 90 * Detects if {@linkcode page} is actually a {@linkcode SearchResultsPage} 91 */ 92export function isSearchResultsPage(page: Page): page is SearchResultsPage { 93 return 'searchClearAction' in page || 'searchCancelAction' in page; 94} 95 96/** 97 * Detects if {@linkcode page} is actually a {@linkcode TopChartsPage} 98 */ 99export function isTopChartsPage(page: Page): page is TopChartsPage { 100 return 'segments' in page && 'categories' in page; 101} 102 103/** 104 * Detects if {@linkcode page} is actually a {@linkcode TodayPage} 105 */ 106export function isTodayPage(page: Page): page is TodayPage { 107 return 'titleDetail' in page; 108} 109 110/** 111 * Detects if {@linkcode page} is actually a {@linkcode StaticMessagePage} 112 */ 113export function isStaticMessagePage( 114 page: GenericPage, 115): page is StaticMessagePage { 116 return 'pageType' in page && page.pageType === 'staticMessagePage'; 117} 118 119export function isErrorPage(page: GenericPage) { 120 return 'pageType' in page && page.pageType === 'errorPage'; 121} 122 123/** 124 * Type-guard that determines if the provided {@linkcode page} matches a renderable {@linkcode Page} definition 125 */ 126export function isPage(page: unknown): page is Page { 127 if (!isObject(page)) { 128 return false; 129 } 130 131 return [ 132 isAppEventDetailPage, 133 isArticlePage, 134 isChartsHubPage, 135 isGenericPage, 136 isShelfBasedProductPage, 137 isSearchLandingPage, 138 isSearchResultsPage, 139 isTopChartsPage, 140 isTodayPage, 141 isErrorPage, 142 isSeeAllPage, 143 ].some((specificPageTypePredicate) => 144 specificPageTypePredicate( 145 // This type-cast reflects the fact that we don't really know if `page` is really a `Page`, 146 // but that we're going to use the type-guards of our `Page` members to see if `page` looks 147 // like one of them 148 page as Page, 149 ), 150 ); 151} 152 153/** 154 * Type-assertion that determines if the provided {@linkcode page} matches a renderable {@linkcode Page} definition 155 */ 156export function assertIsPage(page: unknown): asserts page is Page { 157 if (!isPage(page)) { 158 throw new Error( 159 'The view-model for the dispatched `Intent` does not match a known renderable shape', 160 ); 161 } 162} 163 164/** 165 * Detects if {@linkcode page} has the Vision Pro pathname in it's URL. 166 */ 167export function hasVisionProUrl(page: GenericPage) { 168 if (!page.canonicalURL) { 169 return false; 170 } 171 172 const url = new URL(page.canonicalURL); 173 return ( 174 url.pathname.includes('/vision/apps-and-games') || 175 url.pathname.includes('/vision/arcade') 176 ); 177}