forked from probot/smee-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
88 lines (67 loc) · 2.04 KB
/
index.ts
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import validator = require('validator')
import EventSource = require('eventsource')
import superagent = require('superagent')
import url = require('url')
import querystring = require('querystring')
type Severity = 'info' | 'error'
interface Options {
source: string
target: string
logger?: Pick<Console, Severity>
}
class Client {
source: string;
target: string;
logger: Pick<Console, Severity>;
events!: EventSource;
constructor ({ source, target, logger = console }: Options) {
this.source = source
this.target = target
this.logger = logger!
if (!validator.isURL(this.source)) {
throw new Error('The provided URL is invalid.')
}
}
static async createChannel () {
return superagent.head('https://smee.io/new').redirects(0).catch((err) => {
return err.response.headers.location
})
}
onmessage (msg: any) {
const data = JSON.parse(msg.data)
const target = url.parse(this.target, true)
const mergedQuery = Object.assign(target.query, data.query)
target.search = querystring.stringify(mergedQuery)
delete data.query
const req = superagent.post(url.format(target)).send(data.body)
delete data.body
Object.keys(data).forEach(key => {
req.set(key, data[key])
})
req.end((err, res) => {
if (err) {
this.logger.error(err)
} else {
this.logger.info(`${req.method} ${req.url} - ${res.status}`)
}
})
}
onopen () {
this.logger.info('Connected', this.events.url)
}
onerror (err: any) {
this.logger.error(err)
}
start () {
const events = new EventSource(this.source);
// Reconnect immediately
(events as any).reconnectInterval = 0 // This isn't a valid property of EventSource
events.addEventListener('message', this.onmessage.bind(this))
events.addEventListener('open', this.onopen.bind(this))
events.addEventListener('error', this.onerror.bind(this))
this.logger.info(`Forwarding ${this.source} to ${this.target}`)
this.events = events
return events
}
}
export = Client