mhtml-stream 2.0.1 → 2.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/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-console */
2
- import { argv } from "bun";
3
2
  import { mkdir } from "node:fs/promises";
3
+ import { argv } from "bun";
4
4
  import yargs from "yargs";
5
5
  import { parseMhtml } from ".";
6
6
  async function* readFile(name) {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { MhtmlHeaders } from "./headers";
1
+ import { type MhtmlHeaders } from "./headers";
2
2
  export type { MhtmlHeaders };
3
3
  /** a file that was encoded in MHTML format */
4
4
  export interface MhtmlFile {
package/dist/index.js CHANGED
@@ -113,7 +113,7 @@ function getBoundary(headers) {
113
113
  if (contentType === null) {
114
114
  throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(headers))}`);
115
115
  }
116
- let bound = undefined;
116
+ let bound;
117
117
  let multipart = false;
118
118
  for (const field of contentType.split(/;\s*/)) {
119
119
  if (field.startsWith("multipart/")) {
@@ -1 +1 @@
1
- var D=L;var g=[],Y=[],f=typeof Uint8Array!=="undefined"?Uint8Array:Array,P="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(Z=0,F=P.length;Z<F;++Z)g[Z]=P[Z],Y[P.charCodeAt(Z)]=Z;var Z,F;Y[45]=62;Y[95]=63;function m(G){var K=G.length;if(K%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var J=G.indexOf("=");if(J===-1)J=K;var M=J===K?0:4-J%4;return[J,M]}function v(G,K,J){return(K+J)*3/4-J}function L(G){var K,J=m(G),M=J[0],R=J[1],U=new f(v(G,M,R)),V=0,W=R>0?M-4:M,X;for(X=0;X<W;X+=4)K=Y[G.charCodeAt(X)]<<18|Y[G.charCodeAt(X+1)]<<12|Y[G.charCodeAt(X+2)]<<6|Y[G.charCodeAt(X+3)],U[V++]=K>>16&255,U[V++]=K>>8&255,U[V++]=K&255;if(R===2)K=Y[G.charCodeAt(X)]<<2|Y[G.charCodeAt(X+1)]>>4,U[V++]=K&255;if(R===1)K=Y[G.charCodeAt(X)]<<10|Y[G.charCodeAt(X+1)]<<4|Y[G.charCodeAt(X+2)]>>2,U[V++]=K>>8&255,U[V++]=K&255;return U}class S{#G=new Map;[Symbol.iterator](){return this.entries()}append(G,K){let J=this.#G.get(G);if(J===void 0)this.#G.set(G,[K]);else J.push(K)}*entries(G=", "){for(let[K,J]of this.#G.entries())yield[K,J.join(G)]}*entriesAll(){for(let[G,K]of this.#G.entries())for(let J of K)yield[G,J]}get(G,K=", "){let J=this.#G.get(G);if(J===void 0)return null;else return J.join(K)}getAll(G){return this.#G.get(G)??[]}has(G){return this.#G.has(G)}keys(){return this.#G.keys()}*values(G=", "){for(let K of this.#G.values())yield K.join(G)}*valuesAll(){for(let G of this.#G.values())yield*G}}function _(G,K){if(G.length!==K.length)return!1;else if(G.byteOffset%4===K.byteOffset%4){let J=(4-G.byteOffset%4)%4,M=Math.floor((G.byteLength-J)/4),R=J+M*4,U=new Uint32Array(G.buffer,G.byteOffset+J,M),V=new Uint32Array(K.buffer,K.byteOffset+J,M);for(let W=0;W<J;++W)if(G[W]!==K[W])return!1;for(let W=0;W<M;++W)if(U[W]!==V[W])return!1;for(let W=R;W<G.length;++W)if(G[W]!==K[W])return!1;return!0}else{for(let J of G.keys())if(G[J]!==K[J])return!1;return!0}}function h(G,K){return G.findIndex((J,M)=>{if(J!==K[0]||M+K.length>G.length)return!1;else{for(let R=1;R<K.length;++R)if(G[M+R]!==K[R])return!1;return!0}})}async function*Q(G,K){let J=new Uint8Array(0);for await(let M of G){J=J.length?E([J,M]):M;let R;while((R=h(J,K))!==-1)yield J.subarray(0,R),J=J.subarray(R+K.length)}yield J}function E(G){let K=G.reduce((R,U)=>R+U.length,0),J=new Uint8Array(K),M=0;for(let R of G)J.set(R,M),M+=R.length;return J}async function O(G){let K=[];for await(let J of G)K.push(J);return E(K)}var k=new Uint8Array([10]);async function*T(G,K=k){for await(let J of G){let M=new Uint8Array(J.length+K.length),R=!1,U=0;for(let V=0;V<J.length;++V){let W=J[V];if(W>=128)throw new Error(`got non-ascii character when decoding quoted printable: ${W}`);if(W!==61)M[U++]=W;else{let X=J[++V];if(X===void 0)R=!0;else{let z=J[++V];if(z===void 0)throw new Error("quoted printable escape (=) was not followed by two bytes");let $=parseInt(String.fromCharCode(X),16);$*=16,$+=parseInt(String.fromCharCode(z),16),M[U++]=$}}}if(!R)M.set(K,U),U+=K.length;yield M.subarray(0,U)}}var y=new TextDecoder;async function*C(G){for await(let K of G)yield D(y.decode(K))}async function*j(G){for await(let K of G)yield K}function A(){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 I=new TextEncoder,B=new TextDecoder;function b(G){let K=new Uint8Array(G.length),J=0;for(let M=0;M<G.length;++M){let R=G.charCodeAt(M),U;if(R>=128)throw new Error(`got non-ascii character when decoding q-quoted word: "${G}"`);else if(R===95)U=32;else if(R===61)U=parseInt(G[++M],16),U*=16,U+=parseInt(G[++M],16);else U=R;K[J++]=U}return K.subarray(0,J)}var p=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function H(G){let K=p.exec(G);if(K){let[,J,M,R]=K,U;if(M==="Q")U=b(R);else U=D(R);return new TextDecoder(J).decode(U)}else return G}async function c(G){let K=new S,J="",M="";for(;;){let{done:R,value:U}=await G.next();if(R)throw new Error("didn't find an empty line to signify the end of header parsing");let V=B.decode(U);if(/^\s/.test(V))M+=H(V.substring(1));else{if(J)K.append(J,M);if(V){let W=V.indexOf(": ");if(W===-1)throw new Error(`header line didn't have key-value delimiter: "${V}"`);J=V.slice(0,W),M=H(V.slice(W+2))}else return K}}}var u=new Map([["7bit",j],["base64",C],["quoted-printable",T],["8bit",j],["binary",A]]);function s(G){let K=G.get("Content-Type");if(K===null)throw new Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(G))}`);let J=void 0,M=!1;for(let V of K.split(/;\s*/))if(V.startsWith("multipart/"))M=!0;else if(V.startsWith("boundary=")){if(J=V.slice(9),J.startsWith('"')&&J.endsWith('"'))J=J.slice(1,-1)}if(!M||J===void 0)throw new Error("first content type header didn't contain 'multipart/...' and a boundary string");let R=I.encode(`--${J}`),U=I.encode(`--${J}--`);return[R,U]}async function*e(G,{decoderOverrides:K=new Map}={}){let J=new Map([...u.entries(),...K.entries()]),M=new Uint8Array([13,10]),R=Q(G,M),U=null,V=!0;while(V){let W=await c(R),[X,z]=U??(U=s(W)),$=W.get("Content-Transfer-Encoding")??"7bit",q=J.get($);if(q===void 0)throw new Error(`unhandled encoding type: ${$}`);let w=await O(q({[Symbol.asyncIterator](){return{async next(){let{done:x,value:N}=await R.next();if(x)throw new Error(`stream didn't end with the appropriate termination boundary: ${B.decode(z)}`);else if(_(N,X))return{done:!0,value:void 0};else if(_(N,z))return V=!1,{done:!0,value:void 0};else return{value:N}}}}}));yield{headers:W,content:w}}}export{e as parseMhtml};
1
+ var D=L;var g=[],Y=[],f=typeof Uint8Array<"u"?Uint8Array:Array,P="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(Z=0,S=P.length;Z<S;++Z)g[Z]=P[Z],Y[P.charCodeAt(Z)]=Z;var Z,S;Y[45]=62;Y[95]=63;function m(G){var K=G.length;if(K%4>0)throw Error("Invalid string. Length must be a multiple of 4");var J=G.indexOf("=");if(J===-1)J=K;var M=J===K?0:4-J%4;return[J,M]}function v(G,K,J){return(K+J)*3/4-J}function L(G){var K,J=m(G),M=J[0],R=J[1],U=new f(v(G,M,R)),V=0,W=R>0?M-4:M,X;for(X=0;X<W;X+=4)K=Y[G.charCodeAt(X)]<<18|Y[G.charCodeAt(X+1)]<<12|Y[G.charCodeAt(X+2)]<<6|Y[G.charCodeAt(X+3)],U[V++]=K>>16&255,U[V++]=K>>8&255,U[V++]=K&255;if(R===2)K=Y[G.charCodeAt(X)]<<2|Y[G.charCodeAt(X+1)]>>4,U[V++]=K&255;if(R===1)K=Y[G.charCodeAt(X)]<<10|Y[G.charCodeAt(X+1)]<<4|Y[G.charCodeAt(X+2)]>>2,U[V++]=K>>8&255,U[V++]=K&255;return U}class _{#G=new Map;[Symbol.iterator](){return this.entries()}append(G,K){let J=this.#G.get(G);if(J===void 0)this.#G.set(G,[K]);else J.push(K)}*entries(G=", "){for(let[K,J]of this.#G.entries())yield[K,J.join(G)]}*entriesAll(){for(let[G,K]of this.#G.entries())for(let J of K)yield[G,J]}get(G,K=", "){let J=this.#G.get(G);if(J===void 0)return null;else return J.join(K)}getAll(G){return this.#G.get(G)??[]}has(G){return this.#G.has(G)}keys(){return this.#G.keys()}*values(G=", "){for(let K of this.#G.values())yield K.join(G)}*valuesAll(){for(let G of this.#G.values())yield*G}}function j(G,K){if(G.length!==K.length)return!1;else if(G.byteOffset%4===K.byteOffset%4){let J=(4-G.byteOffset%4)%4,M=Math.floor((G.byteLength-J)/4),R=J+M*4,U=new Uint32Array(G.buffer,G.byteOffset+J,M),V=new Uint32Array(K.buffer,K.byteOffset+J,M);for(let W=0;W<J;++W)if(G[W]!==K[W])return!1;for(let W=0;W<M;++W)if(U[W]!==V[W])return!1;for(let W=R;W<G.length;++W)if(G[W]!==K[W])return!1;return!0}else{for(let J of G.keys())if(G[J]!==K[J])return!1;return!0}}function h(G,K){return G.findIndex((J,M)=>{if(J!==K[0]||M+K.length>G.length)return!1;else{for(let R=1;R<K.length;++R)if(G[M+R]!==K[R])return!1;return!0}})}async function*Q(G,K){let J=new Uint8Array(0);for await(let M of G){J=J.length?E([J,M]):M;let R;while((R=h(J,K))!==-1)yield J.subarray(0,R),J=J.subarray(R+K.length)}yield J}function E(G){let K=G.reduce((R,U)=>R+U.length,0),J=new Uint8Array(K),M=0;for(let R of G)J.set(R,M),M+=R.length;return J}async function O(G){let K=[];for await(let J of G)K.push(J);return E(K)}var k=new Uint8Array([10]);async function*T(G,K=k){for await(let J of G){let M=new Uint8Array(J.length+K.length),R=!1,U=0;for(let V=0;V<J.length;++V){let W=J[V];if(W>=128)throw Error(`got non-ascii character when decoding quoted printable: ${W}`);if(W!==61)M[U++]=W;else{let X=J[++V];if(X===void 0)R=!0;else{let z=J[++V];if(z===void 0)throw Error("quoted printable escape (=) was not followed by two bytes");let $=parseInt(String.fromCharCode(X),16);$*=16,$+=parseInt(String.fromCharCode(z),16),M[U++]=$}}}if(!R)M.set(K,U),U+=K.length;yield M.subarray(0,U)}}var y=new TextDecoder;async function*C(G){for await(let K of G)yield D(y.decode(K))}async function*q(G){for await(let K of G)yield K}function A(){throw 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 I=new TextEncoder,B=new TextDecoder;function b(G){let K=new Uint8Array(G.length),J=0;for(let M=0;M<G.length;++M){let R=G.charCodeAt(M),U;if(R>=128)throw Error(`got non-ascii character when decoding q-quoted word: "${G}"`);else if(R===95)U=32;else if(R===61)U=parseInt(G[++M],16),U*=16,U+=parseInt(G[++M],16);else U=R;K[J++]=U}return K.subarray(0,J)}var p=/^=\?([^?\s]+)\?([BQ])\?([^?\s]+)\?=$/;function H(G){let K=p.exec(G);if(K){let[,J,M,R]=K,U;if(M==="Q")U=b(R);else U=D(R);return new TextDecoder(J).decode(U)}else return G}async function c(G){let K=new _,J="",M="";for(;;){let{done:R,value:U}=await G.next();if(R)throw Error("didn't find an empty line to signify the end of header parsing");let V=B.decode(U);if(/^\s/.test(V))M+=H(V.substring(1));else{if(J)K.append(J,M);if(V){let W=V.indexOf(": ");if(W===-1)throw Error(`header line didn't have key-value delimiter: "${V}"`);J=V.slice(0,W),M=H(V.slice(W+2))}else return K}}}var u=new Map([["7bit",q],["base64",C],["quoted-printable",T],["8bit",q],["binary",A]]);function s(G){let K=G.get("Content-Type");if(K===null)throw Error(`first headers didn't contain a content type: ${JSON.stringify(Object.fromEntries(G))}`);let J,M=!1;for(let V of K.split(/;\s*/))if(V.startsWith("multipart/"))M=!0;else if(V.startsWith("boundary=")){if(J=V.slice(9),J.startsWith('"')&&J.endsWith('"'))J=J.slice(1,-1)}if(!M||J===void 0)throw Error("first content type header didn't contain 'multipart/...' and a boundary string");let R=I.encode(`--${J}`),U=I.encode(`--${J}--`);return[R,U]}async function*t(G,{decoderOverrides:K=new Map}={}){let J=new Map([...u.entries(),...K.entries()]),M=new Uint8Array([13,10]),R=Q(G,M),U=null,V=!0;while(V){let W=await c(R),[X,z]=U??(U=s(W)),$=W.get("Content-Transfer-Encoding")??"7bit",F=J.get($);if(F===void 0)throw Error(`unhandled encoding type: ${$}`);let w=await O(F({[Symbol.asyncIterator](){return{async next(){let{done:x,value:N}=await R.next();if(x)throw Error(`stream didn't end with the appropriate termination boundary: ${B.decode(z)}`);else if(j(N,X))return{done:!0,value:void 0};else if(j(N,z))return V=!1,{done:!0,value:void 0};else return{value:N}}}}}));yield{headers:W,content:w}}}export{t as parseMhtml};
package/dist/utils.js CHANGED
@@ -77,7 +77,9 @@ export function indexOf(haystack, needle) {
77
77
  export async function* splitStream(iter, split) {
78
78
  let current = new Uint8Array(0);
79
79
  for await (const chunk of iter) {
80
- current = current.length ? concat([current, chunk]) : chunk;
80
+ current = current.length
81
+ ? concat([current, chunk])
82
+ : chunk;
81
83
  let nextInd;
82
84
  while ((nextInd = indexOf(current, split)) !== -1) {
83
85
  yield current.subarray(0, nextInd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mhtml-stream",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Zero dependency stream MHTML parser",
5
5
  "keywords": [
6
6
  "mhtml",
@@ -13,87 +13,38 @@
13
13
  "author": "Erik Brinkman <erik.brinkman@gmail.com>",
14
14
  "license": "MIT",
15
15
  "type": "module",
16
+ "sideEffects": false,
16
17
  "types": "dist/index.d.ts",
17
18
  "module": "dist/mhtml.esm.min.js",
18
- "exports": "./dist/mhtml.esm.min.js",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/mhtml.esm.min.js"
23
+ }
24
+ },
19
25
  "files": [
20
26
  "/dist/**/*.js",
21
27
  "/dist/**/*.d.ts"
22
28
  ],
23
29
  "scripts": {
24
30
  "cli": "bun src/cli.ts",
25
- "fmt": "prettier --cache --write 'src/*.ts' '*.{js,json}'",
26
- "lint": "tsc && eslint --cache 'src/*.ts' && typedoc --emit none",
31
+ "fmt": "biome format --write",
32
+ "lint": "tsc && biome check && typedoc --emit none",
27
33
  "doc": "typedoc",
28
34
  "export": "tsc -p tsconfig.build.json && bun build src/index.ts --minify --outfile dist/mhtml.esm.min.js",
29
- "prepack": "bun lint && bun test --coverage && bun export"
35
+ "prepack": "bun lint && bun test --coverage && bun export && publint"
30
36
  },
31
37
  "dependencies": {
32
38
  "base64-js": "^1.5.1"
33
39
  },
34
40
  "devDependencies": {
35
- "@types/base64-js": "^1.3.2",
36
- "@types/bun": "^1.1.14",
37
- "@types/yargs": "^17.0.33",
38
- "eslint": "^9.17.0",
39
- "eslint-config-prettier": "^9.1.0",
40
- "eslint-plugin-spellcheck": "^0.0.20",
41
- "eslint-plugin-tsdoc": "^0.4.0",
42
- "prettier": "^3.4.2",
43
- "prettier-plugin-organize-imports": "^4.1.0",
44
- "typedoc": "^0.27.5",
45
- "typescript": "^5.7.2",
46
- "typescript-eslint": "^8.18.1",
47
- "yargs": "^17.7.2"
48
- },
49
- "eslintConfig": {
50
- "rules": {
51
- "@typescript-eslint/no-inferrable-types": "off",
52
- "@typescript-eslint/no-non-null-assertion": "off",
53
- "@typescript-eslint/no-unused-vars": [
54
- "error",
55
- {
56
- "varsIgnorePattern": "^_+$"
57
- }
58
- ],
59
- "prefer-const": [
60
- "error",
61
- {
62
- "destructuring": "all"
63
- }
64
- ],
65
- "no-warning-comments": [
66
- "error",
67
- {
68
- "terms": [
69
- "fixme"
70
- ],
71
- "location": "anywhere"
72
- }
73
- ],
74
- "spellcheck/spell-checker": [
75
- "error",
76
- {
77
- "identifiers": false,
78
- "skipIfMatch": [
79
- "[^\\s]{20,}"
80
- ],
81
- "skipWords": [
82
- "0x7fffffff",
83
- "Chr",
84
- "Dvalue",
85
- "Hola",
86
- "Mhtml",
87
- "Today’s",
88
- "Uint",
89
- "Yorker",
90
- "ascii",
91
- "delim",
92
- "multipart",
93
- "versa"
94
- ]
95
- }
96
- ]
97
- }
41
+ "@biomejs/biome": "^2.4.15",
42
+ "@types/base64-js": "^1.5.0",
43
+ "@types/bun": "^1.3.14",
44
+ "@types/yargs": "^17.0.35",
45
+ "publint": "^0.3.21",
46
+ "typedoc": "^0.28.19",
47
+ "typescript": "~6.0.3",
48
+ "yargs": "^18.0.0"
98
49
  }
99
50
  }