1*8d307f52SEvan Baconimport path from 'path'; 2*8d307f52SEvan Baconimport resolveFrom from 'resolve-from'; 3*8d307f52SEvan Bacon 4*8d307f52SEvan Bacon/** 5*8d307f52SEvan Bacon * Return true if the parent folder for a given file path is named "node_modules". 6*8d307f52SEvan Bacon * 7*8d307f52SEvan Bacon * @example 8*8d307f52SEvan Bacon * isModuleRootPathInNodeModulesFolder('./foo/expo') -> false 9*8d307f52SEvan Bacon * isModuleRootPathInNodeModulesFolder('./node_modules/expo') -> true 10*8d307f52SEvan Bacon */ 11*8d307f52SEvan Baconfunction isModuleRootPathInNodeModulesFolder(moduleRootPath: string): boolean { 12*8d307f52SEvan Bacon const parentFolderName = path.basename(path.dirname(moduleRootPath)); 13*8d307f52SEvan Bacon return parentFolderName === 'node_modules'; 14*8d307f52SEvan Bacon} 15*8d307f52SEvan Bacon 16*8d307f52SEvan Bacon/** 17*8d307f52SEvan Bacon * Given a node module name, and a project path, this method will: 18*8d307f52SEvan Bacon * 19*8d307f52SEvan Bacon * 1. Resolve the module path. 20*8d307f52SEvan Bacon * 2. Find the module root folder. 21*8d307f52SEvan Bacon * 3. Return true if the module root folder is in a folder named `node_modules` 22*8d307f52SEvan Bacon * 23*8d307f52SEvan Bacon * @param projectRoot 24*8d307f52SEvan Bacon * @param moduleId 25*8d307f52SEvan Bacon * 26*8d307f52SEvan Bacon * @example 27*8d307f52SEvan Bacon * isModuleSymlinked('./expo/apps/native-component-list', { 28*8d307f52SEvan Bacon * moduleId: 'react-native' 29*8d307f52SEvan Bacon * }) 30*8d307f52SEvan Bacon */ 31*8d307f52SEvan Baconexport function isModuleSymlinked( 32*8d307f52SEvan Bacon projectRoot: string, 33*8d307f52SEvan Bacon { 34*8d307f52SEvan Bacon moduleId, 35*8d307f52SEvan Bacon isSilent, 36*8d307f52SEvan Bacon }: { 37*8d307f52SEvan Bacon moduleId: string; 38*8d307f52SEvan Bacon isSilent?: boolean; 39*8d307f52SEvan Bacon } 40*8d307f52SEvan Bacon): boolean { 41*8d307f52SEvan Bacon try { 42*8d307f52SEvan Bacon const moduleRootPath = path.dirname(resolveFrom(projectRoot, `${moduleId}/package.json`)); 43*8d307f52SEvan Bacon return !isModuleRootPathInNodeModulesFolder(moduleRootPath); 44*8d307f52SEvan Bacon } catch (error) { 45*8d307f52SEvan Bacon if (!isSilent) { 46*8d307f52SEvan Bacon throw error; 47*8d307f52SEvan Bacon } 48*8d307f52SEvan Bacon // Failed to resolve the package.json relative to the project, not sure what to do here. 49*8d307f52SEvan Bacon // This is probably not possible due to node module resolution. 50*8d307f52SEvan Bacon return false; 51*8d307f52SEvan Bacon } 52*8d307f52SEvan Bacon} 53