UNPKG

fs-nextra

Version:

Node.js fs next-gen extra (nextra) methods.

92 lines 3.6 kB
"use strict"; 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