UNPKG

@apeleghq/multipart-parser

Version:

TypeScript streaming parser for MIME multipart messages

5 lines (4 loc) 2.54 kB
var m=/;\s*boundary=(?:"([0-9a-zA-Z'()+_,\-./:=? ]{0,69}[0-9a-zA-Z'()+_,\-./:=?])"|([0-9a-zA-Z'+_\-.]{0,69}[0-9a-zA-Z'+_\-.]))/;var M=a=>new ReadableStream({pull(r){if(ArrayBuffer.isView(a))r.enqueue(a.buffer.slice(a.byteOffset,a.byteOffset+a.byteLength));else if(a instanceof ArrayBuffer)r.enqueue(a);else throw new TypeError("Expected ArrayBuffer or an ArrayBuffer view.");r.close()}}),u=M;var T=/;\s*boundary=(?:"([^"]+)"|([^;",]+))/,h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-.",A=()=>{let a=new Uint8Array(24);return globalThis.crypto.getRandomValues(a),Array.from(a).map(s=>h[s%h.length]).join("")},i={preventClose:!0};async function*g(a,s,r){let d=new TextEncoder,y=d.encode(`\r --${a}`);if(Array.isArray(s)&&s.length<1){await r.abort(Error("At least one part is required"));return}let l=0;for await(let e of s){l++;let n,t;if(!e.body&&e.parts)if(t=e.headers.get("content-type"),!t)n=A(),t=`multipart/mixed; boundary="${n}"`;else if(!t.startsWith("multipart/")||!T.test(t)){await r.abort(Error("Invalid multipart content type: "+t));return}else{let o=t.match(m);(!o||!(n=o[1]||o[2]))&&(n=A(),t=t.replace(T,`; boundary="${n}"`))}await u(y).pipeTo(r,i),yield;{let o=[""];if(t){let p=!1;e.headers.forEach((f,c)=>{c!=="content-type"?o.push(`${c}: ${f}`):(p=!0,o.push(`${c}: ${t}`))}),p||o.push(`content-type: ${t}`)}else e.headers.forEach((p,f)=>{o.push(`${f}: ${p}`)});e.parts||!e.body?o.push(""):o.push("","");let B=d.encode(o.join(`\r `));o.length=0,await u(B).pipeTo(r,i),yield}if(e.body){if(e.body instanceof ArrayBuffer||ArrayBuffer.isView(e.body))await u(e.body).pipeTo(r,i);else if(e.body instanceof Blob)await e.body.stream().pipeTo(r,i);else if(e.body instanceof ReadableStream)await e.body.pipeTo(r,i);else{await r.abort(Error("Invalid body type"));return}yield}else if(e.parts){if(!n){await r.abort(Error("Runtime exception: undefined part boundary"));return}yield*g(n,e.parts,r),yield}}if(!l){await r.abort(Error("At least one part is required"));return}let b=d.encode(`\r --${a}--`);await u(b).pipeTo(r,i)}var w=(a,s)=>{let r=new TransformStream,d=g(a,s,r.writable),y=!1,l=r.readable.getReader();return new ReadableStream({start(e){(async()=>{for(;;)try{let n=await l.read();if(n.done){let t=new Uint8Array([13,10]);e.enqueue(t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)),e.close();return}e.enqueue(n.value)}catch(n){e.error(n);return}})().catch(()=>{})},async pull(){if(y)return;(await d.next()).done&&(y=!0,await r.writable.close())}})},x=w;export{x as default,x as encodeMultipartMessage};