rcpy
Version:
Lightweight, fast, simple and flexible file copy utility for Node.js
2 lines (1 loc) • 3.24 kB
JavaScript
;var e=require("path"),r=require("fs"),t=require("fs/promises"),i=require("util"),a=require("process"),n=require("async-sema");const o=i.promisify(r.futimes),s=i.promisify(r.open),c=i.promisify(r.close),f=(e,r)=>r.ino&&r.dev&&r.ino===e.ino&&r.dev===e.dev;function w(e,r){return r.startsWith(e)}async function l(e,i,a){let n=a?t.stat:t.lstat,o=await n(e),s=r.existsSync(i)?await n(i):null,c=o.isDirectory();if(s){if(f(o,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&&w(e,i))throw Error(`Cannot copy '${e}' to a subdirectory of itself, '${i}'.`);return[o,s,c]}async function u(i,a,n,o){let s=e.resolve(e.dirname(i)),c=e.resolve(e.dirname(n));if(c===s||c===e.parse(c).root||!r.existsSync(c))return;let w=o?t.stat:t.lstat,l=await w(c);if(f(a,l))throw Error(`Cannot copy '${i}' to a subdirectory of itself, '${n}'.`);return u(i,a,c,o)}async function m(e,r,t){let i=await s(e,"r+"),a=null;try{await o(i,r,t)}catch(e){a=e}let n=null;try{await c(i)}catch(e){n=e}if(a)throw a;if(n)throw n}const d=async(i,o,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,o))return;let d=new n.Sema(c.concurrency),y=await l(i,o,c.dereference),p=y[0],h=e.resolve(e.dirname(o)),v=r.existsSync(h);async function $(e,r,[t,i,a]){if(a)return await d.acquire(),await b(t,i,e,r),d.release();if(t.isFile()||t.isCharacterDevice()||t.isBlockDevice())return await d.acquire(),await k(t,i,e,r),d.release();if(t.isSymbolicLink())return await d.acquire(),await q(e,r,i),d.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 n=await t.stat(r);await m(i,n.atime,n.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,n){i||await t.mkdir(n);let o=[];for await(let r of(await t.opendir(a))){let t=e.join(a,r.name),i=e.join(n,r.name);await f(t,i)&&o.push($(t,i,await l(t,i,c.dereference)))}await Promise.all(o),i||await t.chmod(n,r.mode)}async function q(r,i,n){let o,s=await t.readlink(r);if(c.dereference&&(s=e.resolve(a.cwd(),s)),!n)return t.symlink(s,i);try{o=await t.readlink(i)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return t.symlink(s,i);throw e}if(c.dereference&&(o=e.resolve(a.cwd(),o)),w(s,o))throw Error(`Cannot copy '${s}' to a subdirectory of itself, '${o}'.`);if(w(o,s))throw Error(`Cannot overwrite '${o}' with '${s}'.`);return await t.unlink(i),t.symlink(s,i)}return await u(i,p,o,c.dereference),v||await t.mkdir(h,{recursive:!0}),$(i,o,y)};exports.copy=d,exports.rcpy=d;