fs-nextra
Version:
Node.js fs next-gen extra (nextra) methods.
92 lines • 3.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.copy = void 0;
const path_1 = require("path");
const fs_1 = require("fs");
const util_1 = require("../utils/util");
const mkdirs_1 = require("./mkdirs");
const remove_1 = require("./remove");
/**
* Copies files from one location to another, creating all directories required to satisfy the destination path.
* @function copy
* @memberof fsn/nextra
* @param source The source path
* @param destination The destination path
* @param options Options for the copy, or a filter function
*/
async function copy(source, destination, options = {}) {
const copyOptions = resolveCopyOptions(source, destination, options);
if (path_1.resolve(source) === path_1.resolve(destination)) {
if (copyOptions.errorOnExist)
throw new Error('FS-NEXTRA: Source and destination must not be the same.');
await fs_1.promises.access(source);
}
else {
await mkdirs_1.mkdirs(path_1.dirname(destination));
await startCopy(source, copyOptions);
}
}
exports.copy = copy;
function resolveCopyOptions(source, destination, options) {
if (typeof options === 'function')
options = { filter: options };
return {
currentPath: path_1.resolve(source),
targetPath: path_1.resolve(destination),
filter: typeof options.filter === 'function' ? options.filter : () => true,
overwrite: 'overwrite' in options ? Boolean(options.overwrite) : true,
preserveTimestamps: Boolean(options.preserveTimestamps),
errorOnExist: Boolean(options.errorOnExist)
};
}
async function isWritable(myPath) {
try {
await fs_1.promises.lstat(myPath);
return false;
}
catch (err) {
return err.code === 'ENOENT';
}
}
async function startCopy(mySource, options) {
if (!options.filter(mySource, options.targetPath))
return;
const stats = await fs_1.promises.lstat(mySource);
const target = mySource.replace(options.currentPath, util_1.replaceEsc(options.targetPath));
if (stats.isDirectory())
await copyDirectory(mySource, stats, target, options);
else
await copyOther(mySource, stats, target, options);
}
async function copyDirectory(mySource, stats, target, options) {
if (util_1.isSrcKid(mySource, target))
throw new Error('FS-NEXTRA: Copying a parent directory into a child will result in an infinite loop.');
if (await isWritable(target)) {
await fs_1.promises.mkdir(target, stats.mode);
await fs_1.promises.chmod(target, stats.mode);
}
const items = await fs_1.promises.readdir(mySource);
await Promise.all(items.map((item) => startCopy(path_1.join(mySource, item), options)));
}
async function copyOther(mySource, stats, target, options) {
try {
const tstats = await fs_1.promises.stat(target);
if (tstats && tstats.isDirectory())
target = path_1.join(target, path_1.basename(mySource));
}
catch (err) {
// noop
}
if (!await isWritable(target)) {
if (options.errorOnExist)
throw new Error(`FS-NEXTRA: ${target} already exists`);
if (!options.overwrite)
return;
await remove_1.remove(target);
}
if (stats.isSymbolicLink())
await fs_1.promises.symlink(await fs_1.promises.readlink(mySource), target);
else
await fs_1.promises.copyFile(mySource, target);
}
//# sourceMappingURL=copy.js.map
;