mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 22:04:26 +00:00

PR-URL: https://github.com/nodejs/node/pull/35474 Reviewed-By: Ruy Adorno <ruyadorno@github.com> Reviewed-By: Ujjwal Sharma <ryzokuken@disroot.org> Reviewed-By: Ben Coe <bencoe@gmail.com> Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
94 lines
1.8 KiB
JavaScript
94 lines
1.8 KiB
JavaScript
const { dirname } = require('path')
|
|
const { promisify } = require('util')
|
|
const {
|
|
access: access_,
|
|
accessSync,
|
|
copyFile: copyFile_,
|
|
copyFileSync,
|
|
unlink: unlink_,
|
|
unlinkSync,
|
|
rename: rename_,
|
|
renameSync,
|
|
} = require('fs')
|
|
|
|
const access = promisify(access_)
|
|
const copyFile = promisify(copyFile_)
|
|
const unlink = promisify(unlink_)
|
|
const rename = promisify(rename_)
|
|
|
|
const mkdirp = require('mkdirp')
|
|
|
|
const pathExists = async path => {
|
|
try {
|
|
await access(path)
|
|
return true
|
|
} catch (er) {
|
|
return er.code !== 'ENOENT'
|
|
}
|
|
}
|
|
|
|
const pathExistsSync = path => {
|
|
try {
|
|
accessSync(path)
|
|
return true
|
|
} catch (er) {
|
|
return er.code !== 'ENOENT'
|
|
}
|
|
}
|
|
|
|
module.exports = async (source, destination, options = {}) => {
|
|
if (!source || !destination) {
|
|
throw new TypeError('`source` and `destination` file required')
|
|
}
|
|
|
|
options = {
|
|
overwrite: true,
|
|
...options
|
|
}
|
|
|
|
if (!options.overwrite && await pathExists(destination)) {
|
|
throw new Error(`The destination file exists: ${destination}`)
|
|
}
|
|
|
|
await mkdirp(dirname(destination))
|
|
|
|
try {
|
|
await rename(source, destination)
|
|
} catch (error) {
|
|
if (error.code === 'EXDEV') {
|
|
await copyFile(source, destination)
|
|
await unlink(source)
|
|
} else {
|
|
throw error
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports.sync = (source, destination, options = {}) => {
|
|
if (!source || !destination) {
|
|
throw new TypeError('`source` and `destination` file required')
|
|
}
|
|
|
|
options = {
|
|
overwrite: true,
|
|
...options
|
|
}
|
|
|
|
if (!options.overwrite && pathExistsSync(destination)) {
|
|
throw new Error(`The destination file exists: ${destination}`)
|
|
}
|
|
|
|
mkdirp.sync(dirname(destination))
|
|
|
|
try {
|
|
renameSync(source, destination)
|
|
} catch (error) {
|
|
if (error.code === 'EXDEV') {
|
|
copyFileSync(source, destination)
|
|
unlinkSync(source)
|
|
} else {
|
|
throw error
|
|
}
|
|
}
|
|
}
|