1'use strict' 2 3const promisify = require('./util.js').promisify 4 5const path = require('path') 6const statAsync = promisify(require('fs').stat) 7 8module.exports = getPrefix 9function getPrefix (root) { 10 const original = root = path.resolve(root) 11 while (path.basename(root) === 'node_modules') { 12 root = path.dirname(root) 13 } 14 if (original !== root) { 15 return Promise.resolve(root) 16 } else { 17 return Promise.resolve(getPrefixFromTree(root)) 18 } 19} 20 21function getPrefixFromTree (current) { 22 if (isRootPath(current, process.platform)) { 23 return false 24 } else { 25 return Promise.all([ 26 fileExists(path.join(current, 'package.json')), 27 fileExists(path.join(current, 'node_modules')) 28 ]).then(args => { 29 const hasPkg = args[0] 30 const hasModules = args[1] 31 if (hasPkg || hasModules) { 32 return current 33 } else { 34 return getPrefixFromTree(path.dirname(current)) 35 } 36 }) 37 } 38} 39 40module.exports._fileExists = fileExists 41function fileExists (f) { 42 return statAsync(f).catch(err => { 43 if (err.code !== 'ENOENT') { 44 throw err 45 } 46 }) 47} 48 49module.exports._isRootPath = isRootPath 50function isRootPath (p, platform) { 51 return platform === 'win32' 52 ? p.match(/^[a-z]+:[/\\]?$/i) 53 : p === '/' 54} 55