modern-file-saver
Version:
Modern file saving library for browsers with File System Access API support and fallback
1 lines • 2.77 kB
JavaScript
function e(e){return e.startsWith("data:")&&e.includes(";base64,")}async function t(t,a){let i=e(t)?t:`data:${a||"application/octet-stream"};base64,${t}`,n=await fetch(i),o=await n.blob();return a&&o.type!==a?new Blob([await o.arrayBuffer()],{type:a}):o}async function a(i,n={}){var o;if("object"==typeof(o=i)&&!(o instanceof Blob)&&!(o instanceof ArrayBuffer)&&!ArrayBuffer.isView(o)&&!(o instanceof URLSearchParams)&&!(o instanceof FormData))return new Blob([JSON.stringify(i,null,2)],{type:n.mimeType||"application/json"});if("string"==typeof i)return n.isBase64||e(i)?t(i,n.mimeType):new Blob([i],{type:n.mimeType||"text/plain"});if(i instanceof Blob)return n.mimeType&&n.mimeType!==i.type?new Blob([await i.arrayBuffer()],{type:n.mimeType}):i;if(i instanceof ArrayBuffer||ArrayBuffer.isView(i))return new Blob([i],{type:n.mimeType||"application/octet-stream"});if(i instanceof URLSearchParams)return new Blob([i.toString()],{type:"application/x-www-form-urlencoded"});if(i instanceof FormData){let e=[];return i.forEach((t,a)=>{e.push(`${encodeURIComponent(a)}=${encodeURIComponent(t.toString())}`)}),new Blob([e.join("&")],{type:"multipart/form-data"})}throw Error("Unsupported input type")}var i=class{constructor(e="none"){this.level=e}debug(e,...t){"debug"===this.level&&console.log(`[modern-file-saver] ${e}`,...t)}};async function n(e,t={}){let{fileName:o=e instanceof File?e.name:"download",promptSaveAs:r=!0,logLevel:s="none"}=t,l=function(e="none"){return new i(e)}(s);try{l.debug("Converting input to blob",{type:e.constructor.name});let i=await a(e,t);if(l.debug("Blob created",{type:i.type,size:i.size}),r&&"showSaveFilePicker"in window)try{let e,t;l.debug("Attempting to use File System Access API");let a=await window.showSaveFilePicker((!(e=i.type||"application/octet-stream").includes("/")&&(e="application/octet-stream"),t=o.split(".").pop()||"bin",{suggestedName:o,types:[{description:"File",accept:{[e]:[t=t.startsWith(".")?t:`.${t}`]}}]}));l.debug("File handle obtained, creating writable");let n=await a.createWritable();await n.write(i),await n.close(),l.debug("File saved successfully using File System Access API");return}catch(e){if("AbortError"===e.name)throw l.debug("User aborted File System Access API save dialog"),e;l.debug("File System Access API failed, falling back to legacy method",e)}else l.debug("Using legacy download method",{reason:r?"API not available":"promptSaveAs is false"});let n=URL.createObjectURL(i),s=document.createElement("a");s.style.display="none",s.href=n,s.download=o,document.body.appendChild(s),s.click(),setTimeout(()=>{URL.revokeObjectURL(n),document.body.removeChild(s),l.debug("File saved successfully using legacy method")},100)}catch(e){throw l.debug("Error saving file:",e),e}}export{n as saveFile};