Home Reference Source

src/private/fs-util.js

import {isDirectoryAsync, readdirAsync, statAsync} from 'fs-extra-promise'
import {join} from 'path'

/** Whether the file exists. */
export async function exists(path) {
	return (await fileKind(path)) !== 'none'
}

/** Whether the path is a directory, file, or does not exist. */
export async function fileKind(filename) {
	try {
		const stats = await statAsync(filename)
		return stats.isDirectory() ? 'directory' : 'file'
	} catch (err) {
		if (!err.message.startsWith('ENOENT'))
			throw err
		return 'none'
	}
}

/**
Calls `traverseDir` on every directory and `traverseFile` on every file.
Avoids a file or directory (and all files in it) when `filter(path)` returns false.
*/
export function traverseTree(dirPath, {filter, traverseDir, traverseFile}) {
	async function recur(relDir) {
		const fullDirPath = join(dirPath, relDir)
		const contents = await readdirAsync(fullDirPath)
		const usedContents = filter === undefined ? contents : contents.filter(filter)
		return await Promise.all(usedContents.map(async function(name) {
			const fullPath = join(fullDirPath, name)
			const relPath = join(relDir, name)
			if (await isDirectoryAsync(fullPath))
				await Promise.all([traverseDir(relPath), recur(relPath)])
			else
				await traverseFile(relPath)
		}))
	}
	return recur('')
}