@knide/fs-prober
Version:
fs-prober is a browser-friendly NPM package for extracting file and folder structures from user-selected files or directories.
2 lines (1 loc) • 7.19 kB
JavaScript
var L=Object.defineProperty;var q=(e,t)=>{for(var r in t)L(e,r,{get:t[r],enumerable:!0})};import M from"lodash.flatmap";import S from"lodash.map";import{nanoid as z}from"nanoid";var W=e=>typeof DataTransferItem>"u"?!1:e in DataTransferItem.prototype,N=W("getAsFileSystemHandle"),w=W("webkitGetAsEntry"),m=e=>"kind"in e,P=e=>"kind"in e?e.kind==="directory":!!e.isDirectory,E=e=>"kind"in e?e.kind==="file":!!e.isFile,D=()=>{let e="Your browser is not supported. Please use a chromium based browser.";return console.error(e),new Error(e)},k=async(e,t)=>{if(!e.dataTransfer)throw new Error("Unable to get rootHandle for drop event");if(w)return e.dataTransfer.items[t]?.webkitGetAsEntry()||null;if(N)return e.dataTransfer.items[t]?.getAsFileSystemHandle()||Promise.resolve(null);throw D()},b=e=>{if(w&&!m(e)){if("isFile"in e&&e.isFile)return"file";if("isDirectory"in e&&e.isDirectory)return"directory";throw new Error("Unknown handle kind")}else if(N){if(m(e))return e.kind;throw new Error("Invalid FileSystemHandle")}throw D()},I=async e=>{let t="Passed handle is not a directory";if(w&&!m(e)){if(!e.isDirectory)throw Error(t);let r=e.createReader();return await(async()=>{let o=[],d=async()=>new Promise((s,i)=>{r.readEntries(a=>{a.length>0?(a.forEach(l=>{o.push([l.name,l])}),d().then(s).catch(i)):s(o)},a=>i(a))});return d()})()}else if(N&&m(e)){if(e.kind!=="directory")throw Error(t);let r=[];for await(let n of e.entries())r.push(n);return r}throw D()},x=async e=>{if(w&&!m(e))return await(async r=>new Promise((n,o)=>r.file(n,o)))(e);if(N&&m(e))return await e.getFile();throw D()};var te=async e=>{if(!e.dataTransfer)throw new Error("Unable to generate hierarchyTree for drop event");let t=[];for(let n=0;n<e.dataTransfer.items.length;n++)try{let o=k(e,n);if(o==null)return null;t.push(o)}catch(o){console.error(`Error probing item ${n}:`,o)}let r=[];for(let n=0;n<t.length;n++){let o=await t[n];if(!o)continue;let d=await U(o,!1);d&&r.push(d)}return j(r)};var u=(e,t)=>{let r=z();return t.set(r,e),r};async function U(e,t=!0){if(!e)return null;let r=new Map,n=new Map,o={emptyFolders:[],allFolders:[],allFiles:[],rootHandle:e,rootFolder:void 0,rootFile:void 0,nameMap:n,objectMap:r},d=e.name;if(P(e))await v(e,d,o,{objectMap:r,nameMap:n}),o.rootFolder=o.allFolders[o.allFolders.length-1],o.allFolders.length===1&&o.allFolders[0]?.children.length===0&&o.allFolders[0]&&o.emptyFolders.push(o.allFolders[0]);else if(E(e)){let s=u(e.name,n),i={name:e.name,nameId:s,pathIds:[s],kind:"file",isBranch:!1,path:d,handle:e};r.set(s,i),o.allFiles.push(i),o.rootFile=i}return o.nameMap=n,o.objectMap=r,t?j([o]):o}var v=async(e,t,r,n,o=[])=>{let d=b(e);if(d!=="directory")return;let{objectMap:s,nameMap:i}=n,a=u(e.name,i),l={name:e.name,nameId:a,pathIds:[...o,a],kind:d,isBranch:!0,path:t,children:[],handle:e};s.set(a,l);let p=await I(e);for(let[F,c]of p){let h=`${t}/${F}`,y=b(c);if(y==="file"&&E(c)){let f=u(c.name,i),g={path:h,pathIds:[...o,a,f],name:c.name,nameId:f,kind:y,isBranch:!1,handle:c};s.set(f,g),r.allFiles.push(g),l.children.push(g)}else if(P(c)){let f=[...o,a],H=await v(c,h,r,{objectMap:s,nameMap:i},f);H&&(H.children.length===0&&r.emptyFolders.push(H),l.children.push(H))}}return r.allFolders.push(l),l},j=e=>{if(!e||e.length===0)return null;let t=[];e.forEach(o=>{t=[...t,...o.nameMap]});let r=[];return e.forEach(o=>{r=[...r,...o.objectMap]}),{emptyFolders:M(e,"emptyFolders"),allFolders:M(e,"allFolders"),allFiles:M(e,"allFiles"),rootHandles:S(e,"rootHandle"),rootFolders:S(e,"rootFolder").filter(Boolean),rootFiles:S(e,"rootFile").filter(Boolean),nameMap:new Map(t),objectMap:new Map(r)}};var O=e=>e.kind==="directory";var T=e=>e?.replace(/\/+$/,"").replace(/\/+/g,"/")||"/";var de=async e=>{if(!e)return null;let t=[];for(let r of e){let n=await x(r.handle);Object.defineProperty(n,"path",{value:r.path}),t.push(n)}return t},R=e=>{try{if(!e.path)throw new Error("isRootFile: no path in file");let t=e.path.replace("/",""),r=e.name.replace("/","");return t===r}catch(t){throw console.error(t),console.warn("isRootFile: ",e),t}},$=(e,t,r)=>{let n=[],o=[],d=new Map,s=(i,a)=>{if(!i.length)return{pathIds:[]};let l=i.join("/");if(d.has(l)){let h=d.get(l);if(h){let y=r.get(h);return a&&y&&O(y)&&y.children.push(a),{pathIds:[h]}}else throw new Error(`Unreachable code: nameId not found for path: ${l}`)}let p=i[i.length-1]||"",F=u(p,t),c={name:p,nameId:F,kind:"directory",isBranch:!0,path:l,children:a?[a]:[],pathIds:[]};if(r.set(F,c),o.push(c),d.set(l,F),i.length>1){let h=i.slice(0,-1),{pathIds:y}=s(h,c);return c.pathIds=[...y,F],{pathIds:c.pathIds}}else return n.push(c),c.pathIds=[F],{pathIds:c.pathIds}};for(let i of e){if(R(i))continue;let l=T(i.path).split("/").filter(Boolean).slice(0,-1),{pathIds:p}=s(l,i);i.pathIds=[...p,i.nameId]}return[o,n]},ce=e=>{if(!e)return null;let t=new Map,r=new Map,n=[],o=e.map(a=>{let l=u(a.name,t),p=T(a.webkitRelativePath||a.path),F={path:p,name:p.split("/").pop()||a.name,kind:"file",isBranch:!1,pathIds:[l],nameId:l};return R(a)&&n.push(F),r.set(l,F),F}),[d,s]=$(o,t,r);return{emptyFolders:[],allFolders:d,rootFolders:s,allFiles:o,rootFiles:n,nameMap:t,objectMap:r}},Fe=e=>e.filter(t=>t instanceof File?!0:t instanceof DataTransferItem&&t.kind==="file"?t.getAsFile()instanceof File:!1),K=e=>"kind"in e?e.kind==="directory"&&e.children.length===0:!1,C=e=>"path"in e,pe=e=>{let t=new DataTransfer;return e.forEach(n=>{let o=new File([],n.name);if(!(n instanceof File)&&K(n)){let d=new File([],n.name);for(let s in n)n[s]&&!d[s]&&s!=="name"&&(d[s]=n[s]);o=d}if(C(n)&&n.path!==""&&n.webkitRelativePath===""){let d=G(n.path);o=V(n,d)}t.items.add(o)}),t.files},G=e=>{if(!e)return"";let t=e.startsWith("/")?e.substring(1):e;return!t.includes("/")?"":t},A=(e,t)=>{let r=t.split("/").filter(Boolean);return r[r.length-1]=e.name,r.join("/")},V=(e,t)=>{let r=A(e,t);try{return Object.defineProperty(e,"webkitRelativePath",{value:t}),e.path===void 0&&Object.defineProperty(e,"path",{value:r}),e}catch(n){if(n instanceof TypeError&&n.message.includes("Cannot redefine property"))return B(e,{webkitRelativePath:t,path:r});throw console.error("Unexpected error: ",n),n}},B=(e,t)=>{try{for(let[r,n]of Object.entries(t))Object.defineProperty(e,r,{value:n});return e}catch(r){if(r instanceof TypeError&&(r.message.includes("Cannot redefine property")||r.message.includes("can't redefine non-configurable property")||r.message.includes("Attempting to change value of a readonly property"))){let o=new File([e],e.name,{type:e.type,lastModified:e.lastModified}),d=[...Object.getOwnPropertyNames(e),...Object.getOwnPropertyNames(Object.getPrototypeOf(e))],s={};for(let a of d){let l=e[a];typeof l=="function"||l===void 0||(s[a]=l)}let i={...s,path:e.path,webkitRelativePath:e.webkitRelativePath,...t};for(let[a,l]of Object.entries(i))Object.defineProperty(o,a,{value:l});return o}else throw console.error("Unexpected error: ",r),r}},Y=e=>{if(!e)return"";let t=e;return e.startsWith("./")&&(t=e.substring(2)),e.startsWith("/")&&(t=e.substring(1)),t},he=e=>e.map(t=>{let r=Y(t.path||t.relativePath||t.webkitRelativePath);return B(t,{webkitRelativePath:r,path:A(t,r)})});export{q as a,te as b,U as c,O as d,de as e,ce as f,Fe as g,pe as h,B as i,he as j};