Files
portfolio2023/build/node_modules/cp-file/index.js
T
2023-11-24 22:35:41 +01:00

112 lines
2.8 KiB
JavaScript

'use strict';
const path = require('path');
const {constants: fsConstants} = require('fs');
const pEvent = require('p-event');
const CpFileError = require('./cp-file-error');
const fs = require('./fs');
const ProgressEmitter = require('./progress-emitter');
const cpFileAsync = async (source, destination, options, progressEmitter) => {
let readError;
const stat = await fs.stat(source);
progressEmitter.size = stat.size;
const readStream = await fs.createReadStream(source);
await fs.makeDir(path.dirname(destination), {mode: options.directoryMode});
const writeStream = fs.createWriteStream(destination, {flags: options.overwrite ? 'w' : 'wx'});
readStream.on('data', () => {
progressEmitter.writtenBytes = writeStream.bytesWritten;
});
readStream.once('error', error => {
readError = new CpFileError(`Cannot read from \`${source}\`: ${error.message}`, error);
writeStream.end();
});
let shouldUpdateStats = false;
try {
const writePromise = pEvent(writeStream, 'close');
readStream.pipe(writeStream);
await writePromise;
progressEmitter.writtenBytes = progressEmitter.size;
shouldUpdateStats = true;
} catch (error) {
throw new CpFileError(`Cannot write to \`${destination}\`: ${error.message}`, error);
}
if (readError) {
throw readError;
}
if (shouldUpdateStats) {
const stats = await fs.lstat(source);
return Promise.all([
fs.utimes(destination, stats.atime, stats.mtime),
fs.chmod(destination, stats.mode)
]);
}
};
const cpFile = (sourcePath, destinationPath, options) => {
if (!sourcePath || !destinationPath) {
return Promise.reject(new CpFileError('`source` and `destination` required'));
}
options = {
overwrite: true,
...options
};
const progressEmitter = new ProgressEmitter(path.resolve(sourcePath), path.resolve(destinationPath));
const promise = cpFileAsync(sourcePath, destinationPath, options, progressEmitter);
promise.on = (...arguments_) => {
progressEmitter.on(...arguments_);
return promise;
};
return promise;
};
module.exports = cpFile;
const checkSourceIsFile = (stat, source) => {
if (stat.isDirectory()) {
throw Object.assign(new CpFileError(`EISDIR: illegal operation on a directory '${source}'`), {
errno: -21,
code: 'EISDIR',
source
});
}
};
module.exports.sync = (source, destination, options) => {
if (!source || !destination) {
throw new CpFileError('`source` and `destination` required');
}
options = {
overwrite: true,
...options
};
const stat = fs.statSync(source);
checkSourceIsFile(stat, source);
fs.makeDirSync(path.dirname(destination), {mode: options.directoryMode});
const flags = options.overwrite ? null : fsConstants.COPYFILE_EXCL;
try {
fs.copyFileSync(source, destination, flags);
} catch (error) {
if (!options.overwrite && error.code === 'EEXIST') {
return;
}
throw error;
}
fs.utimesSync(destination, stat.atime, stat.mtime);
};