1// This MUST be first to ensure that `fetch` is defined in the React Native environment. 2import 'react-native/Libraries/Core/InitializeCore'; 3import Constants from 'expo-constants'; 4import URL from 'url-parse'; 5import getDevServer from '../getDevServer'; 6import { install, setLocationHref } from './Location'; 7let hasWarned = false; 8const manifest = Constants.expoConfig; 9// Add a development warning for fetch requests with relative paths 10// to ensure developers are aware of the need to configure a production 11// base URL in the Expo config (app.json) under `expo.extra.router.origin`. 12function warnProductionOriginNotConfigured(requestUrl) { 13 if (hasWarned) { 14 return; 15 } 16 hasWarned = true; 17 if (!manifest?.extra?.router?.origin) { 18 console.warn(`The relative fetch request "${requestUrl}" will not work in production until the Expo Router Config Plugin (app.json) is configured with the \`origin\` prop set to the base URL of your web server, e.g. \`{ plugins: [["expo-router", { origin: "..." }]] }\`. [Learn more](https://expo.github.io/router/docs/lab/runtime-location)`); 19 } 20} 21// TODO: This would be better if native and tied as close to the JS engine as possible, i.e. it should 22// reflect the exact location of the JS file that was executed. 23function getBaseUrl() { 24 if (process.env.NODE_ENV !== 'production') { 25 // e.g. http://localhost:19006 26 return getDevServer().url?.replace(/\/$/, ''); 27 } 28 // TODO: Make it official by moving out of `extra` 29 const productionBaseUrl = manifest?.extra?.router?.origin; 30 if (!productionBaseUrl) { 31 return null; 32 } 33 // Ensure no trailing slash 34 return productionBaseUrl?.replace(/\/$/, ''); 35} 36function wrapFetchWithWindowLocation(fetch) { 37 if (fetch.__EXPO_BASE_URL_POLYFILLED) { 38 return fetch; 39 } 40 const _fetch = (...props) => { 41 if (props[0] && typeof props[0] === 'string' && props[0].startsWith('/')) { 42 if (process.env.NODE_ENV !== 'production') { 43 warnProductionOriginNotConfigured(props[0]); 44 } 45 props[0] = new URL(props[0], window.location?.origin).toString(); 46 } 47 else if (props[0] && typeof props[0] === 'object') { 48 if (props[0].url && typeof props[0].url === 'string' && props[0].url.startsWith('/')) { 49 if (process.env.NODE_ENV !== 'production') { 50 warnProductionOriginNotConfigured(props[0]); 51 } 52 props[0].url = new URL(props[0].url, window.location?.origin).toString(); 53 } 54 } 55 return fetch(...props); 56 }; 57 _fetch.__EXPO_BASE_URL_POLYFILLED = true; 58 return _fetch; 59} 60if (manifest?.extra?.router?.origin !== false) { 61 // Polyfill window.location in native runtimes. 62 if (typeof window !== 'undefined' && !window.location) { 63 const url = getBaseUrl(); 64 if (url) { 65 setLocationHref(url); 66 install(); 67 } 68 } 69 // Polyfill native fetch to support relative URLs 70 Object.defineProperty(global, 'fetch', { 71 value: wrapFetchWithWindowLocation(fetch), 72 }); 73} 74//# sourceMappingURL=install.native.js.map