Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: sindresorhus/trash
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4827f9c7e91be43add11e9aa03a530744df9b14a
Choose a base ref
...
head repository: sindresorhus/trash
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2e460f664094619d84211777948dc79bbb6ad094
Choose a head ref
  • 14 commits
  • 15 files changed
  • 4 contributors

Commits on Apr 20, 2018

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    186423a View commit details

Commits on Nov 6, 2018

  1. Require Node.js 8

    sindresorhus committed Nov 6, 2018
    2
    Copy the full SHA
    6cd7609 View commit details
  2. Drop support for Iterable as input

    It makes more sense to be explicit and only support string or array. You can easily use an iterable by spreading anyway.
    sindresorhus committed Nov 6, 2018
    Copy the full SHA
    aa29749 View commit details

Commits on Dec 31, 2018

  1. CI updates (#78)

    brandon93s authored and sindresorhus committed Dec 31, 2018
    Copy the full SHA
    27018aa View commit details

Commits on Mar 8, 2019

  1. Copy the full SHA
    c029c43 View commit details
  2. 5.0.0

    sindresorhus committed Mar 8, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    75c270b View commit details

Commits on Mar 31, 2019

  1. Copy the full SHA
    bdfbd07 View commit details
  2. 5.1.0

    sindresorhus committed Mar 31, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    08723b1 View commit details

Commits on Apr 1, 2019

  1. Copy the full SHA
    78e705c View commit details
  2. 5.2.0

    sindresorhus committed Apr 1, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0e17911 View commit details

Commits on May 28, 2019

  1. Create funding.yml

    sindresorhus authored May 28, 2019
    Copy the full SHA
    08934d3 View commit details

Commits on May 29, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8ec3260 View commit details
  2. Copy the full SHA
    cc399fe View commit details
  3. 6.0.0

    sindresorhus committed May 29, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2e460f6 View commit details
Showing with 246 additions and 165 deletions.
  1. +1 −2 .gitattributes
  2. +3 −0 .github/funding.yml
  3. +3 −2 .travis.yml
  4. +31 −0 index.d.ts
  5. +43 −25 index.js
  6. +8 −0 index.test-d.ts
  7. +28 −20 lib/linux.js
  8. +9 −29 lib/macos.js
  9. BIN lib/win-trash.exe
  10. +0 −9 lib/win.js
  11. BIN lib/windows-trash.exe
  12. +13 −0 lib/windows.js
  13. +55 −55 package.json
  14. +6 −6 readme.md
  15. +46 −17 test.js
3 changes: 1 addition & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
* text=auto
*.js text eol=lf
* text=auto eol=lf
lib/macos-trash binary
lib/win-trash.exe binary
3 changes: 3 additions & 0 deletions .github/funding.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
github: sindresorhus
open_collective: sindresorhus
custom: https://sindresorhus.com/donate
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
os:
- linux
- osx
- windows
language: node_js
node_js:
- '11'
- '10'
- '8'
- '6'
- '4'
31 changes: 31 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
declare namespace trash {
interface Options {
/**
Enable globbing when matching file paths.
@default true
*/
readonly glob?: boolean;
}
}

/**
Move files and folders to the trash.
@param input - Accepts paths and [glob patterns](https://github.com/sindresorhus/globby#globbing-patterns).
@example
```
import trash = require('trash');
(async () => {
await trash(['*.png', '!rainbow.png']);
})();
```
*/
declare function trash(
input: string | readonly string[],
options?: trash.Options
): Promise<void>;

export = trash;
68 changes: 43 additions & 25 deletions index.js
Original file line number Diff line number Diff line change
@@ -3,39 +3,57 @@ const fs = require('fs');
const path = require('path');
const globby = require('globby');
const pTry = require('p-try');
const isPathInside = require('is-path-inside');
const macos = require('./lib/macos');
const linux = require('./lib/linux');
const win = require('./lib/win');

module.exports = (iterable, opts) => pTry(() => {
iterable = Array.from(typeof iterable === 'string' ? [iterable] : iterable).map(String);
opts = Object.assign({glob: true}, opts);

const paths = (opts.glob === false ? iterable : globby.sync(iterable, {
expandDirectories: false,
nodir: false,
nonull: true
}))
.map(x => path.resolve(x))
.filter(x => {
try {
return fs.lstatSync(x);
} catch (err) {
if (err.code === 'ENOENT') {
return false;
}

throw err;
}
const windows = require('./lib/windows');

const trash = (paths, options) => pTry(() => {
paths = (typeof paths === 'string' ? [paths] : paths).map(String);

options = {
glob: true,
...options
};

// TOOD: Upgrading to latest `globby` version is blocked by https://github.com/mrmlnc/fast-glob/issues/110
if (options.glob) {
paths = globby.sync(paths, {
expandDirectories: false,
nodir: false,
nonull: true
});
}

paths = paths.map(filePath => path.resolve(filePath));
paths = paths.filter(filePath => {
if (paths.some(otherPath => isPathInside(filePath, otherPath))) {
return false;
}

try {
return fs.lstatSync(filePath);
} catch (error) {
if (error.code === 'ENOENT') {
return false;
}

throw error;
}
});

if (paths.length === 0) {
return;
}

switch (process.platform) {
case 'darwin': return macos(paths);
case 'win32': return win(paths);
default: return linux(paths);
case 'darwin':
return macos(paths);
case 'win32':
return windows(paths);
default:
return linux(paths);
}
});

module.exports = trash;
8 changes: 8 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {expectType} from 'tsd';
import trash = require('.');

expectType<Promise<void>>(trash('/path/to/item1'));
expectType<Promise<void>>(trash(['/path/to/item1', '/path/to/item2']));
expectType<Promise<void>>(
trash(['/path/to/item1', '/path/to/item2'], {glob: false})
);
48 changes: 28 additions & 20 deletions lib/linux.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
'use strict';
const {promisify} = require('util');
const os = require('os');
const path = require('path');
const fsExtra = require('fs-extra');
const pify = require('pify');
const fs = require('fs');
const uuid = require('uuid');
const xdgTrashdir = require('xdg-trashdir');
const pMap = require('p-map');
const makeDir = require('make-dir');
const moveFile = require('move-file');

const fs = pify(fsExtra);
const pWriteFile = promisify(fs.writeFile);

function trash(src) {
return xdgTrashdir(src).then(dir => {
const name = uuid.v4();
const dest = path.join(dir, 'files', name);
const info = path.join(dir, 'info', `${name}.trashinfo`);
const msg = `
const trash = async filePath => {
const trashDirectory = await xdgTrashdir(filePath);
const name = uuid.v4();
const destination = path.join(trashDirectory, 'files', name);
const trashInfoPath = path.join(trashDirectory, 'info', `${name}.trashinfo`);

const trashInfoData = `
[Trash Info]
Path=${src.replace(/\s/g, '%20')}
Path=${filePath.replace(/\s/g, '%20')}
DeletionDate=${(new Date()).toISOString()}
`.trim();

return Promise.all([
fs.move(src, dest, {mkdirp: true}),
fs.outputFile(info, msg)
]).then(() => ({
path: dest,
info
}));
});
}
await Promise.all([
moveFile(filePath, destination),
(async () => {
// TODO: Use the `fs.mkdir` with `recursive` option when targeting Node.js 12.
await makeDir(path.dirname(trashInfoPath));
await pWriteFile(trashInfoPath, trashInfoData);
})()
]);

return {
path: destination,
info: trashInfoPath
};
};

module.exports = paths => pMap(paths, trash, {concurrency: os.cpus().length});
module.exports = async paths => pMap(paths, trash, {concurrency: os.cpus().length});
38 changes: 9 additions & 29 deletions lib/macos.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,19 @@
'use strict';
const {promisify} = require('util');
const os = require('os');
const path = require('path');
const execFile = require('child_process').execFile;
const escapeStringApplescript = require('escape-string-applescript');
const runApplescript = require('run-applescript');
const pify = require('pify');
const {execFile} = require('child_process');

const olderThanMountainLion = Number(os.release().split('.')[0]) < 12;
const isOlderThanMountainLion = Number(os.release().split('.')[0]) < 12;
const pExecFile = promisify(execFile);

// Binary source: https://github.com/sindresorhus/macos-trash
const bin = path.join(__dirname, 'macos-trash');
const binary = path.join(__dirname, 'macos-trash');

function legacy(paths) {
const pathStr = paths.map(x => `"${escapeStringApplescript(x)}"`).join(',');
const script = `
set deleteList to {}
repeat with currentPath in {${pathStr}}
set end of deleteList to POSIX file currentPath
end repeat
tell app "Finder" to delete deleteList
`.trim();

return runApplescript(script).catch(err => {
if (/10010/.test(err.message)) {
err = new Error('Item doesn\'t exist');
}

throw err;
});
}

module.exports = paths => {
if (olderThanMountainLion) {
return legacy(paths);
module.exports = async paths => {
if (isOlderThanMountainLion) {
throw new Error('macOS 10.12 or later required');
}

return pify(execFile)(bin, paths);
await pExecFile(binary, paths);
};
Binary file removed lib/win-trash.exe
Binary file not shown.
9 changes: 0 additions & 9 deletions lib/win.js

This file was deleted.

Binary file added lib/windows-trash.exe
Binary file not shown.
13 changes: 13 additions & 0 deletions lib/windows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict';
const {promisify} = require('util');
const path = require('path');
const {execFile} = require('child_process');

const pExecFile = promisify(execFile);

// Binary source: https://github.com/sindresorhus/recycle-bin
const binary = path.join(__dirname, 'windows-trash.exe');

module.exports = async paths => {
await pExecFile(binary, paths);
};
110 changes: 55 additions & 55 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
{
"name": "trash",
"version": "4.3.0",
"description": "Move files and folders to the trash",
"license": "MIT",
"repository": "sindresorhus/trash",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=4"
},
"scripts": {
"test": "xo && ava"
},
"files": [
"index.js",
"lib"
],
"keywords": [
"trash",
"recycle",
"bin",
"rm",
"rmrf",
"rimraf",
"remove",
"delete",
"del",
"file",
"files",
"dir",
"directory",
"directories",
"folder",
"folders",
"xdg"
],
"dependencies": {
"escape-string-applescript": "^2.0.0",
"fs-extra": "^0.30.0",
"globby": "^7.1.1",
"p-map": "^1.2.0",
"p-try": "^1.0.0",
"pify": "^3.0.0",
"run-applescript": "^3.0.0",
"uuid": "^3.1.0",
"xdg-trashdir": "^2.1.1"
},
"devDependencies": {
"ava": "*",
"tempfile": "^2.0.0",
"xo": "*"
}
"name": "trash",
"version": "6.0.0",
"description": "Move files and folders to the trash",
"license": "MIT",
"repository": "sindresorhus/trash",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=8"
},
"scripts": {
"test": "xo && ava && tsd"
},
"files": [
"index.js",
"index.d.ts",
"lib"
],
"keywords": [
"trash",
"recycle",
"bin",
"rm",
"rmrf",
"rimraf",
"remove",
"delete",
"del",
"file",
"files",
"directory",
"directories",
"folder",
"folders",
"xdg"
],
"dependencies": {
"globby": "^7.1.1",
"is-path-inside": "^2.0.0",
"make-dir": "^3.0.0",
"move-file": "^1.1.0",
"p-map": "^2.0.0",
"p-try": "^2.2.0",
"uuid": "^3.3.2",
"xdg-trashdir": "^2.1.1"
},
"devDependencies": {
"ava": "^1.4.1",
"tempfile": "^3.0.0",
"tsd": "^0.7.3",
"xo": "^0.24.0"
}
}
Loading