1'use strict' 2// try to find the most reasonable prefix to use 3 4module.exports = findPrefix 5 6const fs = require('fs') 7const path = require('path') 8 9function findPrefix (dir) { 10 return new Promise((resolve, reject) => { 11 dir = path.resolve(dir) 12 13 // this is a weird special case where an infinite recurse of 14 // node_modules folders resolves to the level that contains the 15 // very first node_modules folder 16 let walkedUp = false 17 while (path.basename(dir) === 'node_modules') { 18 dir = path.dirname(dir) 19 walkedUp = true 20 } 21 if (walkedUp) { 22 resolve(dir) 23 } else { 24 resolve(findPrefix_(dir)) 25 } 26 }) 27} 28 29function findPrefix_ (dir, original) { 30 if (!original) original = dir 31 32 const parent = path.dirname(dir) 33 // this is a platform independent way of checking if we're in the root 34 // directory 35 if (parent === dir) return Promise.resolve(original) 36 37 return new Promise((resolve, reject) => { 38 fs.readdir(dir, (err, files) => { 39 if (err) { 40 // an error right away is a bad sign. 41 // unless the prefix was simply a non 42 // existent directory. 43 if (err && dir === original && err.code !== 'ENOENT') { 44 reject(err) 45 } else { 46 resolve(original) 47 } 48 } else if (files.indexOf('node_modules') !== -1 || 49 files.indexOf('package.json') !== -1) { 50 resolve(dir) 51 } else { 52 resolve(findPrefix_(parent, original)) 53 } 54 }) 55 }) 56} 57