UNPKG

2.81 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5const validator_1 = __importDefault(require("validator"));
6const eventsource_1 = __importDefault(require("eventsource"));
7const url_1 = __importDefault(require("url"));
8const querystring_1 = __importDefault(require("querystring"));
9class Client {
10 constructor({ source, target, logger = console, fetch = global.fetch, }) {
11 this.source = source;
12 this.target = target;
13 this.logger = logger;
14 this.fetch = fetch;
15 if (!validator_1.default.isURL(this.source)) {
16 throw new Error("The provided URL is invalid.");
17 }
18 }
19 static async createChannel({ fetch = global.fetch } = {}) {
20 const response = await fetch("https://smee.io/new", {
21 method: "HEAD",
22 redirect: "manual",
23 });
24 const address = response.headers.get("location");
25 if (!address) {
26 throw new Error("Failed to create channel");
27 }
28 return address;
29 }
30 async onmessage(msg) {
31 const data = JSON.parse(msg.data);
32 const target = url_1.default.parse(this.target, true);
33 const mergedQuery = { ...target.query, ...data.query };
34 target.search = querystring_1.default.stringify(mergedQuery);
35 delete data.query;
36 const body = JSON.stringify(data.body);
37 delete data.body;
38 const headers = {};
39 Object.keys(data).forEach((key) => {
40 headers[key] = data[key];
41 });
42 headers["content-length"] = Buffer.byteLength(body);
43 try {
44 const response = await this.fetch(url_1.default.format(target), {
45 method: "POST",
46 mode: data["sec-fetch-mode"],
47 cache: "default",
48 body,
49 headers,
50 });
51 this.logger.info(`POST ${response.url} - ${response.status}`);
52 }
53 catch (err) {
54 this.logger.error(err);
55 }
56 }
57 onopen() {
58 this.logger.info("Connected", this.events.url);
59 }
60 onerror(err) {
61 this.logger.error(err);
62 }
63 start() {
64 const events = new eventsource_1.default(this.source);
65 // Reconnect immediately
66 events.reconnectInterval = 0; // This isn't a valid property of EventSource
67 events.addEventListener("message", this.onmessage.bind(this));
68 events.addEventListener("open", this.onopen.bind(this));
69 events.addEventListener("error", this.onerror.bind(this));
70 this.logger.info(`Forwarding ${this.source} to ${this.target}`);
71 this.events = events;
72 return events;
73 }
74}
75module.exports = Client;
76//# sourceMappingURL=index.js.map
\No newline at end of file