diff --git a/index.d.ts b/index.d.ts index be9f392..25608eb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,6 +1,23 @@ import {GlobbyOptions} from 'globby'; declare namespace del { + interface ProgressData { + /** + Deleted files and directories count. + */ + deletedCount: number; + + /** + Total files and directories count. + */ + totalCount: number; + + /** + Completed percentage. A value between `0` and `1`. + */ + percent: number; + } + interface Options extends GlobbyOptions { /** Allow deleting the current working directory and outside. @@ -33,6 +50,21 @@ declare namespace del { @default Infinity */ readonly concurrency?: number; + + /** + Called after each file or directory is deleted. + + @example + ``` + import del from 'del'; + + await del(patterns, { + onProgress: progress => { + // … + }}); + ``` + */ + readonly onProgress?: (progress: ProgressData) => void; } } diff --git a/index.js b/index.js index e1956b8..735aabe 100644 --- a/index.js +++ b/index.js @@ -52,7 +52,7 @@ function normalizePatterns(patterns) { return patterns; } -module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { +module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), onProgress = () => {}, ...options} = {}) => { options = { expandDirectories: false, onlyFiles: false, @@ -66,7 +66,15 @@ module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...option const files = (await globby(patterns, options)) .sort((a, b) => b.localeCompare(a)); - const mapper = async file => { + if (files.length === 0) { + onProgress({ + totalCount: 0, + deletedCount: 0, + percent: 1 + }); + } + + const mapper = async (file, fileIndex) => { file = path.resolve(cwd, file); if (!force) { @@ -77,11 +85,23 @@ module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...option await rimrafP(file, rimrafOptions); } + onProgress({ + totalCount: files.length, + deletedCount: fileIndex, + percent: fileIndex / files.length + }); + return file; }; const removedFiles = await pMap(files, mapper, options); + onProgress({ + totalCount: files.length, + deletedCount: files.length, + percent: 1 + }); + removedFiles.sort((a, b) => a.localeCompare(b)); return removedFiles; diff --git a/readme.md b/readme.md index e071435..bfd47f4 100644 --- a/readme.md +++ b/readme.md @@ -108,6 +108,33 @@ Minimum: `1` Concurrency limit. +##### onProgress + +Type: `(progress: ProgressData) => void` + +Called after each file or directory is deleted. + +```js +import del from 'del'; + +await del(patterns, { + onProgress: progress => { + // … +}}); +``` + +###### ProgressData + +```js +{ + totalFiles: number, + deletedFiles: number, + percent: number +} +``` + +- `percent` is a value between `0` and `1` + ## CLI See [del-cli](https://github.com/sindresorhus/del-cli) for a CLI for this module and [trash-cli](https://github.com/sindresorhus/trash-cli) for a safe version that is suitable for running by hand. diff --git a/test.js b/test.js index d5a4fcf..b7aa11c 100644 --- a/test.js +++ b/test.js @@ -349,3 +349,51 @@ test('windows can pass relative paths with "\\" - sync', t => { t.deepEqual(removeFiles, [nestedFile]); }); + +test('onProgress option - progress of non-existent file', async t => { + let report; + + await del('non-existent-directory', {onProgress: event => { + report = event; + }}); + + t.deepEqual(report, { + totalCount: 0, + deletedCount: 0, + percent: 1 + }); +}); + +test('onProgress option - progress of single file', async t => { + let report; + + await del(t.context.tmp, {cwd: __dirname, force: true, onProgress: event => { + report = event; + }}); + + t.deepEqual(report, { + totalCount: 1, + deletedCount: 1, + percent: 1 + }); +}); + +test('onProgress option - progress of multiple files', async t => { + let report; + + const sourcePath = process.platform === 'win32' ? path.resolve(`${t.context.tmp}/*`).replace(/\\/g, '/') : `${t.context.tmp}/*`; + + await del(sourcePath, { + cwd: __dirname, + force: true, + onProgress: event => { + report = event; + } + }); + + t.deepEqual(report, { + totalCount: 4, + deletedCount: 4, + percent: 1 + }); +});