|
| 1 | +const fs = require('fs') |
| 2 | +const path = require('path') |
| 3 | +const { promisify } = require('util') |
| 4 | + |
| 5 | +exports.access = promisify(fs.access) |
| 6 | +exports.lstat = promisify(fs.lstat) |
| 7 | +exports.mkdir = promisify(fs.mkdir) |
| 8 | +exports.readDir = promisify(fs.readdir) |
| 9 | +exports.readFile = promisify(fs.readFile) |
| 10 | +exports.stat = promisify(fs.stat) |
| 11 | +exports.writeFile = promisify(fs.writeFile) |
| 12 | + |
| 13 | +/** |
| 14 | + * Finds and returns the path to an upwards file by traversing parent directories |
| 15 | + * until either the file exists or the directory is in the root of the filesystem. |
| 16 | + * |
| 17 | + * @param filename Name of file to look for |
| 18 | + * @param directory (Optional) Directory to start looking in. |
| 19 | + * @returns {string|false} Absolute path to the file. |
| 20 | + */ |
| 21 | +exports.findUpwardsFile = async (filename, directory = process.cwd()) => { |
| 22 | + const parsedPath = path.parse(path.join(directory, filename)) |
| 23 | + const targetFile = path.join(parsedPath.dir, parsedPath.base) |
| 24 | + let fileExists = false |
| 25 | + try { |
| 26 | + await this.access(targetFile) |
| 27 | + fileExists = true |
| 28 | + } catch (err) { |
| 29 | + if (err.code !== 'ENOENT') throw err |
| 30 | + } |
| 31 | + if (fileExists) { |
| 32 | + // yay! |
| 33 | + return targetFile |
| 34 | + } else { |
| 35 | + if (parsedPath.dir === parsedPath.root) { |
| 36 | + // We're at the root of the filesystem. There's nowhere else to look. |
| 37 | + return false |
| 38 | + } else { |
| 39 | + // Keep digging |
| 40 | + return this.findUpwardsFile(filename, path.dirname(directory)) |
| 41 | + } |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +/** |
| 46 | + * Retrieve all filenames in a directory, excluding subdirectories. |
| 47 | + * |
| 48 | + * @param directoryPath |
| 49 | + * @return {string[]} Filenames |
| 50 | + */ |
| 51 | +exports.listDirectoryFiles = async (directoryPath) => { |
| 52 | + // Note: withFileTypes requires Node 10+ |
| 53 | + const dirItems = await this.readDir(directoryPath, { withFileTypes: true }) |
| 54 | + |
| 55 | + return dirItems |
| 56 | + .filter(item => !item.isDirectory()) |
| 57 | + .map(item => item.name) |
| 58 | +} |
0 commit comments