You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.3 KiB
65 lines
1.3 KiB
'use strict'; |
|
const path = require('path'); |
|
const fs = require('fs'); |
|
const {promisify} = require('util'); |
|
const pLocate = require('p-locate'); |
|
|
|
const fsStat = promisify(fs.stat); |
|
const fsLStat = promisify(fs.lstat); |
|
|
|
const typeMappings = { |
|
directory: 'isDirectory', |
|
file: 'isFile' |
|
}; |
|
|
|
function checkType({type}) { |
|
if (type in typeMappings) { |
|
return; |
|
} |
|
|
|
throw new Error(`Invalid type specified: ${type}`); |
|
} |
|
|
|
const matchType = (type, stat) => type === undefined || stat[typeMappings[type]](); |
|
|
|
module.exports = async (paths, options) => { |
|
options = { |
|
cwd: process.cwd(), |
|
type: 'file', |
|
allowSymlinks: true, |
|
...options |
|
}; |
|
checkType(options); |
|
const statFn = options.allowSymlinks ? fsStat : fsLStat; |
|
|
|
return pLocate(paths, async path_ => { |
|
try { |
|
const stat = await statFn(path.resolve(options.cwd, path_)); |
|
return matchType(options.type, stat); |
|
} catch (_) { |
|
return false; |
|
} |
|
}, options); |
|
}; |
|
|
|
module.exports.sync = (paths, options) => { |
|
options = { |
|
cwd: process.cwd(), |
|
allowSymlinks: true, |
|
type: 'file', |
|
...options |
|
}; |
|
checkType(options); |
|
const statFn = options.allowSymlinks ? fs.statSync : fs.lstatSync; |
|
|
|
for (const path_ of paths) { |
|
try { |
|
const stat = statFn(path.resolve(options.cwd, path_)); |
|
|
|
if (matchType(options.type, stat)) { |
|
return path_; |
|
} |
|
} catch (_) { |
|
} |
|
} |
|
};
|
|
|