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  };