1// Copyright 2023-present 650 Industries (Expo). All rights reserved. 2import { getPackageJson } from '@expo/config'; 3import { resolveEntryPoint } from '@expo/config/paths'; 4import chalk from 'chalk'; 5import path from 'path'; 6 7import { getServerRoot } from './getModulesPaths'; 8 9const debug = require('debug')('expo:metro:config:rewriteRequestUrl'); 10 11export function getRewriteRequestUrl(projectRoot: string) { 12 function rewriteExpoRequestUrl(url: string): string { 13 // Like: `/.expo/.virtual-metro-entry.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.bacon.test-custom-entry` 14 // Sometimes a fully qualified URL is passed in, e.g. `http://localhost:19001/.expo/.virtual-metro-entry.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.bacon.test-custom-entry` 15 if (url.includes('/.expo/.virtual-metro-entry.bundle?')) { 16 const ensured = url.startsWith('/') ? new URL(url, 'https://acme.dev') : new URL(url); 17 // TODO: Maybe this function could be memoized in some capacity? 18 const { search, searchParams } = ensured; 19 20 const platform = searchParams.get('platform') ?? 'web'; 21 22 debug('Rewriting magic request url to entry point', { url, platform }); 23 24 const entry = resolveEntryPoint(projectRoot, { 25 platform, 26 // @ts-ignore 27 projectConfig: { 28 pkg: getPackageJson(projectRoot), 29 }, 30 }); 31 32 if (!entry) { 33 throw new Error( 34 chalk`The project entry file could not be resolved (platform: ${platform}, root: ${projectRoot}). Define it in the {bold package.json} "main" field.` 35 ); 36 } 37 38 const serverRoot = getServerRoot(projectRoot); 39 const relativeEntry = path.relative(serverRoot, entry).replace(/\.[tj]sx?$/, ''); 40 debug('Resolved entry point', { entry, relativeEntry, serverRoot }); 41 42 // Like: `/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.bacon.test-custom-entry` 43 return '/' + relativeEntry + '.bundle' + search; 44 } 45 46 return url; 47 } 48 return rewriteExpoRequestUrl; 49} 50