diff --git a/lib/fs.js b/lib/fs.js index 93ac68d..70701fe 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -125,15 +125,6 @@ function ignoreExcludeFiles(arr, parent) { return ({ name }) => !set.has(join(parent, name)); } -function reduceFiles(result, item) { - if (Array.isArray(item)) { - return result.concat(item); - } - - result.push(item); - return result; -} - async function _readAndFilterDir(path, options) { const { ignoreHidden = true, ignorePattern } = options; return (await fsPromises.readdir(path, { ...options, withFileTypes: true })) @@ -148,19 +139,18 @@ function _readAndFilterDirSync(path, options) { .filter(ignoreFilesRegex(ignorePattern)); } -async function _copyDir(src, dest, options, parent) { - const entrys = await _readAndFilterDir(src, options); - return Promise.reduce(entrys.map(item => { +function _copyDirWalker(src, dest, results, parent, options) { + return Promise.map(_readAndFilterDir(src, options), item => { const childSrc = join(src, item.name); const childDest = join(dest, item.name); const currentPath = join(parent, item.name); if (item.isDirectory()) { - return _copyDir(childSrc, childDest, options, currentPath); + return _copyDirWalker(childSrc, childDest, results, currentPath, options); } - - return copyFile(childSrc, childDest).thenReturn(currentPath); - }), reduceFiles, []); + results.push(currentPath); + return copyFile(childSrc, childDest); + }); } function copyDir(src, dest, options = {}, callback) { @@ -172,20 +162,25 @@ function copyDir(src, dest, options = {}, callback) { options = {}; } - return checkParent(dest).then(() => _copyDir(src, dest, options, '')).asCallback(callback); + const results = []; + + return checkParent(dest).then(() => _copyDirWalker(src, dest, results, '', options)).return(results).asCallback(callback); } -async function _listDir(path, options, parent) { - const entrys = await _readAndFilterDir(path, options); - return Promise.reduce(entrys.map(item => { +async function _listDirWalker(path, results, parent, options) { + const promises = []; + + for (const item of await _readAndFilterDir(path, options)) { const currentPath = join(parent, item.name); if (item.isDirectory()) { - return _listDir(join(path, item.name), options, currentPath); + promises.push(_listDirWalker(join(path, item.name), results, currentPath, options)); + } else { + results.push(currentPath); } + } - return currentPath; - }), reduceFiles, []); + await Promise.all(promises); } function listDir(path, options = {}, callback) { @@ -196,25 +191,31 @@ function listDir(path, options = {}, callback) { options = {}; } - return Promise.resolve(_listDir(path, options, '')).asCallback(callback); + const results = []; + + return Promise.resolve(_listDirWalker(path, results, '', options)).return(results).asCallback(callback); } -function _listDirSync(path, options, parent) { - return _readAndFilterDirSync(path, options).map(item => { +function _listDirSyncWalker(path, results, parent, options) { + for (const item of _readAndFilterDirSync(path, options)) { const currentPath = join(parent, item.name); if (item.isDirectory()) { - return _listDirSync(join(path, item.name), options, currentPath); + _listDirSyncWalker(join(path, item.name), results, currentPath, options); + } else { + results.push(currentPath); } - - return currentPath; - }).reduce(reduceFiles, []); + } } function listDirSync(path, options = {}) { if (!path) throw new TypeError('path is required!'); - return _listDirSync(path, options, ''); + const results = []; + + _listDirSyncWalker(path, results, '', options); + + return results; } function escapeEOL(str) { @@ -266,22 +267,28 @@ function readFileSync(path, options = {}) { return content; } -async function _emptyDir(path, options, parent) { +async function _emptyDir(path, parent, options) { const entrys = (await _readAndFilterDir(path, options)) .filter(ignoreExcludeFiles(options.exclude, parent)); - return Promise.reduce(entrys.map(item => { + const results = []; + + await Promise.map(entrys, item => { const fullPath = join(path, item.name); const currentPath = join(parent, item.name); if (item.isDirectory()) { - return _emptyDir(fullPath, options, currentPath).then(files => { - if (!files.length) return fsPromises.rmdir(fullPath).then(() => files); - return files; + return _emptyDir(fullPath, currentPath, options).then(files => { + if (!files.length) { + return fsPromises.rmdir(fullPath); + } + results.push(...files); }); } + results.push(currentPath); + return fsPromises.unlink(fullPath); + }); - return fsPromises.unlink(fullPath).then(() => currentPath); - }), reduceFiles, []); + return results; } function emptyDir(path, options = {}, callback) { @@ -292,29 +299,34 @@ function emptyDir(path, options = {}, callback) { options = {}; } - return Promise.resolve(_emptyDir(path, options, '')).asCallback(callback); + return Promise.resolve(_emptyDir(path, '', options)).asCallback(callback); } function _emptyDirSync(path, options, parent) { - return _readAndFilterDirSync(path, options) - .filter(ignoreExcludeFiles(options.exclude, parent)) - .map(item => { - const childPath = join(path, item.name); - const currentPath = join(parent, item.name); + const entrys = _readAndFilterDirSync(path, options) + .filter(ignoreExcludeFiles(options.exclude, parent)); - if (item.isDirectory()) { - const removed = _emptyDirSync(childPath, options, currentPath); + const results = []; - if (!fs.readdirSync(childPath).length) { - rmdirSync(childPath); - } + for (const item of entrys) { + const childPath = join(path, item.name); + const currentPath = join(parent, item.name); + + if (item.isDirectory()) { + const removed = _emptyDirSync(childPath, options, currentPath); - return removed; + if (!fs.readdirSync(childPath).length) { + rmdirSync(childPath); } + results.push(...removed); + } else { fs.unlinkSync(childPath); - return currentPath; - }).reduce(reduceFiles, []); + results.push(currentPath); + } + } + + return results; } function emptyDirSync(path, options = {}) { @@ -324,12 +336,12 @@ function emptyDirSync(path, options = {}) { } async function _rmdir(path) { - const files = await fsPromises.readdir(path, { withFileTypes: true }); - await Promise.all(files.map(item => { + const files = fsPromises.readdir(path, { withFileTypes: true }); + await Promise.map(files, item => { const childPath = join(path, item.name); return item.isDirectory() ? _rmdir(childPath) : fsPromises.unlink(childPath); - })); + }); return fsPromises.rmdir(path); } @@ -342,8 +354,7 @@ function rmdir(path, callback) { function _rmdirSync(path) { const files = fs.readdirSync(path, { withFileTypes: true }); - for (let i = 0, len = files.length; i < len; i++) { - const item = files[i]; + for (const item of files) { const childPath = join(path, item.name); if (item.isDirectory()) {