UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

141 lines (117 loc) 4.16 kB
export function parsePathAndParamsFromExpoGoLink(url: string): { pathname: string queryString: string } { // If the URL is defined (default in Expo Go dev apps) and the URL has no path: // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/` const href = parsePathFromExpoGoLink(url) const results = href.match(/([^?]*)(\?.*)?/) return { pathname: results?.[1] ?? '', queryString: results?.[2] ?? '', } } export function parsePathFromExpoGoLink(url: string): string { // If the URL is defined (default in Expo Go dev apps) and the URL has no path: // `exp://192.168.87.39:19000/` then use the default `exp://192.168.87.39:19000/--/` return url.match(/exps?:\/\/.*?\/--\/(.*)/)?.[1] ?? '' } // This is only run on native. function extractExactPathFromURL(url: string): string { if ( // If a universal link / app link / web URL is used, we should use the path // from the URL, while stripping the origin. url.match(/^https?:\/\//) ) { const { origin, href, hostname } = new URL(url) if (hostname === 'exp.host' || hostname === 'u.expo.dev') { // These are QR code generate deep-link that always like to the '/' path // TODO: In the future, QR code may link to a specific path and this logic will need to be udpated return '' } return href.replace(origin, '') } const isExpoGo = typeof expo !== 'undefined' && globalThis.expo?.modules?.ExpoGo // Handle special URLs used in Expo Go: `/--/pathname` -> `pathname` if ( isExpoGo && // while not exhaustive, `exp` and `exps` are the only two schemes which // are passed through to other apps in Expo Go. url.match(/^exp(s)?:\/\//) ) { const pathname = parsePathFromExpoGoLink(url) if (pathname) { return fromDeepLink('a://' + pathname) } // Match the `?.*` segment of the URL. const queryParams = url.match(/exps?:\/\/.*\?(.*)/)?.[1] if (queryParams) { return fromDeepLink('a://?' + queryParams) } return '' } // TODO: Support dev client URLs return fromDeepLink(url) } /** Major hack to support the makeshift expo-development-client system. */ function isExpoDevelopmentClient(url: URL): boolean { return url.hostname === 'expo-development-client' } function fromDeepLink(url: string): string { let res: URL | null try { // This is for all standard deep links, e.g. `foobar://` where everything // after the `://` is the path. res = new URL(url) } catch { /** * We failed to parse the URL. This can occur for a variety of reasons, including: * - Its a partial URL (e.g. `/route?query=param`). * - It has a valid App scheme, but the scheme isn't a valid URL scheme (e.g. `my_app://`) */ /** * App schemes are not valid URL schemes, so they will fail to parse. * We need to strip the scheme from these URLs */ return url.replace(/^[^:]+:\/\//, '') } if (isExpoDevelopmentClient(res)) { if (!res.searchParams.get('url')) { return '' } const incomingUrl = res.searchParams.get('url')! return extractExactPathFromURL(decodeURI(incomingUrl)) } let results = '' if (res.host) { results += res.host } if (res.pathname) { results += res.pathname } const qs = !res.search ? '' : // @ts-ignore: `entries` is not on `URLSearchParams` in some typechecks. [...res.searchParams.entries()] .map(([k, v]) => `${k}=${decodeURIComponent(v)}`) .join('&') if (qs) { results += '?' + qs } return results } export function extractExpoPathFromURL(_prefixes: string[], url = '') { return ( extractExactPathFromURL(url) // TODO: We should get rid of this, dropping specificities is not good .replace(/^\//, '') ) } export function adjustPathname(url: { hostname?: string | null; pathname: string }) { if (url.hostname === 'exp.host' || url.hostname === 'u.expo.dev') { // drop the first two segments from pathname: return url.pathname.split('/').slice(2).join('/') } return url.pathname } export const extractPathFromURL = extractExpoPathFromURL