-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
67 lines (57 loc) · 1.55 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { pipeline, Readable } from "stream";
import HTMLStream from "@bonniernews/atlas-html-stream";
import ESI from "./lib/ESI.js";
import HTMLWriter from "./lib/HTMLWriter.js";
export {
ESI,
HTMLWriter,
parse,
};
function parse(html, options) {
const response = {};
let body = "";
const esi = new ESI(options)
.on("set_response_code", onSetResponseCode)
.on("add_header", onAddHeader)
.once("set_redirect", onRedirect);
return new Promise((resolve, reject) => {
pipeline([
Readable.from(html),
new HTMLStream({ preserveWS: true }),
esi,
new HTMLWriter(),
], (err) => {
if (err && ![ "ERR_STREAM_DESTROYED", "ERR_STREAM_PREMATURE_CLOSE" ].includes(err.code)) return reject(err);
resolve({
body,
...response,
});
}).on("data", (chunk) => {
body += chunk;
});
});
function onRedirect(statusCode, location) {
response.statusCode = statusCode;
if (location) {
response.headers = response.headers || {};
response.headers.location = location;
}
this.destroy();
}
function onAddHeader(name, value) {
const headers = response.headers = response.headers || {};
const lname = name.toLowerCase();
if (lname === "set-cookie") {
headers[lname] = headers[lname] || [];
headers[lname].push(value);
} else {
headers[lname] = value;
}
}
function onSetResponseCode(statusCode, withBody) {
response.statusCode = statusCode;
if (!withBody) return;
response.body = withBody;
this.destroy();
}
}