diff --git a/lib/fs.js b/lib/fs.js index 4e03928..c79c8f9 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -216,22 +216,22 @@ function _readAndFilterDirSync(path, options) { }); } -function _copyDir(src, dest, options = {}, parent = '') { - return checkParent(dest).then(() => _readAndFilterDir(src, options)) +function _copyDir(src, dest, options, parent) { + return _readAndFilterDir(src, options) .map(item => { const childSrc = item.fullPath; const childDest = join(dest, item.path); + const currentPath = join(parent, item.path); if (item.isDirectory) { - return _copyDir(childSrc, childDest, options, join(parent, item.path)); + return _copyDir(childSrc, childDest, options, currentPath); } - return copyFile(childSrc, childDest, options) - .thenReturn(join(parent, item.path)); + return copyFile(childSrc, childDest, options).thenReturn(currentPath); }).reduce(reduceFiles, []); } -function copyDir(src, dest, options, callback) { +function copyDir(src, dest, options = {}, callback) { if (!src) throw new TypeError('src is required!'); if (!dest) throw new TypeError('dest is required!'); @@ -240,20 +240,22 @@ function copyDir(src, dest, options, callback) { options = {}; } - return _copyDir(src, dest, options).asCallback(callback); + return checkParent(dest).then(() => _copyDir(src, dest, options, '')).asCallback(callback); } -function _listDir(path, options = {}, parent = '') { +function _listDir(path, options, parent) { return _readAndFilterDir(path, options).map(item => { + const currentPath = join(parent, item.path); + if (item.isDirectory) { - return _listDir(item.fullPath, options, join(parent, item.path)); + return _listDir(item.fullPath, options, currentPath); } - return join(parent, item.path); + return currentPath; }).reduce(reduceFiles, []); } -function listDir(path, options, callback) { +function listDir(path, options = {}, callback) { if (!path) throw new TypeError('path is required!'); if (!callback && typeof options === 'function') { @@ -261,21 +263,27 @@ function listDir(path, options, callback) { options = {}; } - return _listDir(path, options).asCallback(callback); + return _listDir(path, options, '').asCallback(callback); } -function listDirSync(path, options = {}, parent = '') { - if (!path) throw new TypeError('path is required!'); - +function _listDirSync(path, options, parent) { return _readAndFilterDirSync(path, options).map(item => { + const currentPath = join(parent, item.path); + if (item.isDirectory) { - return listDirSync(item.fullPath, options, join(parent, item.path)); + return _listDirSync(item.fullPath, options, currentPath); } - return join(parent, item.path); + return currentPath; }).reduce(reduceFiles, []); } +function listDirSync(path, options = {}) { + if (!path) throw new TypeError('path is required!'); + + return _listDirSync(path, options, ''); +} + function escapeEOL(str) { return str.replace(rEOL, '\n'); } @@ -288,7 +296,7 @@ function escapeFileContent(content) { return escapeBOM(escapeEOL(content)); } -function readFile(path, options, callback) { +function readFile(path, options = {}, callback) { if (!path) throw new TypeError('path is required!'); if (!callback && typeof options === 'function') { @@ -296,7 +304,6 @@ function readFile(path, options, callback) { options = {}; } - options = options || {}; if (!options.hasOwnProperty('encoding')) options.encoding = 'utf8'; return readFileAsync(path, options).then(content => { @@ -322,23 +329,24 @@ function readFileSync(path, options = {}) { return content; } -function _emptyDir(path, options = {}, parent = '') { +function _emptyDir(path, options, parent) { return _readAndFilterDir(path, options) .filter(ignoreExcludeFiles(options.exclude, parent)) .map(item => { const fullPath = item.fullPath; + const currentPath = join(parent, item.path); if (item.isDirectory) { - return _emptyDir(fullPath, options, join(parent, item.path)).then(removed => readdirAsync(fullPath).then(files => { + return _emptyDir(fullPath, options, currentPath).tap(() => readdirAsync(fullPath).then(files => { if (!files.length) return rmdirAsync(fullPath); - }).thenReturn(removed)); + })); } - return unlinkAsync(fullPath).thenReturn(join(parent, item.path)); + return unlinkAsync(fullPath).thenReturn(currentPath); }).reduce(reduceFiles, []); } -function emptyDir(path, options, callback) { +function emptyDir(path, options = {}, callback) { if (!path) throw new TypeError('path is required!'); if (!callback && typeof options === 'function') { @@ -346,19 +354,18 @@ function emptyDir(path, options, callback) { options = {}; } - return _emptyDir(path, options).asCallback(callback); + return _emptyDir(path, options, '').asCallback(callback); } -function emptyDirSync(path, options = {}, parent = '') { - if (!path) throw new TypeError('path is required!'); - +function _emptyDirSync(path, options, parent) { return _readAndFilterDirSync(path, options) .filter(ignoreExcludeFiles(options.exclude, parent)) .map(item => { const childPath = item.fullPath; + const currentPath = join(parent, item.path); if (item.isDirectory) { - const removed = emptyDirSync(childPath, options, join(parent, item.path)); + const removed = _emptyDirSync(childPath, options, currentPath); if (!fs.readdirSync(childPath).length) { rmdirSync(childPath); @@ -368,29 +375,37 @@ function emptyDirSync(path, options = {}, parent = '') { } fs.unlinkSync(childPath); - return join(parent, item.path); + return currentPath; }).reduce(reduceFiles, []); } -function rmdir(path, callback) { +function emptyDirSync(path, options = {}) { if (!path) throw new TypeError('path is required!'); + return _emptyDirSync(path, options, ''); +} + +function _rmdir(path) { return readdirAsync(path).map(item => { const childPath = join(path, item); return statAsync(childPath).then(stats => { if (stats.isDirectory()) { - return rmdir(childPath); + return _rmdir(childPath); } return unlinkAsync(childPath); }); - }).then(() => rmdirAsync(path)).asCallback(callback); + }).then(() => rmdirAsync(path)); } -function rmdirSync(path) { +function rmdir(path, callback) { if (!path) throw new TypeError('path is required!'); + return _rmdir(path).asCallback(callback); +} + +function _rmdirSync(path) { const files = fs.readdirSync(path); for (let i = 0, len = files.length; i < len; i++) { @@ -398,7 +413,7 @@ function rmdirSync(path) { const stats = fs.statSync(childPath); if (stats.isDirectory()) { - rmdirSync(childPath); + _rmdirSync(childPath); } else { fs.unlinkSync(childPath); } @@ -407,6 +422,12 @@ function rmdirSync(path) { fs.rmdirSync(path); } +function rmdirSync(path) { + if (!path) throw new TypeError('path is required!'); + + _rmdirSync(path); +} + function watch(path, options, callback) { if (!path) throw new TypeError('path is required!'); @@ -415,34 +436,24 @@ function watch(path, options, callback) { options = {}; } - return new Promise((resolve, reject) => { - const watcher = chokidar.watch(path, options); - - watcher.on('ready', () => { - resolve(watcher); - }); + const watcher = chokidar.watch(path, options); + return new Promise((resolve, reject) => { + watcher.on('ready', resolve); watcher.on('error', reject); - }).asCallback(callback); + }).thenReturn(watcher).asCallback(callback); } function _findUnusedPath(path, files) { const ext = extname(path); const base = basename(path, ext); - const regex = new RegExp(`^${escapeRegExp(base)}(?:-(\\d+))?${escapeRegExp(ext)}$`); - let num = -1; + const regex = new RegExp(`^${escapeRegExp(base)}-(\\d+)${escapeRegExp(ext)}$`); - for (let i = 0, len = files.length; i < len; i++) { - const item = files[i]; - if (!regex.test(item)) continue; + const num = files.reduce((_num, item) => { + const match = regex.exec(item); - const match = item.match(regex); - const matchNum = match[1] ? parseInt(match[1], 10) : 0; - - if (matchNum > num) { - num = matchNum; - } - } + return match != null ? Math.max(parseInt(match[1], 10), _num) : _num; + }, -1); return join(dirname(path), `${base}-${num + 1}${ext}`); } @@ -488,7 +499,7 @@ function ensureWriteStreamSync(path, options) { ['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(key => { Object.defineProperty(exports, key, { enumerable: true, - value: (fs.constants || fs)[key], + value: fs.constants[key], writable: false }); });