index.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import process from 'node:process';
  2. import path from 'node:path';
  3. import fs, {promises as fsPromises} from 'node:fs';
  4. import {fileURLToPath} from 'node:url';
  5. import pLocate from 'p-locate';
  6. const typeMappings = {
  7. directory: 'isDirectory',
  8. file: 'isFile',
  9. };
  10. function checkType(type) {
  11. if (Object.hasOwnProperty.call(typeMappings, type)) {
  12. return;
  13. }
  14. throw new Error(`Invalid type specified: ${type}`);
  15. }
  16. const matchType = (type, stat) => stat[typeMappings[type]]();
  17. const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
  18. export async function locatePath(
  19. paths,
  20. {
  21. cwd = process.cwd(),
  22. type = 'file',
  23. allowSymlinks = true,
  24. concurrency,
  25. preserveOrder,
  26. } = {},
  27. ) {
  28. checkType(type);
  29. cwd = toPath(cwd);
  30. const statFunction = allowSymlinks ? fsPromises.stat : fsPromises.lstat;
  31. return pLocate(paths, async path_ => {
  32. try {
  33. const stat = await statFunction(path.resolve(cwd, path_));
  34. return matchType(type, stat);
  35. } catch {
  36. return false;
  37. }
  38. }, {concurrency, preserveOrder});
  39. }
  40. export function locatePathSync(
  41. paths,
  42. {
  43. cwd = process.cwd(),
  44. type = 'file',
  45. allowSymlinks = true,
  46. } = {},
  47. ) {
  48. checkType(type);
  49. cwd = toPath(cwd);
  50. const statFunction = allowSymlinks ? fs.statSync : fs.lstatSync;
  51. for (const path_ of paths) {
  52. try {
  53. const stat = statFunction(path.resolve(cwd, path_), {
  54. throwIfNoEntry: false,
  55. });
  56. if (!stat) {
  57. continue;
  58. }
  59. if (matchType(type, stat)) {
  60. return path_;
  61. }
  62. } catch {}
  63. }
  64. }