index.js
1 'use strict'; 2 const path = require('path'); 3 const fs = require('fs'); 4 const {promisify} = require('util'); 5 const pLocate = require('p-locate'); 6 7 const fsStat = promisify(fs.stat); 8 const fsLStat = promisify(fs.lstat); 9 10 const typeMappings = { 11 directory: 'isDirectory', 12 file: 'isFile' 13 }; 14 15 function checkType({type}) { 16 if (type in typeMappings) { 17 return; 18 } 19 20 throw new Error(`Invalid type specified: ${type}`); 21 } 22 23 const matchType = (type, stat) => type === undefined || stat[typeMappings[type]](); 24 25 module.exports = async (paths, options) => { 26 options = { 27 cwd: process.cwd(), 28 type: 'file', 29 allowSymlinks: true, 30 ...options 31 }; 32 checkType(options); 33 const statFn = options.allowSymlinks ? fsStat : fsLStat; 34 35 return pLocate(paths, async path_ => { 36 try { 37 const stat = await statFn(path.resolve(options.cwd, path_)); 38 return matchType(options.type, stat); 39 } catch (_) { 40 return false; 41 } 42 }, options); 43 }; 44 45 module.exports.sync = (paths, options) => { 46 options = { 47 cwd: process.cwd(), 48 allowSymlinks: true, 49 type: 'file', 50 ...options 51 }; 52 checkType(options); 53 const statFn = options.allowSymlinks ? fs.statSync : fs.lstatSync; 54 55 for (const path_ of paths) { 56 try { 57 const stat = statFn(path.resolve(options.cwd, path_)); 58 59 if (matchType(options.type, stat)) { 60 return path_; 61 } 62 } catch (_) { 63 } 64 } 65 };