78 lines
1.5 KiB
JavaScript
78 lines
1.5 KiB
JavaScript
|
import process from 'node:process';
|
||
|
import path from 'node:path';
|
||
|
import fs, {promises as fsPromises} from 'node:fs';
|
||
|
import {fileURLToPath} from 'node:url';
|
||
|
import pLocate from 'p-locate';
|
||
|
|
||
|
const typeMappings = {
|
||
|
directory: 'isDirectory',
|
||
|
file: 'isFile',
|
||
|
};
|
||
|
|
||
|
function checkType(type) {
|
||
|
if (Object.hasOwnProperty.call(typeMappings, type)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
throw new Error(`Invalid type specified: ${type}`);
|
||
|
}
|
||
|
|
||
|
const matchType = (type, stat) => stat[typeMappings[type]]();
|
||
|
|
||
|
const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
|
||
|
|
||
|
export async function locatePath(
|
||
|
paths,
|
||
|
{
|
||
|
cwd = process.cwd(),
|
||
|
type = 'file',
|
||
|
allowSymlinks = true,
|
||
|
concurrency,
|
||
|
preserveOrder,
|
||
|
} = {},
|
||
|
) {
|
||
|
checkType(type);
|
||
|
cwd = toPath(cwd);
|
||
|
|
||
|
const statFunction = allowSymlinks ? fsPromises.stat : fsPromises.lstat;
|
||
|
|
||
|
return pLocate(paths, async path_ => {
|
||
|
try {
|
||
|
const stat = await statFunction(path.resolve(cwd, path_));
|
||
|
return matchType(type, stat);
|
||
|
} catch {
|
||
|
return false;
|
||
|
}
|
||
|
}, {concurrency, preserveOrder});
|
||
|
}
|
||
|
|
||
|
export function locatePathSync(
|
||
|
paths,
|
||
|
{
|
||
|
cwd = process.cwd(),
|
||
|
type = 'file',
|
||
|
allowSymlinks = true,
|
||
|
} = {},
|
||
|
) {
|
||
|
checkType(type);
|
||
|
cwd = toPath(cwd);
|
||
|
|
||
|
const statFunction = allowSymlinks ? fs.statSync : fs.lstatSync;
|
||
|
|
||
|
for (const path_ of paths) {
|
||
|
try {
|
||
|
const stat = statFunction(path.resolve(cwd, path_), {
|
||
|
throwIfNoEntry: false,
|
||
|
});
|
||
|
|
||
|
if (!stat) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (matchType(type, stat)) {
|
||
|
return path_;
|
||
|
}
|
||
|
} catch {}
|
||
|
}
|
||
|
}
|