You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
40 lines
2.3 KiB
40 lines
2.3 KiB
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ |
|
|
|
import C from 'fetch-blob' |
|
import F from 'fetch-blob/file.js' |
|
|
|
var {toStringTag:t,iterator:i,hasInstance:h}=Symbol, |
|
r=Math.random, |
|
m='append,set,get,getAll,delete,keys,values,entries,forEach,constructor'.split(','), |
|
f=(a,b,c)=>(a+='',/^(Blob|File)$/.test(b && b[t])?[(c=c!==void 0?c+'':b[t]=='File'?b.name:'blob',a),b.name!==c||b[t]=='blob'?new F([b],c,b):b]:[a,b+'']), |
|
e=(c,f)=>(f?c:c.replace(/\r?\n|\r/g,'\r\n')).replace(/\n/g,'%0A').replace(/\r/g,'%0D').replace(/"/g,'%22'), |
|
x=(n, a, e)=>{if(a.length<e){throw new TypeError(`Failed to execute '${n}' on 'FormData': ${e} arguments required, but only ${a.length} present.`)}} |
|
|
|
export const File = F |
|
|
|
/** @type {typeof globalThis.FormData} */ |
|
export const FormData = class FormData { |
|
#d=[]; |
|
constructor(...a){if(a.length)throw new TypeError(`Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'.`)} |
|
get [t]() {return 'FormData'} |
|
[i](){return this.entries()} |
|
static [h](o) {return o&&typeof o==='object'&&o[t]==='FormData'&&!m.some(m=>typeof o[m]!='function')} |
|
append(...a){x('append',arguments,2);this.#d.push(f(...a))} |
|
delete(a){x('delete',arguments,1);a+='';this.#d=this.#d.filter(([b])=>b!==a)} |
|
get(a){x('get',arguments,1);a+='';for(var b=this.#d,l=b.length,c=0;c<l;c++)if(b[c][0]===a)return b[c][1];return null} |
|
getAll(a,b){x('getAll',arguments,1);b=[];a+='';this.#d.forEach(c=>c[0]===a&&b.push(c[1]));return b} |
|
has(a){x('has',arguments,1);a+='';return this.#d.some(b=>b[0]===a)} |
|
forEach(a,b){x('forEach',arguments,1);for(var [c,d]of this)a.call(b,d,c,this)} |
|
set(...a){x('set',arguments,2);var b=[],c=!0;a=f(...a);this.#d.forEach(d=>{d[0]===a[0]?c&&(c=!b.push(a)):b.push(d)});c&&b.push(a);this.#d=b} |
|
*entries(){yield*this.#d} |
|
*keys(){for(var[a]of this)yield a} |
|
*values(){for(var[,a]of this)yield a}} |
|
|
|
/** @param {FormData} F */ |
|
export function formDataToBlob (F,B=C){ |
|
var b=`${r()}${r()}`.replace(/\./g, '').slice(-28).padStart(32, '-'),c=[],p=`--${b}\r\nContent-Disposition: form-data; name="` |
|
F.forEach((v,n)=>typeof v=='string' |
|
?c.push(p+e(n)+`"\r\n\r\n${v.replace(/\r(?!\n)|(?<!\r)\n/g, '\r\n')}\r\n`) |
|
:c.push(p+e(n)+`"; filename="${e(v.name, 1)}"\r\nContent-Type: ${v.type||"application/octet-stream"}\r\n\r\n`, v, '\r\n')) |
|
c.push(`--${b}--`) |
|
return new B(c,{type:"multipart/form-data; boundary="+b})}
|
|
|