mhtml-stream 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,3 +25,11 @@ for await (const { headers, content } of parseMhtml(...)) {
25
25
  // for how to parse each individual included file.
26
26
  }
27
27
  ```
28
+
29
+ Notes
30
+ -----
31
+
32
+ - As far as I can tell, header folding behavior is not well defined when it
33
+ comes to whether whitespace should be added when unfolding. This currently
34
+ uses the first whitespace character to indicate folding, and preservers any
35
+ others.
@@ -0,0 +1 @@
1
+ var Q=Object.create;var h=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var V=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),_=(t,e)=>{for(var r in e)h(t,r,{get:e[r],enumerable:!0})},x=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of W(e))!J.call(t,o)&&o!==r&&h(t,o,{get:()=>e[o],enumerable:!(n=R(e,o))||n.enumerable});return t};var U=(t,e,r)=>(r=t!=null?Q(N(t)):{},x(e||!t||!t.__esModule?h(r,"default",{value:t,enumerable:!0}):r,t)),z=t=>x(h({},"__esModule",{value:!0}),t);var w=V(g=>{"use strict";g.byteLength=K;g.toByteArray=Y;g.fromByteArray=te;var c=[],d=[],G=typeof Uint8Array<"u"?Uint8Array:Array,b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(f=0,F=b.length;f<F;++f)c[f]=b[f],d[b.charCodeAt(f)]=f;var f,F;d["-".charCodeAt(0)]=62;d["_".charCodeAt(0)]=63;function B(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");r===-1&&(r=e);var n=r===e?0:4-r%4;return[r,n]}function K(t){var e=B(t),r=e[0],n=e[1];return(r+n)*3/4-n}function X(t,e,r){return(e+r)*3/4-r}function Y(t){var e,r=B(t),n=r[0],o=r[1],a=new G(X(t,n,o)),s=0,i=o>0?n-4:n,l;for(l=0;l<i;l+=4)e=d[t.charCodeAt(l)]<<18|d[t.charCodeAt(l+1)]<<12|d[t.charCodeAt(l+2)]<<6|d[t.charCodeAt(l+3)],a[s++]=e>>16&255,a[s++]=e>>8&255,a[s++]=e&255;return o===2&&(e=d[t.charCodeAt(l)]<<2|d[t.charCodeAt(l+1)]>>4,a[s++]=e&255),o===1&&(e=d[t.charCodeAt(l)]<<10|d[t.charCodeAt(l+1)]<<4|d[t.charCodeAt(l+2)]>>2,a[s++]=e>>8&255,a[s++]=e&255),a}function Z(t){return c[t>>18&63]+c[t>>12&63]+c[t>>6&63]+c[t&63]}function ee(t,e,r){for(var n,o=[],a=e;a<r;a+=3)n=(t[a]<<16&16711680)+(t[a+1]<<8&65280)+(t[a+2]&255),o.push(Z(n));return o.join("")}function te(t){for(var e,r=t.length,n=r%3,o=[],a=16383,s=0,i=r-n;s<i;s+=a)o.push(ee(t,s,s+a>i?i:s+a));return n===1?(e=t[r-1],o.push(c[e>>2]+c[e<<4&63]+"==")):n===2&&(e=(t[r-2]<<8)+t[r-1],o.push(c[e>>10]+c[e>>4&63]+c[e<<2&63]+"=")),o.join("")}});var ue={};_(ue,{parseMhtml:()=>fe});module.exports=z(ue);var q=U(w());var p=class{#e=new Map;[Symbol.iterator](){return this.entries()}append(e,r){let n=this.#e.get(e);n===void 0?this.#e.set(e,[r]):n.push(r)}*entries(e=", "){for(let[r,n]of this.#e.entries())yield[r,n.join(e)]}*entriesAll(){for(let[e,r]of this.#e.entries())for(let n of r)yield[e,n]}get(e,r=", "){let n=this.#e.get(e);return n===void 0?null:n.join(r)}getAll(e){return this.#e.get(e)??[]}has(e){return this.#e.has(e)}keys(){return this.#e.keys()}*values(e=", "){for(let r of this.#e.values())yield r.join(e)}*valuesAll(){for(let e of this.#e.values())yield*e}};var C=U(w());function re(t){return ArrayBuffer.isView(t)?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t)}function v(t,e){if(t.length!==e.length)return!1;if(t.byteOffset%4===e.byteOffset%4){let r=(4-t.byteOffset%4)%4,n=Math.floor((t.byteLength-r)/4),o=r+n*4,a=new Uint32Array(t.buffer,t.byteOffset+r,n),s=new Uint32Array(e.buffer,e.byteOffset+r,n);for(let i=0;i<r;++i)if(t[i]!==e[i])return!1;for(let i=0;i<n;++i)if(a[i]!==s[i])return!1;for(let i=o;i<t.length;++i)if(t[i]!==e[i])return!1;return!0}else{for(let r of t.keys())if(t[r]!==e[r])return!1;return!0}}function k(t){return{[Symbol.asyncIterator](){let e=t.getReader();return{async next(){let r=await e.read();return r.done?{done:!0,value:void 0}:{done:!1,value:r.value}}}}}}function ne(t,e){return t.findIndex((r,n)=>{if(r!==e[0]||n+e.length>t.length)return!1;for(let o=1;o<e.length;++o)if(t[n+o]!==e[o])return!1;return!0})}async function*E(t,e){let r=new Uint8Array(0);for await(let n of t){let o=re(n);r=r.length?M([r,o]):o;let a;for(;(a=ne(r,e))!==-1;)yield r.subarray(0,a),r=r.subarray(a+e.length)}yield r}function M(t){let e=t.reduce((o,a)=>o+a.length,0),r=new Uint8Array(e),n=0;for(let o of t)r.set(o,n),n+=o.length;return r}async function L(t){let e=[];for await(let r of t)e.push(r);return M(e)}var oe=new Uint8Array([10]);async function*O(t,e=oe){for await(let r of t){let n=new Uint8Array(r.length+e.length),o=!1,a=0;for(let s=0;s<r.length;++s){let i=r[s];if(i>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${r}`);if(i!==61)n[a++]=i;else{let l=r[++s];if(l===void 0)o=!0;else{let y=r[++s];if(y===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let u=parseInt(String.fromCharCode(l),16);u*=16,u+=parseInt(String.fromCharCode(y),16),n[a++]=u}}}o||(n.set(e,a),a+=e.length),yield n.subarray(0,a)}}var ae=new TextDecoder;async function*T(t){for await(let e of t)yield(0,C.toByteArray)(ae.decode(e))}async function*m(t){for await(let e of t)yield e}function H(){throw new Error("binary transfer-encoding is explicitly not supported and trying to add an implementation will likely result in unexpected results, but if you want to ignore anyway, set binary to `decode8bit`")}var S=new TextEncoder,D=new TextDecoder;function se(t){let e=new Uint8Array(t.length),r=0;for(let n=0;n<t.length;++n){let o=t.charCodeAt(n),a;if(o>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${t}"`);o===95?a=32:o===61?(a=parseInt(t[++n],16),a*=16,a+=parseInt(t[++n],16)):a=o,e[r++]=a}return e.subarray(0,r)}var ie=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function $(t){let e=ie.exec(t);if(e){let[,r,n,o]=e,a;if(n==="Q")a=se(o);else if(n==="B")a=(0,q.toByteArray)(o);else throw new Error(`unknown encoding for header value encoding: ${n}`);return new TextDecoder(r).decode(a)}else return t}async function le(t){let e=new p,r="",n="";for(;;){let{done:o,value:a}=await t.next();if(o)throw new Error("didn't find an empty line to signify the end of header parsing");let s=D.decode(a);if(/^\s/.test(s))n+=$(s.substr(1));else if(r&&e.append(r,n),s){let i=s.indexOf(": ");if(i===-1)throw new Error(`header line didn't have key-value delimiter: "${s}"`);r=s.slice(0,i),n=$(s.slice(i+2))}else return e}}var de=new Map([["7bit",m],["base64",T],["quoted-printable",O],["8bit",m],["binary",H]]);function ce(t){let e=t.get("Content-Type");if(e===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(t))}`);let r,n=!1;for(let s of e.split(/;\s*/))s.startsWith("multipart/")?n=!0:s.startsWith("boundary=")&&(r=s.slice(9),r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)));if(!n||r===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let o=S.encode(`--${r}`),a=S.encode(`--${r}--`);return[o,a]}async function*fe(t,{decoderOverrides:e=new Map}={}){let r=new Map([...de.entries(),...e.entries()]),n=new Uint8Array([13,10]),o=E(k(t),n),a=null,s=!0;for(;s;){let i=await le(o),[l,y]=a??(a=ce(i)),u=i.get("Content-Transfer-Encoding")??"7bit",I=r.get(u);if(I===void 0)throw new Error(`unhandled encoding type: ${u}`);let P=await L(I({[Symbol.asyncIterator](){return{async next(){let{done:j,value:A}=await o.next();if(j)throw new Error(`stream didn't end with the appropriate termination boundary: ${D.decode(y)}`);return v(A,l)?{done:!0,value:void 0}:v(A,y)?(s=!1,{done:!0,value:void 0}):{value:A}}}}}));yield{headers:i,content:P}}}0&&(module.exports={parseMhtml});
@@ -0,0 +1 @@
1
+ var j=Object.create;var I=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var J=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var V=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of R(e))!N.call(t,o)&&o!==r&&I(t,o,{get:()=>e[o],enumerable:!(n=Q(e,o))||n.enumerable});return t};var x=(t,e,r)=>(r=t!=null?j(W(t)):{},V(e||!t||!t.__esModule?I(r,"default",{value:t,enumerable:!0}):r,t));var b=J(h=>{"use strict";h.byteLength=z;h.toByteArray=K;h.fromByteArray=Z;var c=[],d=[],_=typeof Uint8Array<"u"?Uint8Array:Array,A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(f=0,U=A.length;f<U;++f)c[f]=A[f],d[A.charCodeAt(f)]=f;var f,U;d["-".charCodeAt(0)]=62;d["_".charCodeAt(0)]=63;function F(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");r===-1&&(r=e);var n=r===e?0:4-r%4;return[r,n]}function z(t){var e=F(t),r=e[0],n=e[1];return(r+n)*3/4-n}function G(t,e,r){return(e+r)*3/4-r}function K(t){var e,r=F(t),n=r[0],o=r[1],a=new _(G(t,n,o)),s=0,i=o>0?n-4:n,l;for(l=0;l<i;l+=4)e=d[t.charCodeAt(l)]<<18|d[t.charCodeAt(l+1)]<<12|d[t.charCodeAt(l+2)]<<6|d[t.charCodeAt(l+3)],a[s++]=e>>16&255,a[s++]=e>>8&255,a[s++]=e&255;return o===2&&(e=d[t.charCodeAt(l)]<<2|d[t.charCodeAt(l+1)]>>4,a[s++]=e&255),o===1&&(e=d[t.charCodeAt(l)]<<10|d[t.charCodeAt(l+1)]<<4|d[t.charCodeAt(l+2)]>>2,a[s++]=e>>8&255,a[s++]=e&255),a}function X(t){return c[t>>18&63]+c[t>>12&63]+c[t>>6&63]+c[t&63]}function Y(t,e,r){for(var n,o=[],a=e;a<r;a+=3)n=(t[a]<<16&16711680)+(t[a+1]<<8&65280)+(t[a+2]&255),o.push(X(n));return o.join("")}function Z(t){for(var e,r=t.length,n=r%3,o=[],a=16383,s=0,i=r-n;s<i;s+=a)o.push(Y(t,s,s+a>i?i:s+a));return n===1?(e=t[r-1],o.push(c[e>>2]+c[e<<4&63]+"==")):n===2&&(e=(t[r-2]<<8)+t[r-1],o.push(c[e>>10]+c[e>>4&63]+c[e<<2&63]+"=")),o.join("")}});var $=x(b());var g=class{#e=new Map;[Symbol.iterator](){return this.entries()}append(e,r){let n=this.#e.get(e);n===void 0?this.#e.set(e,[r]):n.push(r)}*entries(e=", "){for(let[r,n]of this.#e.entries())yield[r,n.join(e)]}*entriesAll(){for(let[e,r]of this.#e.entries())for(let n of r)yield[e,n]}get(e,r=", "){let n=this.#e.get(e);return n===void 0?null:n.join(r)}getAll(e){return this.#e.get(e)??[]}has(e){return this.#e.has(e)}keys(){return this.#e.keys()}*values(e=", "){for(let r of this.#e.values())yield r.join(e)}*valuesAll(){for(let e of this.#e.values())yield*e}};var B=x(b());function ee(t){return ArrayBuffer.isView(t)?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t)}function w(t,e){if(t.length!==e.length)return!1;if(t.byteOffset%4===e.byteOffset%4){let r=(4-t.byteOffset%4)%4,n=Math.floor((t.byteLength-r)/4),o=r+n*4,a=new Uint32Array(t.buffer,t.byteOffset+r,n),s=new Uint32Array(e.buffer,e.byteOffset+r,n);for(let i=0;i<r;++i)if(t[i]!==e[i])return!1;for(let i=0;i<n;++i)if(a[i]!==s[i])return!1;for(let i=o;i<t.length;++i)if(t[i]!==e[i])return!1;return!0}else{for(let r of t.keys())if(t[r]!==e[r])return!1;return!0}}function C(t){return{[Symbol.asyncIterator](){let e=t.getReader();return{async next(){let r=await e.read();return r.done?{done:!0,value:void 0}:{done:!1,value:r.value}}}}}}function te(t,e){return t.findIndex((r,n)=>{if(r!==e[0]||n+e.length>t.length)return!1;for(let o=1;o<e.length;++o)if(t[n+o]!==e[o])return!1;return!0})}async function*k(t,e){let r=new Uint8Array(0);for await(let n of t){let o=ee(n);r=r.length?E([r,o]):o;let a;for(;(a=te(r,e))!==-1;)yield r.subarray(0,a),r=r.subarray(a+e.length)}yield r}function E(t){let e=t.reduce((o,a)=>o+a.length,0),r=new Uint8Array(e),n=0;for(let o of t)r.set(o,n),n+=o.length;return r}async function M(t){let e=[];for await(let r of t)e.push(r);return E(e)}var re=new Uint8Array([10]);async function*L(t,e=re){for await(let r of t){let n=new Uint8Array(r.length+e.length),o=!1,a=0;for(let s=0;s<r.length;++s){let i=r[s];if(i>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${r}`);if(i!==61)n[a++]=i;else{let l=r[++s];if(l===void 0)o=!0;else{let y=r[++s];if(y===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let u=parseInt(String.fromCharCode(l),16);u*=16,u+=parseInt(String.fromCharCode(y),16),n[a++]=u}}}o||(n.set(e,a),a+=e.length),yield n.subarray(0,a)}}var ne=new TextDecoder;async function*O(t){for await(let e of t)yield(0,B.toByteArray)(ne.decode(e))}async function*v(t){for await(let e of t)yield e}function T(){throw new Error("binary transfer-encoding is explicitly not supported and trying to add an implementation will likely result in unexpected results, but if you want to ignore anyway, set binary to `decode8bit`")}var H=new TextEncoder,q=new TextDecoder;function oe(t){let e=new Uint8Array(t.length),r=0;for(let n=0;n<t.length;++n){let o=t.charCodeAt(n),a;if(o>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${t}"`);o===95?a=32:o===61?(a=parseInt(t[++n],16),a*=16,a+=parseInt(t[++n],16)):a=o,e[r++]=a}return e.subarray(0,r)}var ae=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function S(t){let e=ae.exec(t);if(e){let[,r,n,o]=e,a;if(n==="Q")a=oe(o);else if(n==="B")a=(0,$.toByteArray)(o);else throw new Error(`unknown encoding for header value encoding: ${n}`);return new TextDecoder(r).decode(a)}else return t}async function se(t){let e=new g,r="",n="";for(;;){let{done:o,value:a}=await t.next();if(o)throw new Error("didn't find an empty line to signify the end of header parsing");let s=q.decode(a);if(/^\s/.test(s))n+=S(s.substr(1));else if(r&&e.append(r,n),s){let i=s.indexOf(": ");if(i===-1)throw new Error(`header line didn't have key-value delimiter: "${s}"`);r=s.slice(0,i),n=S(s.slice(i+2))}else return e}}var ie=new Map([["7bit",v],["base64",O],["quoted-printable",L],["8bit",v],["binary",T]]);function le(t){let e=t.get("Content-Type");if(e===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(t))}`);let r,n=!1;for(let s of e.split(/;\s*/))s.startsWith("multipart/")?n=!0:s.startsWith("boundary=")&&(r=s.slice(9),r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)));if(!n||r===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let o=H.encode(`--${r}`),a=H.encode(`--${r}--`);return[o,a]}async function*pe(t,{decoderOverrides:e=new Map}={}){let r=new Map([...ie.entries(),...e.entries()]),n=new Uint8Array([13,10]),o=k(C(t),n),a=null,s=!0;for(;s;){let i=await se(o),[l,y]=a??(a=le(i)),u=i.get("Content-Transfer-Encoding")??"7bit",m=r.get(u);if(m===void 0)throw new Error(`unhandled encoding type: ${u}`);let D=await M(m({[Symbol.asyncIterator](){return{async next(){let{done:P,value:p}=await o.next();if(P)throw new Error(`stream didn't end with the appropriate termination boundary: ${q.decode(y)}`);return w(p,l)?{done:!0,value:void 0}:w(p,y)?(s=!1,{done:!0,value:void 0}):{value:p}}}}}));yield{headers:i,content:D}}}export{pe as parseMhtml};
@@ -0,0 +1 @@
1
+ var mhtml=(()=>{var Q=Object.create;var h=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var V=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),_=(t,e)=>{for(var r in e)h(t,r,{get:e[r],enumerable:!0})},x=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of W(e))!J.call(t,o)&&o!==r&&h(t,o,{get:()=>e[o],enumerable:!(n=R(e,o))||n.enumerable});return t};var U=(t,e,r)=>(r=t!=null?Q(N(t)):{},x(e||!t||!t.__esModule?h(r,"default",{value:t,enumerable:!0}):r,t)),z=t=>x(h({},"__esModule",{value:!0}),t);var w=V(g=>{"use strict";g.byteLength=K;g.toByteArray=Y;g.fromByteArray=te;var c=[],d=[],G=typeof Uint8Array<"u"?Uint8Array:Array,b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(f=0,F=b.length;f<F;++f)c[f]=b[f],d[b.charCodeAt(f)]=f;var f,F;d["-".charCodeAt(0)]=62;d["_".charCodeAt(0)]=63;function B(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");r===-1&&(r=e);var n=r===e?0:4-r%4;return[r,n]}function K(t){var e=B(t),r=e[0],n=e[1];return(r+n)*3/4-n}function X(t,e,r){return(e+r)*3/4-r}function Y(t){var e,r=B(t),n=r[0],o=r[1],a=new G(X(t,n,o)),s=0,i=o>0?n-4:n,l;for(l=0;l<i;l+=4)e=d[t.charCodeAt(l)]<<18|d[t.charCodeAt(l+1)]<<12|d[t.charCodeAt(l+2)]<<6|d[t.charCodeAt(l+3)],a[s++]=e>>16&255,a[s++]=e>>8&255,a[s++]=e&255;return o===2&&(e=d[t.charCodeAt(l)]<<2|d[t.charCodeAt(l+1)]>>4,a[s++]=e&255),o===1&&(e=d[t.charCodeAt(l)]<<10|d[t.charCodeAt(l+1)]<<4|d[t.charCodeAt(l+2)]>>2,a[s++]=e>>8&255,a[s++]=e&255),a}function Z(t){return c[t>>18&63]+c[t>>12&63]+c[t>>6&63]+c[t&63]}function ee(t,e,r){for(var n,o=[],a=e;a<r;a+=3)n=(t[a]<<16&16711680)+(t[a+1]<<8&65280)+(t[a+2]&255),o.push(Z(n));return o.join("")}function te(t){for(var e,r=t.length,n=r%3,o=[],a=16383,s=0,i=r-n;s<i;s+=a)o.push(ee(t,s,s+a>i?i:s+a));return n===1?(e=t[r-1],o.push(c[e>>2]+c[e<<4&63]+"==")):n===2&&(e=(t[r-2]<<8)+t[r-1],o.push(c[e>>10]+c[e>>4&63]+c[e<<2&63]+"=")),o.join("")}});var ue={};_(ue,{parseMhtml:()=>fe});var q=U(w());var p=class{#e=new Map;[Symbol.iterator](){return this.entries()}append(e,r){let n=this.#e.get(e);n===void 0?this.#e.set(e,[r]):n.push(r)}*entries(e=", "){for(let[r,n]of this.#e.entries())yield[r,n.join(e)]}*entriesAll(){for(let[e,r]of this.#e.entries())for(let n of r)yield[e,n]}get(e,r=", "){let n=this.#e.get(e);return n===void 0?null:n.join(r)}getAll(e){return this.#e.get(e)??[]}has(e){return this.#e.has(e)}keys(){return this.#e.keys()}*values(e=", "){for(let r of this.#e.values())yield r.join(e)}*valuesAll(){for(let e of this.#e.values())yield*e}};var C=U(w());function re(t){return ArrayBuffer.isView(t)?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):new Uint8Array(t)}function v(t,e){if(t.length!==e.length)return!1;if(t.byteOffset%4===e.byteOffset%4){let r=(4-t.byteOffset%4)%4,n=Math.floor((t.byteLength-r)/4),o=r+n*4,a=new Uint32Array(t.buffer,t.byteOffset+r,n),s=new Uint32Array(e.buffer,e.byteOffset+r,n);for(let i=0;i<r;++i)if(t[i]!==e[i])return!1;for(let i=0;i<n;++i)if(a[i]!==s[i])return!1;for(let i=o;i<t.length;++i)if(t[i]!==e[i])return!1;return!0}else{for(let r of t.keys())if(t[r]!==e[r])return!1;return!0}}function k(t){return{[Symbol.asyncIterator](){let e=t.getReader();return{async next(){let r=await e.read();return r.done?{done:!0,value:void 0}:{done:!1,value:r.value}}}}}}function ne(t,e){return t.findIndex((r,n)=>{if(r!==e[0]||n+e.length>t.length)return!1;for(let o=1;o<e.length;++o)if(t[n+o]!==e[o])return!1;return!0})}async function*E(t,e){let r=new Uint8Array(0);for await(let n of t){let o=re(n);r=r.length?M([r,o]):o;let a;for(;(a=ne(r,e))!==-1;)yield r.subarray(0,a),r=r.subarray(a+e.length)}yield r}function M(t){let e=t.reduce((o,a)=>o+a.length,0),r=new Uint8Array(e),n=0;for(let o of t)r.set(o,n),n+=o.length;return r}async function L(t){let e=[];for await(let r of t)e.push(r);return M(e)}var oe=new Uint8Array([10]);async function*O(t,e=oe){for await(let r of t){let n=new Uint8Array(r.length+e.length),o=!1,a=0;for(let s=0;s<r.length;++s){let i=r[s];if(i>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${r}`);if(i!==61)n[a++]=i;else{let l=r[++s];if(l===void 0)o=!0;else{let y=r[++s];if(y===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let u=parseInt(String.fromCharCode(l),16);u*=16,u+=parseInt(String.fromCharCode(y),16),n[a++]=u}}}o||(n.set(e,a),a+=e.length),yield n.subarray(0,a)}}var ae=new TextDecoder;async function*T(t){for await(let e of t)yield(0,C.toByteArray)(ae.decode(e))}async function*m(t){for await(let e of t)yield e}function H(){throw new Error("binary transfer-encoding is explicitly not supported and trying to add an implementation will likely result in unexpected results, but if you want to ignore anyway, set binary to `decode8bit`")}var S=new TextEncoder,D=new TextDecoder;function se(t){let e=new Uint8Array(t.length),r=0;for(let n=0;n<t.length;++n){let o=t.charCodeAt(n),a;if(o>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${t}"`);o===95?a=32:o===61?(a=parseInt(t[++n],16),a*=16,a+=parseInt(t[++n],16)):a=o,e[r++]=a}return e.subarray(0,r)}var ie=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function $(t){let e=ie.exec(t);if(e){let[,r,n,o]=e,a;if(n==="Q")a=se(o);else if(n==="B")a=(0,q.toByteArray)(o);else throw new Error(`unknown encoding for header value encoding: ${n}`);return new TextDecoder(r).decode(a)}else return t}async function le(t){let e=new p,r="",n="";for(;;){let{done:o,value:a}=await t.next();if(o)throw new Error("didn't find an empty line to signify the end of header parsing");let s=D.decode(a);if(/^\s/.test(s))n+=$(s.substr(1));else if(r&&e.append(r,n),s){let i=s.indexOf(": ");if(i===-1)throw new Error(`header line didn't have key-value delimiter: "${s}"`);r=s.slice(0,i),n=$(s.slice(i+2))}else return e}}var de=new Map([["7bit",m],["base64",T],["quoted-printable",O],["8bit",m],["binary",H]]);function ce(t){let e=t.get("Content-Type");if(e===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(t))}`);let r,n=!1;for(let s of e.split(/;\s*/))s.startsWith("multipart/")?n=!0:s.startsWith("boundary=")&&(r=s.slice(9),r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)));if(!n||r===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let o=S.encode(`--${r}`),a=S.encode(`--${r}--`);return[o,a]}async function*fe(t,{decoderOverrides:e=new Map}={}){let r=new Map([...de.entries(),...e.entries()]),n=new Uint8Array([13,10]),o=E(k(t),n),a=null,s=!0;for(;s;){let i=await le(o),[l,y]=a??(a=ce(i)),u=i.get("Content-Transfer-Encoding")??"7bit",I=r.get(u);if(I===void 0)throw new Error(`unhandled encoding type: ${u}`);let P=await L(I({[Symbol.asyncIterator](){return{async next(){let{done:j,value:A}=await o.next();if(j)throw new Error(`stream didn't end with the appropriate termination boundary: ${D.decode(y)}`);return v(A,l)?{done:!0,value:void 0}:v(A,y)?(s=!1,{done:!0,value:void 0}):{value:A}}}}}));yield{headers:i,content:P}}}return z(ue);})();
@@ -0,0 +1,62 @@
1
+ /**
2
+ * class for storing headers parse from MHTML
3
+ *
4
+ * Tries to somewhat mimic the behavior of the fetch-api Headers object, with
5
+ * some differences, notably that it does no validation.
6
+ */
7
+ export interface MhtmlHeaders extends Iterable<[string, string]> {
8
+ /**
9
+ * add a key-value pair
10
+ *
11
+ * If key is already present it will be appended.
12
+ */
13
+ append(key: string, value: string): void;
14
+ /**
15
+ * iterate over all key-value pairs
16
+ *
17
+ * Multiple values for the same key will be joined in the order they were
18
+ * added by `delim`.
19
+ */
20
+ entries(delim?: string): IterableIterator<[string, string]>;
21
+ /**
22
+ * iterate over all key-value pairs
23
+ *
24
+ * Multiple values for the same key will get iterated in the order they were
25
+ * added.
26
+ */
27
+ entriesAll(): IterableIterator<[string, string]>;
28
+ /**
29
+ * get the value for a key
30
+ *
31
+ * If the key is missing, null will be returned, if multiple values for the
32
+ * key are present, they will be joined be `delim`.
33
+ */
34
+ get(key: string, delim?: string): string | null;
35
+ /** get all values for a key */
36
+ getAll(key: string): string[];
37
+ /** whether key has any values associated with it */
38
+ has(key: string): boolean;
39
+ /** all keys with at least one value */
40
+ keys(): Iterable<string>;
41
+ /**
42
+ * iterate over all values
43
+ *
44
+ * If a key has multiple values they will be joined by `delim`.
45
+ */
46
+ values(delim?: string): IterableIterator<string>;
47
+ /** iterate over all values added */
48
+ valuesAll(): IterableIterator<string>;
49
+ }
50
+ export declare class Headers implements MhtmlHeaders {
51
+ #private;
52
+ [Symbol.iterator](): Iterator<[string, string]>;
53
+ append(key: string, value: string): void;
54
+ entries(delim?: string): IterableIterator<[string, string]>;
55
+ entriesAll(): IterableIterator<[string, string]>;
56
+ get(key: string, delim?: string): string | null;
57
+ getAll(key: string): string[];
58
+ has(key: string): boolean;
59
+ keys(): Iterable<string>;
60
+ values(delim?: string): IterableIterator<string>;
61
+ valuesAll(): IterableIterator<string>;
62
+ }
@@ -0,0 +1,55 @@
1
+ export class Headers {
2
+ #raw = new Map();
3
+ [Symbol.iterator]() {
4
+ return this.entries();
5
+ }
6
+ append(key, value) {
7
+ const list = this.#raw.get(key);
8
+ if (list === undefined) {
9
+ this.#raw.set(key, [value]);
10
+ }
11
+ else {
12
+ list.push(value);
13
+ }
14
+ }
15
+ *entries(delim = ", ") {
16
+ for (const [key, values] of this.#raw.entries()) {
17
+ yield [key, values.join(delim)];
18
+ }
19
+ }
20
+ *entriesAll() {
21
+ for (const [key, values] of this.#raw.entries()) {
22
+ for (const val of values) {
23
+ yield [key, val];
24
+ }
25
+ }
26
+ }
27
+ get(key, delim = ", ") {
28
+ const vals = this.#raw.get(key);
29
+ if (vals === undefined) {
30
+ return null;
31
+ }
32
+ else {
33
+ return vals.join(delim);
34
+ }
35
+ }
36
+ getAll(key) {
37
+ return this.#raw.get(key) ?? [];
38
+ }
39
+ has(key) {
40
+ return this.#raw.has(key);
41
+ }
42
+ keys() {
43
+ return this.#raw.keys();
44
+ }
45
+ *values(delim = ", ") {
46
+ for (const vals of this.#raw.values()) {
47
+ yield vals.join(delim);
48
+ }
49
+ }
50
+ *valuesAll() {
51
+ for (const vals of this.#raw.values()) {
52
+ yield* vals;
53
+ }
54
+ }
55
+ }
package/dist/index.d.ts CHANGED
@@ -1,81 +1,25 @@
1
- /**
2
- * class for storing headers parse from MHTML
3
- *
4
- * Tries to somewhat mimic the behavior of the fetch-api Headers object, with
5
- * some differences, notably that it does no validation.
6
- */
7
- export declare class MhtmlHeaders {
8
- #private;
9
- [Symbol.iterator](): Iterator<[string, string]>;
10
- /**
11
- * add a key-value pair
12
- *
13
- * If key is already present it will be appended.
14
- */
15
- append(key: string, value: string): void;
16
- /**
17
- * iterate over all key-value pairs
18
- *
19
- * Multiple values for the same key will be joined in the order they were
20
- * added by `delim`.
21
- */
22
- entries(delim?: string): IterableIterator<[string, string]>;
23
- /**
24
- * iterate over all key-value pairs
25
- *
26
- * Multiple values for the same key will get iterated in the order they were
27
- * added.
28
- */
29
- entriesAll(): IterableIterator<[string, string]>;
30
- /**
31
- * get the value for a key
32
- *
33
- * If the key is missing, null will be returned, if multiple values for the
34
- * key are present, they will be joined be `delim`.
35
- */
36
- get(key: string, delim?: string): string | null;
37
- /**
38
- * get all values for a key
39
- */
40
- getAll(key: string): string[];
41
- /**
42
- * whether key has any values associated with it
43
- */
44
- has(key: string): boolean;
45
- /**
46
- * all keys with at least one value
47
- */
48
- keys(): Iterable<string>;
49
- /**
50
- * iterate over all values
51
- *
52
- * If a key has multiple values they will be joined by `delim`.
53
- */
54
- values(delim?: string): IterableIterator<string>;
55
- /**
56
- * iterate over all values added
57
- */
58
- valuesAll(): IterableIterator<string>;
59
- }
60
- /**
61
- * a file that was encoded in MHTML format
62
- */
1
+ import { MhtmlHeaders } from "./headers";
2
+ export type { MhtmlHeaders };
3
+ /** a file that was encoded in MHTML format */
63
4
  export interface MhtmlFile {
5
+ /** the files's headers */
64
6
  headers: MhtmlHeaders;
7
+ /** the file's content */
65
8
  content: Uint8Array;
66
9
  }
67
- /**
68
- * The decoder of any Content-Transfer-Encoding
69
- */
10
+ /** The decoder of any Content-Transfer-Encoding */
70
11
  export interface Decoder {
71
12
  (lines: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array>;
72
13
  }
14
+ /** options for mhtml parsing */
15
+ export interface ParseOptions {
16
+ /** custom decoders for other Content-Transfer-Encodings */
17
+ decoderOverrides?: Map<string, Decoder>;
18
+ }
73
19
  /**
74
20
  * parse a readable stream into an async iterator of MHTML files
75
21
  *
76
22
  * decoderOverrides can be used to overwrite default encoders or specify your
77
23
  * own if a Content-Transfer-Encoding isn't handled properly
78
24
  */
79
- export declare function parseMhtml(stream: ReadableStream<ArrayBuffer>, { decoderOverrides, }?: {
80
- decoderOverrides?: Map<string, Decoder>;
81
- }): AsyncIterableIterator<MhtmlFile>;
25
+ export declare function parseMhtml(stream: ReadableStream<ArrayBuffer>, { decoderOverrides }?: ParseOptions): AsyncIterableIterator<MhtmlFile>;
package/dist/index.js CHANGED
@@ -1,113 +1,11 @@
1
- import { decodeBase64 as decodeBEncoding } from "./base64";
1
+ import { toByteArray } from "base64-js";
2
+ import { Headers } from "./headers";
2
3
  import { asIterable, bytesEqual, collect, decodeBase64, decodeBinary, decodeIdentity, decodeQuotedPrintable, splitStream, } from "./utils";
3
4
  // NOTE we use this for ascii because it's faster than manual, but may cause
4
5
  // unexpected errors if the assumption is violated
5
6
  const encoder = new TextEncoder();
6
7
  const decoder = new TextDecoder();
7
- /**
8
- * class for storing headers parse from MHTML
9
- *
10
- * Tries to somewhat mimic the behavior of the fetch-api Headers object, with
11
- * some differences, notably that it does no validation.
12
- */
13
- export class MhtmlHeaders {
14
- #raw = new Map();
15
- [Symbol.iterator]() {
16
- return this.entries();
17
- }
18
- /**
19
- * add a key-value pair
20
- *
21
- * If key is already present it will be appended.
22
- */
23
- append(key, value) {
24
- const list = this.#raw.get(key);
25
- if (list === undefined) {
26
- this.#raw.set(key, [value]);
27
- }
28
- else {
29
- list.push(value);
30
- }
31
- }
32
- /**
33
- * iterate over all key-value pairs
34
- *
35
- * Multiple values for the same key will be joined in the order they were
36
- * added by `delim`.
37
- */
38
- *entries(delim = ", ") {
39
- for (const [key, values] of this.#raw.entries()) {
40
- yield [key, values.join(delim)];
41
- }
42
- }
43
- /**
44
- * iterate over all key-value pairs
45
- *
46
- * Multiple values for the same key will get iterated in the order they were
47
- * added.
48
- */
49
- *entriesAll() {
50
- for (const [key, values] of this.#raw.entries()) {
51
- for (const val of values) {
52
- yield [key, val];
53
- }
54
- }
55
- }
56
- /**
57
- * get the value for a key
58
- *
59
- * If the key is missing, null will be returned, if multiple values for the
60
- * key are present, they will be joined be `delim`.
61
- */
62
- get(key, delim = ", ") {
63
- const vals = this.#raw.get(key);
64
- if (vals === undefined) {
65
- return null;
66
- }
67
- else {
68
- return vals.join(delim);
69
- }
70
- }
71
- /**
72
- * get all values for a key
73
- */
74
- getAll(key) {
75
- return this.#raw.get(key) ?? [];
76
- }
77
- /**
78
- * whether key has any values associated with it
79
- */
80
- has(key) {
81
- return this.#raw.has(key);
82
- }
83
- /**
84
- * all keys with at least one value
85
- */
86
- keys() {
87
- return this.#raw.keys();
88
- }
89
- /**
90
- * iterate over all values
91
- *
92
- * If a key has multiple values they will be joined by `delim`.
93
- */
94
- *values(delim = ", ") {
95
- for (const vals of this.#raw.values()) {
96
- yield vals.join(delim);
97
- }
98
- }
99
- /**
100
- * iterate over all values added
101
- */
102
- *valuesAll() {
103
- for (const vals of this.#raw.values()) {
104
- yield* vals;
105
- }
106
- }
107
- }
108
- /**
109
- * decode a q-encoded token
110
- */
8
+ /** decode a q-encoded token */
111
9
  function decodeQEncoding(text) {
112
10
  const res = new Uint8Array(text.length);
113
11
  let destInd = 0;
@@ -136,9 +34,7 @@ function decodeQEncoding(text) {
136
34
  return res.subarray(0, destInd);
137
35
  }
138
36
  const encodeFormat = /^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;
139
- /**
140
- * decode a header line that may have an extra encoding in it
141
- */
37
+ /** decode a header line that may have an extra encoding in it */
142
38
  function decodeLine(line) {
143
39
  // TODO this might make more sense as a function as part of a regex replaceAll
144
40
  const match = encodeFormat.exec(line);
@@ -150,7 +46,7 @@ function decodeLine(line) {
150
46
  buff = decodeQEncoding(text);
151
47
  }
152
48
  else if (encoding === "B") {
153
- buff = decodeBEncoding(text);
49
+ buff = toByteArray(text);
154
50
  }
155
51
  else {
156
52
  // NOTE should be impossible
@@ -170,7 +66,7 @@ function decodeLine(line) {
170
66
  * keys instead of storing multiple
171
67
  */
172
68
  async function parseHeaders(iter) {
173
- const headers = new MhtmlHeaders();
69
+ const headers = new Headers();
174
70
  let key = "";
175
71
  let val = "";
176
72
  for (;;) {
@@ -181,8 +77,7 @@ async function parseHeaders(iter) {
181
77
  const line = decoder.decode(value);
182
78
  if (/^\s/.test(line)) {
183
79
  // header folded
184
- val += " ";
185
- val += decodeLine(line.trimStart());
80
+ val += decodeLine(line.substr(1));
186
81
  }
187
82
  else {
188
83
  if (key) {
@@ -222,7 +117,7 @@ function getBoundary(headers) {
222
117
  }
223
118
  let bound = undefined;
224
119
  let multipart = false;
225
- for (const field of contentType.split("; ")) {
120
+ for (const field of contentType.split(/;\s*/)) {
226
121
  if (field.startsWith("multipart/")) {
227
122
  multipart = true;
228
123
  }
@@ -247,7 +142,7 @@ function getBoundary(headers) {
247
142
  * decoderOverrides can be used to overwrite default encoders or specify your
248
143
  * own if a Content-Transfer-Encoding isn't handled properly
249
144
  */
250
- export async function* parseMhtml(stream, { decoderOverrides = new Map(), } = {}) {
145
+ export async function* parseMhtml(stream, { decoderOverrides = new Map() } = {}) {
251
146
  // initial setup
252
147
  const decoders = new Map([
253
148
  ...defaultDecoders.entries(),
package/dist/utils.js CHANGED
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
- import { decodeBase64 as db64 } from "./base64";
10
+ import { toByteArray } from "base64-js";
11
11
  /**
12
12
  * create a Uint8Array from a buffer
13
13
  *
@@ -199,7 +199,7 @@ const decoder = new TextDecoder();
199
199
  */
200
200
  export async function* decodeBase64(lines) {
201
201
  for await (const bytes of lines) {
202
- yield db64(decoder.decode(bytes));
202
+ yield toByteArray(decoder.decode(bytes));
203
203
  }
204
204
  }
205
205
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mhtml-stream",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Zero dependency stream MHTML parser",
5
5
  "keywords": [
6
6
  "mhtml",
@@ -12,41 +12,138 @@
12
12
  },
13
13
  "author": "Erik Brinkman <erik.brinkman@gmail.com>",
14
14
  "license": "MIT",
15
- "module": "dist/index.js",
16
15
  "types": "dist/index.d.ts",
17
- "main": "dist/index.cjs.min.js",
18
- "unpkg": "dist/index.iife.min.js",
16
+ "module": "bundle/mhtml.esm.min.js",
17
+ "main": "bundle/mhtml.cjs.min.js",
18
+ "unpkg": "bundle/mhtml.iife.min.js",
19
19
  "files": [
20
+ "/bundle/*.js",
20
21
  "/dist/**/*.js",
21
22
  "/dist/**/*.d.ts"
22
23
  ],
23
24
  "type": "module",
24
25
  "scripts": {
25
- "fmt": "prettier --write 'src/*.ts' '*.json'",
26
- "lint": "tsc && eslint 'src/*.ts'",
26
+ "fmt": "prettier --write 'src/*.ts' '*.json' bundle.mjs",
27
+ "lint": "tsc && eslint --cache 'src/*.ts' && typedoc --emit none",
27
28
  "test": "jest --coverage",
28
29
  "doc": "typedoc",
29
- "build": "tsc -p tsconfig.build.json && esbuild src/index.ts --bundle --minify --format=cjs --outfile=dist/index.cjs.min.js && esbuild src/index.ts --bundle --minify --global-name=mhtmlStream --outfile=dist/index.iife.min.js",
30
- "prepare": "yarn lint && yarn test && yarn build"
30
+ "build": "tsc -p tsconfig.build.json && node bundle.mjs",
31
+ "prepack": "yarn lint && yarn test && yarn build"
32
+ },
33
+ "dependencies": {
34
+ "base64-js": "^1.5.1"
31
35
  },
32
36
  "devDependencies": {
33
- "@types/node": "^17.0.14",
34
- "esbuild": "^0.14.17",
35
- "@babel/core": "^7.16.12",
36
- "@babel/preset-env": "^7.16.11",
37
+ "@babel/core": "^7.17.10",
38
+ "@babel/preset-env": "^7.17.10",
37
39
  "@babel/preset-typescript": "^7.16.7",
38
- "@types/jest": "^27.4.0",
39
- "@typescript-eslint/eslint-plugin": "^5.10.0",
40
- "@typescript-eslint/parser": "^5.10.0",
41
- "babel-jest": "^27.4.6",
42
- "eslint": "^8.7.0",
43
- "eslint-config-prettier": "^8.3.0",
44
- "eslint-plugin-jest": "^26.0.0",
40
+ "@types/base64-js": "^1.3.0",
41
+ "@types/jest": "^27.5.1",
42
+ "@types/node": "^17.0.33",
43
+ "@typescript-eslint/eslint-plugin": "^5.23.0",
44
+ "@typescript-eslint/parser": "^5.23.0",
45
+ "@yarnpkg/esbuild-plugin-pnp": "^2.0.2",
46
+ "babel-jest": "^28.1.0",
47
+ "chalk": "4.1.2",
48
+ "esbuild": "^0.14.39",
49
+ "eslint": "^8.15.0",
50
+ "eslint-config-prettier": "^8.5.0",
51
+ "eslint-plugin-jest": "^26.1.5",
45
52
  "eslint-plugin-spellcheck": "^0.0.19",
46
- "jest": "^27.4.7",
47
- "prettier": "^2.5.1",
53
+ "eslint-plugin-tsdoc": "^0.2.16",
54
+ "jest": "^28.1.0",
55
+ "prettier": "^2.6.2",
48
56
  "prettier-plugin-organize-imports": "^2.3.4",
49
- "typedoc": "^0.22.11",
50
- "typescript": "^4.5.5"
51
- }
52
- }
57
+ "typedoc": "^0.22.15",
58
+ "typescript": "^4.6.4"
59
+ },
60
+ "prettier": {
61
+ "plugins": [
62
+ "prettier-plugin-organize-imports"
63
+ ]
64
+ },
65
+ "jest": {
66
+ "testEnvironment": "node"
67
+ },
68
+ "babel": {
69
+ "presets": [
70
+ [
71
+ "@babel/preset-env",
72
+ {
73
+ "targets": {
74
+ "node": "current"
75
+ }
76
+ }
77
+ ],
78
+ "@babel/preset-typescript"
79
+ ]
80
+ },
81
+ "eslintConfig": {
82
+ "root": true,
83
+ "parser": "@typescript-eslint/parser",
84
+ "plugins": [
85
+ "@typescript-eslint",
86
+ "jest",
87
+ "spellcheck",
88
+ "eslint-plugin-tsdoc"
89
+ ],
90
+ "extends": [
91
+ "eslint:recommended",
92
+ "plugin:@typescript-eslint/recommended",
93
+ "plugin:jest/recommended",
94
+ "prettier"
95
+ ],
96
+ "env": {
97
+ "node": true
98
+ },
99
+ "rules": {
100
+ "@typescript-eslint/no-inferrable-types": "off",
101
+ "@typescript-eslint/no-non-null-assertion": "off",
102
+ "@typescript-eslint/no-unused-vars": [
103
+ "error",
104
+ {
105
+ "varsIgnorePattern": "^_+$"
106
+ }
107
+ ],
108
+ "prefer-const": [
109
+ "error",
110
+ {
111
+ "destructuring": "all"
112
+ }
113
+ ],
114
+ "no-warning-comments": [
115
+ "error",
116
+ {
117
+ "terms": [
118
+ "fixme"
119
+ ],
120
+ "location": "anywhere"
121
+ }
122
+ ],
123
+ "spellcheck/spell-checker": [
124
+ "error",
125
+ {
126
+ "identifiers": false,
127
+ "skipIfMatch": [
128
+ "[^\\s]{20,}"
129
+ ],
130
+ "skipWords": [
131
+ "0x7fffffff",
132
+ "Chr",
133
+ "Dvalue",
134
+ "Hola",
135
+ "Mhtml",
136
+ "Today’s",
137
+ "Uint",
138
+ "Yorker",
139
+ "ascii",
140
+ "delim",
141
+ "multipart",
142
+ "versa"
143
+ ]
144
+ }
145
+ ]
146
+ }
147
+ },
148
+ "packageManager": "yarn@3.2.0"
149
+ }
package/dist/base64.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * decode base 64 string as bytes
3
- */
4
- export declare function decodeBase64(sBase64: string, nBlocksSize?: number): Uint8Array;
5
- /**
6
- * encode bytes as base64 string
7
- */
8
- export declare function encodeBase64(aBytes: Uint8Array): string;
package/dist/base64.js DELETED
@@ -1,77 +0,0 @@
1
- /*\
2
- |*|
3
- |*| Base64 / binary data / UTF-8 strings utilities
4
- |*|
5
- |*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
6
- |*|
7
- \*/
8
- /* Array of bytes to Base64 string decoding */
9
- function b64ToUint6(nChr) {
10
- return nChr > 64 && nChr < 91
11
- ? nChr - 65
12
- : nChr > 96 && nChr < 123
13
- ? nChr - 71
14
- : nChr > 47 && nChr < 58
15
- ? nChr + 4
16
- : nChr === 43
17
- ? 62
18
- : nChr === 47
19
- ? 63
20
- : /* istanbul ignore next */
21
- 0;
22
- }
23
- /**
24
- * decode base 64 string as bytes
25
- */
26
- export function decodeBase64(sBase64, nBlocksSize) {
27
- const sB64Enc = sBase64.replace(/[^A-Za-z0-9+/]/g, "");
28
- const nInLen = sB64Enc.length;
29
- const nOutLen = nBlocksSize
30
- ? Math.ceil(((nInLen * 3 + 1) >> 2) / nBlocksSize) * nBlocksSize
31
- : (nInLen * 3 + 1) >> 2;
32
- const taBytes = new Uint8Array(nOutLen);
33
- for (let nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
34
- const nMod4 = nInIdx & 3;
35
- nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4));
36
- if (nMod4 === 3 || nInLen - nInIdx === 1) {
37
- for (let nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
38
- taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255;
39
- }
40
- nUint24 = 0;
41
- }
42
- }
43
- return taBytes;
44
- }
45
- /* Base64 string to array encoding */
46
- function uint6ToB64(nUint6) {
47
- return nUint6 < 26
48
- ? nUint6 + 65
49
- : nUint6 < 52
50
- ? nUint6 + 71
51
- : nUint6 < 62
52
- ? nUint6 - 4
53
- : nUint6 === 62
54
- ? 43
55
- : nUint6 === 63
56
- ? 47
57
- : /* istanbul ignore next */
58
- 65;
59
- }
60
- /**
61
- * encode bytes as base64 string
62
- */
63
- export function encodeBase64(aBytes) {
64
- const nLen = aBytes.length;
65
- let nMod3 = 2;
66
- let sB64Enc = "";
67
- for (let nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
68
- nMod3 = nIdx % 3;
69
- nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24);
70
- if (nMod3 === 2 || aBytes.length - nIdx === 1) {
71
- sB64Enc += String.fromCodePoint(uint6ToB64((nUint24 >>> 18) & 63), uint6ToB64((nUint24 >>> 12) & 63), uint6ToB64((nUint24 >>> 6) & 63), uint6ToB64(nUint24 & 63));
72
- nUint24 = 0;
73
- }
74
- }
75
- return (sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) +
76
- (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "=="));
77
- }
@@ -1 +0,0 @@
1
- var y=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var q=e=>y(e,"__esModule",{value:!0});var D=(e,t)=>{for(var r in t)y(e,r,{get:t[r],enumerable:!0})},L=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!k.call(e,o)&&(r||o!=="default")&&y(e,o,{get:()=>t[o],enumerable:!(n=S(t,o))||n.enumerable});return e};var P=(e=>(t,r)=>e&&e.get(t)||(r=L(q({}),t,1),e&&e.set(t,r),r))(typeof WeakMap!="undefined"?new WeakMap:0);var K={};D(K,{MhtmlHeaders:()=>h,parseMhtml:()=>G});function Q(e){return e>64&&e<91?e-65:e>96&&e<123?e-71:e>47&&e<58?e+4:e===43?62:e===47?63:0}function f(e,t){let r=e.replace(/[^A-Za-z0-9+/]/g,""),n=r.length,o=t?Math.ceil((n*3+1>>2)/t)*t:n*3+1>>2,s=new Uint8Array(o);for(let a=0,i=0,d=0;d<n;d++){let l=d&3;if(a|=Q(r.charCodeAt(d))<<6*(3-l),l===3||n-d===1){for(let c=0;c<3&&i<o;c++,i++)s[i]=a>>>(16>>>c&24)&255;a=0}}return s}function j(e){return ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e)}function g(e,t){if(e.length!==t.length)return!1;if(e.byteOffset%4===t.byteOffset%4){let r=(4-e.byteOffset%4)%4,n=Math.floor((e.byteLength-r)/4),o=r+n*4,s=new Uint32Array(e.buffer,e.byteOffset+r,n),a=new Uint32Array(t.buffer,t.byteOffset+r,n);for(let i=0;i<r;++i)if(e[i]!==t[i])return!1;for(let i=0;i<n;++i)if(s[i]!==a[i])return!1;for(let i=o;i<e.length;++i)if(e[i]!==t[i])return!1;return!0}else{for(let r of e.keys())if(e[r]!==t[r])return!1;return!0}}function A(e){return{[Symbol.asyncIterator](){let t=e.getReader();return{async next(){let r=await t.read();return r.done?{done:!0,value:void 0}:{done:!1,value:r.value}}}}}}function H(e,t){return e.findIndex((r,n)=>{if(r!==t[0]||n+t.length>e.length)return!1;for(let o=1;o<t.length;++o)if(e[n+o]!==t[o])return!1;return!0})}async function*p(e,t){let r=new Uint8Array(0);for await(let n of e){let o=j(n);r=r.length?I([r,o]):o;let s;for(;(s=H(r,t))!==-1;)yield r.subarray(0,s),r=r.subarray(s+t.length)}yield r}function I(e){let t=e.reduce((o,s)=>o+s.length,0),r=new Uint8Array(t),n=0;for(let o of e)r.set(o,n),n+=o.length;return r}async function m(e){let t=[];for await(let r of e)t.push(r);return I(t)}var R=new Uint8Array([10]);async function*U(e,t=R){for await(let r of e){let n=new Uint8Array(r.length+t.length),o=!1,s=0;for(let a=0;a<r.length;++a){let i=r[a];if(i>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${r}`);if(i!==61)n[s++]=i;else{let d=r[++a];if(d===void 0)o=!0;else{let l=r[++a];if(l===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let c=parseInt(String.fromCharCode(d),16);c*=16,c+=parseInt(String.fromCharCode(l),16),n[s++]=c}}}o||(n.set(t,s),s+=t.length),yield n.subarray(0,s)}}var W=new TextDecoder;async function*x(e){for await(let t of e)yield f(W.decode(t))}async function*b(e){for await(let t of e)yield t}function v(){throw new Error("binary transfer-encoding is explicitly not supported and trying to add an implementation will likely result in unexpected results, but if you want to ignore anyway, set binary to `decode8bit`")}var E=new TextEncoder,M=new TextDecoder,h=class{#e=new Map;[Symbol.iterator](){return this.entries()}append(t,r){let n=this.#e.get(t);n===void 0?this.#e.set(t,[r]):n.push(r)}*entries(t=", "){for(let[r,n]of this.#e.entries())yield[r,n.join(t)]}*entriesAll(){for(let[t,r]of this.#e.entries())for(let n of r)yield[t,n]}get(t,r=", "){let n=this.#e.get(t);return n===void 0?null:n.join(r)}getAll(t){return this.#e.get(t)??[]}has(t){return this.#e.has(t)}keys(){return this.#e.keys()}*values(t=", "){for(let r of this.#e.values())yield r.join(t)}*valuesAll(){for(let t of this.#e.values())yield*t}};function F(e){let t=new Uint8Array(e.length),r=0;for(let n=0;n<e.length;++n){let o=e.charCodeAt(n),s;if(o>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${e}"`);o===95?s=32:o===61?(s=parseInt(e[++n],16),s*=16,s+=parseInt(e[++n],16)):s=o,t[r++]=s}return t.subarray(0,r)}var N=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function B(e){let t=N.exec(e);if(t){let[,r,n,o]=t,s;if(n==="Q")s=F(o);else if(n==="B")s=f(o);else throw new Error(`unknown encoding for header value encoding: ${n}`);return new TextDecoder(r).decode(s)}else return e}async function J(e){let t=new h,r="",n="";for(;;){let{done:o,value:s}=await e.next();if(o)throw new Error("didn't find an empty line to signify the end of header parsing");let a=M.decode(s);if(/^\s/.test(a))n+=" ",n+=B(a.trimStart());else if(r&&t.append(r,n),a){let i=a.indexOf(": ");if(i===-1)throw new Error(`header line didn't have key-value delimiter: "${a}"`);r=a.slice(0,i),n=B(a.slice(i+2))}else return t}}var V=new Map([["7bit",b],["base64",x],["quoted-printable",U],["8bit",b],["binary",v]]);function Z(e){let t=e.get("Content-Type");if(t===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(e))}`);let r,n=!1;for(let a of t.split("; "))a.startsWith("multipart/")?n=!0:a.startsWith("boundary=")&&(r=a.slice(9),r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)));if(!n||r===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let o=E.encode(`--${r}`),s=E.encode(`--${r}--`);return[o,s]}async function*G(e,{decoderOverrides:t=new Map}={}){let r=new Map([...V.entries(),...t.entries()]),n=new Uint8Array([13,10]),o=p(A(e),n),s=null,a=!0;for(;a;){let i=await J(o),[d,l]=s??(s=Z(i)),c=i.get("Content-Transfer-Encoding")??"7bit",w=r.get(c);if(w===void 0)throw new Error(`unhandled encoding type: ${c}`);let O=await m(w({[Symbol.asyncIterator](){return{async next(){let{done:T,value:u}=await o.next();if(T)throw new Error(`stream didn't end with the appropriate termination boundary: ${M.decode(l)}`);return g(u,d)?{done:!0,value:void 0}:g(u,l)?(a=!1,{done:!0,value:void 0}):{value:u}}}}}));yield{headers:i,content:O}}}module.exports=P(K);
@@ -1 +0,0 @@
1
- var mhtmlStream=(()=>{var y=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var q=e=>y(e,"__esModule",{value:!0});var D=(e,t)=>{for(var r in t)y(e,r,{get:t[r],enumerable:!0})},L=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!k.call(e,o)&&(r||o!=="default")&&y(e,o,{get:()=>t[o],enumerable:!(n=S(t,o))||n.enumerable});return e};var P=(e=>(t,r)=>e&&e.get(t)||(r=L(q({}),t,1),e&&e.set(t,r),r))(typeof WeakMap!="undefined"?new WeakMap:0);var K={};D(K,{MhtmlHeaders:()=>h,parseMhtml:()=>G});function Q(e){return e>64&&e<91?e-65:e>96&&e<123?e-71:e>47&&e<58?e+4:e===43?62:e===47?63:0}function f(e,t){let r=e.replace(/[^A-Za-z0-9+/]/g,""),n=r.length,o=t?Math.ceil((n*3+1>>2)/t)*t:n*3+1>>2,s=new Uint8Array(o);for(let a=0,i=0,d=0;d<n;d++){let l=d&3;if(a|=Q(r.charCodeAt(d))<<6*(3-l),l===3||n-d===1){for(let c=0;c<3&&i<o;c++,i++)s[i]=a>>>(16>>>c&24)&255;a=0}}return s}function j(e){return ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e)}function g(e,t){if(e.length!==t.length)return!1;if(e.byteOffset%4===t.byteOffset%4){let r=(4-e.byteOffset%4)%4,n=Math.floor((e.byteLength-r)/4),o=r+n*4,s=new Uint32Array(e.buffer,e.byteOffset+r,n),a=new Uint32Array(t.buffer,t.byteOffset+r,n);for(let i=0;i<r;++i)if(e[i]!==t[i])return!1;for(let i=0;i<n;++i)if(s[i]!==a[i])return!1;for(let i=o;i<e.length;++i)if(e[i]!==t[i])return!1;return!0}else{for(let r of e.keys())if(e[r]!==t[r])return!1;return!0}}function A(e){return{[Symbol.asyncIterator](){let t=e.getReader();return{async next(){let r=await t.read();return r.done?{done:!0,value:void 0}:{done:!1,value:r.value}}}}}}function H(e,t){return e.findIndex((r,n)=>{if(r!==t[0]||n+t.length>e.length)return!1;for(let o=1;o<t.length;++o)if(e[n+o]!==t[o])return!1;return!0})}async function*p(e,t){let r=new Uint8Array(0);for await(let n of e){let o=j(n);r=r.length?I([r,o]):o;let s;for(;(s=H(r,t))!==-1;)yield r.subarray(0,s),r=r.subarray(s+t.length)}yield r}function I(e){let t=e.reduce((o,s)=>o+s.length,0),r=new Uint8Array(t),n=0;for(let o of e)r.set(o,n),n+=o.length;return r}async function m(e){let t=[];for await(let r of e)t.push(r);return I(t)}var R=new Uint8Array([10]);async function*U(e,t=R){for await(let r of e){let n=new Uint8Array(r.length+t.length),o=!1,s=0;for(let a=0;a<r.length;++a){let i=r[a];if(i>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${r}`);if(i!==61)n[s++]=i;else{let d=r[++a];if(d===void 0)o=!0;else{let l=r[++a];if(l===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let c=parseInt(String.fromCharCode(d),16);c*=16,c+=parseInt(String.fromCharCode(l),16),n[s++]=c}}}o||(n.set(t,s),s+=t.length),yield n.subarray(0,s)}}var W=new TextDecoder;async function*x(e){for await(let t of e)yield f(W.decode(t))}async function*b(e){for await(let t of e)yield t}function v(){throw new Error("binary transfer-encoding is explicitly not supported and trying to add an implementation will likely result in unexpected results, but if you want to ignore anyway, set binary to `decode8bit`")}var E=new TextEncoder,M=new TextDecoder,h=class{#e=new Map;[Symbol.iterator](){return this.entries()}append(t,r){let n=this.#e.get(t);n===void 0?this.#e.set(t,[r]):n.push(r)}*entries(t=", "){for(let[r,n]of this.#e.entries())yield[r,n.join(t)]}*entriesAll(){for(let[t,r]of this.#e.entries())for(let n of r)yield[t,n]}get(t,r=", "){let n=this.#e.get(t);return n===void 0?null:n.join(r)}getAll(t){return this.#e.get(t)??[]}has(t){return this.#e.has(t)}keys(){return this.#e.keys()}*values(t=", "){for(let r of this.#e.values())yield r.join(t)}*valuesAll(){for(let t of this.#e.values())yield*t}};function F(e){let t=new Uint8Array(e.length),r=0;for(let n=0;n<e.length;++n){let o=e.charCodeAt(n),s;if(o>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${e}"`);o===95?s=32:o===61?(s=parseInt(e[++n],16),s*=16,s+=parseInt(e[++n],16)):s=o,t[r++]=s}return t.subarray(0,r)}var N=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function B(e){let t=N.exec(e);if(t){let[,r,n,o]=t,s;if(n==="Q")s=F(o);else if(n==="B")s=f(o);else throw new Error(`unknown encoding for header value encoding: ${n}`);return new TextDecoder(r).decode(s)}else return e}async function J(e){let t=new h,r="",n="";for(;;){let{done:o,value:s}=await e.next();if(o)throw new Error("didn't find an empty line to signify the end of header parsing");let a=M.decode(s);if(/^\s/.test(a))n+=" ",n+=B(a.trimStart());else if(r&&t.append(r,n),a){let i=a.indexOf(": ");if(i===-1)throw new Error(`header line didn't have key-value delimiter: "${a}"`);r=a.slice(0,i),n=B(a.slice(i+2))}else return t}}var V=new Map([["7bit",b],["base64",x],["quoted-printable",U],["8bit",b],["binary",v]]);function Z(e){let t=e.get("Content-Type");if(t===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(e))}`);let r,n=!1;for(let a of t.split("; "))a.startsWith("multipart/")?n=!0:a.startsWith("boundary=")&&(r=a.slice(9),r.startsWith('"')&&r.endsWith('"')&&(r=r.slice(1,-1)));if(!n||r===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let o=E.encode(`--${r}`),s=E.encode(`--${r}--`);return[o,s]}async function*G(e,{decoderOverrides:t=new Map}={}){let r=new Map([...V.entries(),...t.entries()]),n=new Uint8Array([13,10]),o=p(A(e),n),s=null,a=!0;for(;a;){let i=await J(o),[d,l]=s??(s=Z(i)),c=i.get("Content-Transfer-Encoding")??"7bit",w=r.get(c);if(w===void 0)throw new Error(`unhandled encoding type: ${c}`);let O=await m(w({[Symbol.asyncIterator](){return{async next(){let{done:T,value:u}=await o.next();if(T)throw new Error(`stream didn't end with the appropriate termination boundary: ${M.decode(l)}`);return g(u,d)?{done:!0,value:void 0}:g(u,l)?(a=!1,{done:!0,value:void 0}):{value:u}}}}}));yield{headers:i,content:O}}}return P(K);})();