@apeleghq/multipart-parser
Version:
TypeScript streaming parser for MIME multipart messages
4 lines (3 loc) • 2.85 kB
JavaScript
var M=/^[0-9a-zA-Z'()+_,\-./:=? ]{0,69}[0-9a-zA-Z'()+_,\-./:=?]$/,I=/;\s*boundary=(?:"([0-9a-zA-Z'()+_,\-./:=? ]{0,69}[0-9a-zA-Z'()+_,\-./:=?])"|([0-9a-zA-Z'+_\-.]{0,69}[0-9a-zA-Z'+_\-.]))/;var v=e=>new ReadableStream({pull(t){if(ArrayBuffer.isView(e))t.enqueue(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));else if(e instanceof ArrayBuffer)t.enqueue(e);else throw new TypeError("Expected ArrayBuffer or an ArrayBuffer view.");t.close()}}),L=v;var N=(e,n)=>{e:for(let t=0;t<=e.length-n.length;t++){for(let s=0;s<n.length;s++)if(e[t+s]!==n[s])continue e;return t}return-1},c=N;var _=(e,...n)=>{let t=n.reduce((a,l)=>a+l.byteLength,e.length),s=new(Object(n[0])).constructor(t);s.set(e);let y=e.length;return n.forEach(a=>{s.set(a,y),y+=a.byteLength}),s},P=_;var B=new TextDecoder,k=new TextEncoder,g=k.encode(`\r
`),G=[9,32],j=(e,n)=>{let t=0,s=[];for(;(t=c(e,g))!==-1&&t!==0;){let a=e.indexOf(58);if(a===-1)throw new Error("Invalid header");let l=B.decode(e.subarray(0,a));for(;G.includes(e[t+2]);){let d=c(e.subarray(t+2),g);if(d<1)break;t+=2+d}let r=B.decode(e.subarray(a+1,t)).replace(/\r\n/g,"");s.push([l,r]),e=e.subarray(t+g.length)}return{headers:n?n(s):(()=>{let a=new Headers(s);return a.has("content-transfer-encoding")||a.set("content-transfer-encoding","7bit"),a.has("content-type")||a.set("content-type","text/plain; charset=us-ascii"),a})(),body:t===-1?null:e.subarray(t+g.length)}},S=j;async function*O(e,n,t){var w;if(!M.test(n))throw new Error("Invalid boundary delimiter");let s=new TextEncoder,y=[9,32],a=new Uint8Array([13,10]),l=s.encode(`\r
--${n}`),r=new Uint8Array,d=0,E=!1,b=e.getReader();try{for(;d!==3;){let{done:A,value:u}=await b.read();if(A){if(r.length===0||E)throw new Error("Invalid message");E=!0}else r=P(r,ArrayBuffer.isView(u)?new Uint8Array(u.buffer,u.byteOffset,u.byteLength):new Uint8Array(u));for(;r.length>0;){let i=NaN;if(d===0&&(i=c(r,l.slice(2))-2,i===-3)||(i!==-2&&(i=c(r,l)),i===-1))break;let o=i+l.length,p=A?0:c(r.subarray(o,o+32),a);if(p===-1&&r.length-o<32)break;if(p===-1||!Array.from(r.subarray(o+Math.min(2,p),o+p)).every(T=>y.includes(T)))throw new Error(`Invalid boundary at index ${i}`);if(A||p>=2){if([1,2].includes(d)&&r[o+0]===r[o+1]&&r[o+0]===45)d=3;else if(!y.includes(r[o+0])||!y.includes(r[o+1]))throw new Error(`Invalid boundary at index ${i} (${n}): ${(w=r[o+1])==null?void 0:w.toString(16)}`)}switch(d){case 0:d=1;break;case 1:d=2;case 2:case 3:if(r.subarray(i,o).length>0){let T=r.subarray(0,i),f=S(T,t),h=f.headers.get("content-type"),x;if(f.body&&(h!=null&&h.startsWith("multipart/"))){let m=h.match(I);if(m){let U=m[1]||m[2];x=O(L(f.body),U)}else x=null}yield{headers:f.headers,body:f.body,...x!==void 0&&{parts:x}}}break}if(d===3){r=r.subarray(r.length);break}r=r.subarray(p+o+2)}}}finally{b.releaseLock()}}var R=O;export{R as default,R as parseMultipartMessage};