UNPKG

rcpy

Version:

Lightweight, fast, simple and flexible file copy utility for Node.js

2 lines (1 loc) 3.21 kB
import e from"path";import r from"fs";import t from"fs/promises";import{promisify as i}from"util";import a from"process";import{Sema as o}from"async-sema";let n=i(r.futimes),s=i(r.open),c=i(r.close),f=(e,r)=>r.ino&&r.dev&&r.ino===e.ino&&r.dev===e.dev;function l(e,r){return r.startsWith(e)}async function m(e,i,a){let o=a?t.stat:t.lstat,n=await o(e),s=r.existsSync(i)?await o(i):null,c=n.isDirectory();if(s){if(f(n,s))throw Error("Source and destination must not be the same.");let r=s.isDirectory();if(c&&!r)throw Error(`Cannot overwrite non-directory '${i}' with directory '${e}'.`);if(!c&&r)throw Error(`Cannot overwrite directory '${i}' with non-directory '${e}'.`)}if(c&&l(e,i))throw Error(`Cannot copy '${e}' to a subdirectory of itself, '${i}'.`);return[n,s,c]}async function w(i,a,o,n){let s=e.resolve(e.dirname(i)),c=e.resolve(e.dirname(o));if(c===s||c===e.parse(c).root||!r.existsSync(c))return;let l=n?t.stat:t.lstat,m=await l(c);if(f(a,m))throw Error(`Cannot copy '${i}' to a subdirectory of itself, '${o}'.`);return w(i,a,c,n)}async function d(e,r,t){let i=await s(e,"r+"),a=null;try{await n(i,r,t)}catch(e){a=e}let o=null;try{await c(i)}catch(e){o=e}if(a)throw a;if(o)throw o}let u=async(i,n,s={})=>{let c=Object.assign({dereference:!1,filter:(e,r)=>!0,force:s.overwrite??!0,overwrite:!0,errorOnExist:!1,mode:0,preserveTimestamps:!1,concurrency:32},s),f=c.filter;if(c.preserveTimestamps&&"ia32"===a.arch&&a.emitWarning("Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269","Warning","rcpy-WARN0001"),!await f(i,n))return;let u=new o(c.concurrency),y=await m(i,n,c.dereference),p=y[0],h=e.resolve(e.dirname(n)),v=r.existsSync(h);async function $(e,r,[t,i,a]){if(a)return await u.acquire(),await b(t,i,e,r),u.release();if(t.isFile()||t.isCharacterDevice()||t.isBlockDevice())return await u.acquire(),await k(t,i,e,r),u.release();if(t.isSymbolicLink())return await u.acquire(),await x(e,r,i),u.release();throw Error(`Can not copy '${e}', incompatible file type`)}async function E(e,r,i){if(await t.copyFile(r,i,c.mode),c.preserveTimestamps){var a;(128&e.mode)==0&&await (a=e.mode,t.chmod(i,128|a));let o=await t.stat(r);await d(i,o.atime,o.mtime)}return t.chmod(i,e.mode)}async function k(e,r,i,a){if(!r)return E(e,i,a);if(c.force)return await t.unlink(a),E(e,i,a);if(c.errorOnExist)throw Error(`'${a}' already exists`)}async function b(r,i,a,o){i||await t.mkdir(o);let n=[];for await(let r of(await t.opendir(a))){let t=e.join(a,r.name),i=e.join(o,r.name);await f(t,i)&&n.push($(t,i,await m(t,i,c.dereference)))}await Promise.all(n),i||await t.chmod(o,r.mode)}async function x(r,i,o){let n,s=await t.readlink(r);if(c.dereference&&(s=e.resolve(a.cwd(),s)),!o)return t.symlink(s,i);try{n=await t.readlink(i)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return t.symlink(s,i);throw e}if(c.dereference&&(n=e.resolve(a.cwd(),n)),l(s,n))throw Error(`Cannot copy '${s}' to a subdirectory of itself, '${n}'.`);if(l(n,s))throw Error(`Cannot overwrite '${n}' with '${s}'.`);return await t.unlink(i),t.symlink(s,i)}return await w(i,p,n,c.dereference),v||await t.mkdir(h,{recursive:!0}),$(i,n,y)};export{u as copy,u as rcpy};