@npmcli/move-file
Advanced tools
Comparing version 1.0.1 to 1.1.0
83
index.js
@@ -1,2 +0,3 @@ | ||
const { dirname } = require('path') | ||
const { dirname, join, resolve, relative, isAbsolute } = require('path') | ||
const rimraf_ = require('rimraf') | ||
const { promisify } = require('util') | ||
@@ -10,4 +11,14 @@ const { | ||
unlinkSync, | ||
readdir: readdir_, | ||
readdirSync, | ||
rename: rename_, | ||
renameSync, | ||
stat: stat_, | ||
statSync, | ||
lstat: lstat_, | ||
lstatSync, | ||
symlink: symlink_, | ||
symlinkSync, | ||
readlink: readlink_, | ||
readlinkSync | ||
} = require('fs') | ||
@@ -18,3 +29,10 @@ | ||
const unlink = promisify(unlink_) | ||
const readdir = promisify(readdir_) | ||
const rename = promisify(rename_) | ||
const stat = promisify(stat_) | ||
const lstat = promisify(lstat_) | ||
const symlink = promisify(symlink_) | ||
const readlink = promisify(readlink_) | ||
const rimraf = promisify(rimraf_) | ||
const rimrafSync = rimraf_.sync | ||
@@ -41,3 +59,3 @@ const mkdirp = require('mkdirp') | ||
module.exports = async (source, destination, options = {}) => { | ||
const moveFile = async (source, destination, options = {}, root = true, symlinks = []) => { | ||
if (!source || !destination) { | ||
@@ -62,4 +80,11 @@ throw new TypeError('`source` and `destination` file required') | ||
if (error.code === 'EXDEV') { | ||
await copyFile(source, destination) | ||
await unlink(source) | ||
const sourceStat = await lstat(source) | ||
if (sourceStat.isDirectory()) { | ||
const files = await readdir(source) | ||
await Promise.all(files.map((file) => moveFile(join(source, file), join(destination, file), options, false, symlinks))) | ||
} else if (sourceStat.isSymbolicLink()) { | ||
symlinks.push({ source, destination }) | ||
} else { | ||
await copyFile(source, destination) | ||
} | ||
} else { | ||
@@ -69,5 +94,21 @@ throw error | ||
} | ||
if (root) { | ||
await Promise.all(symlinks.map(async ({ source, destination }) => { | ||
let target = await readlink(source) | ||
// junction symlinks in windows will be absolute paths, so we need to make sure they point to the destination | ||
if (isAbsolute(target)) | ||
target = resolve(destination, relative(source, target)) | ||
// try to determine what the actual file is so we can create the correct type of symlink in windows | ||
let targetStat | ||
try { | ||
targetStat = await stat(resolve(dirname(source), target)) | ||
} catch (err) {} | ||
await symlink(target, destination, targetStat && targetStat.isDirectory() ? 'junction' : 'file') | ||
})) | ||
await rimraf(source) | ||
} | ||
} | ||
module.exports.sync = (source, destination, options = {}) => { | ||
const moveFileSync = (source, destination, options = {}, root = true, symlinks = []) => { | ||
if (!source || !destination) { | ||
@@ -92,4 +133,13 @@ throw new TypeError('`source` and `destination` file required') | ||
if (error.code === 'EXDEV') { | ||
copyFileSync(source, destination) | ||
unlinkSync(source) | ||
const sourceStat = lstatSync(source) | ||
if (sourceStat.isDirectory()) { | ||
const files = readdirSync(source) | ||
for (const file of files) { | ||
moveFileSync(join(source, file), join(destination, file), options, false, symlinks) | ||
} | ||
} else if (sourceStat.isSymbolicLink()) { | ||
symlinks.push({ source, destination }) | ||
} else { | ||
copyFileSync(source, destination) | ||
} | ||
} else { | ||
@@ -99,2 +149,21 @@ throw error | ||
} | ||
if (root) { | ||
for (const { source, destination } of symlinks) { | ||
let target = readlinkSync(source) | ||
// junction symlinks in windows will be absolute paths, so we need to make sure they point to the destination | ||
if (isAbsolute(target)) | ||
target = resolve(destination, relative(source, target)) | ||
// try to determine what the actual file is so we can create the correct type of symlink in windows | ||
let targetStat | ||
try { | ||
targetStat = statSync(resolve(dirname(source), target)) | ||
} catch (err) {} | ||
symlinkSync(target, destination, targetStat && targetStat.isDirectory() ? 'junction' : 'file') | ||
} | ||
rimrafSync(source) | ||
} | ||
} | ||
module.exports = moveFile | ||
module.exports.sync = moveFileSync |
{ | ||
"name": "@npmcli/move-file", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"files": [ | ||
@@ -9,3 +9,4 @@ "index.js" | ||
"dependencies": { | ||
"mkdirp": "^1.0.4" | ||
"mkdirp": "^1.0.4", | ||
"rimraf": "^2.7.1" | ||
}, | ||
@@ -12,0 +13,0 @@ "devDependencies": { |
@@ -6,3 +6,3 @@ # @npmcli/move-file | ||
> Move a file | ||
> Move a file (or directory) | ||
@@ -22,2 +22,3 @@ The built-in | ||
- Support for Node versions that lack built-in recursive `fs.mkdir()` | ||
- Automatically recurses when source is a directory. | ||
@@ -53,3 +54,3 @@ ## Install | ||
File you want to move. | ||
File, or directory, you want to move. | ||
@@ -60,3 +61,3 @@ #### destination | ||
Where you want the file moved. | ||
Where you want the file or directory moved. | ||
@@ -72,2 +73,2 @@ #### options | ||
Overwrite existing destination file. | ||
Overwrite existing destination file(s). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7843
145
70
2
1
+ Addedrimraf@^2.7.1
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedwrappy@1.0.2(transitive)