-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ls
79 lines (64 loc) · 3.04 KB
/
index.ls
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
{promises:{bindP, from-error-value-callback, new-promise, returnP, sequenceP, to-callback}} = require \async-ls
{get-ip-from-request, get-country-from-ip} = require \./ip-to-country
{id, map, obj-to-pairs, pairs-to-obj, Str, take} = require \prelude-ls
require! \ua-parser-js
# :: [StorageDetail] -> Spy
module.exports = (storage-details) ->
# record :: Event -> p [InsertedEvent]
record = (event-object) ->
creation-date = new Date!
creation-time = creation-date.get-time!
extended-event-object = {
creation-date
creation-time
} <<< event-object
storage-details
|> map ({name, connection-string, connection-options, insert-into}) ->
# establish a connection to the store
{insert, close} <- bindP ((require "./stores/#{name}") connection-string, connection-options)
# insert extended-event-object into the store
result <- bindP insert insert-into, extended-event-object
# close the connection to the store & return the inserted event
close!
returnP result
|> sequenceP
# record-req :: Request -> Event -> p [InsertedEvent]
record-req = ({headers, original-url, protocol}:req, event-object) -->
# get ip & country from event-object (if present) otherwise use IP2Location
ip = event-object?.ip ? (get-ip-from-request req)
country = event-object?.country ? (get-country-from-ip ip)
# get the url from req, cut data urls (as mongo has issues inserting big & complex ones)
url = "#{protocol}://#{req.get \host}#{original-url}"
url :=
| (url.trim!.index-of "data:text/html") == 0 => "data:text/html"
| _ => url
# tokenize-ip :: String -> Int -> String
tokenize-ip = (ip, n) ->
(ip or '') .split \.
|> take n
|> Str.join \.
record do
{
ip
ip-tokens: [2 to 3]
|> map -> ["ip#{it}", (tokenize-ip ip, it)]
|> pairs-to-obj
country
headers
ua-tokens: ua-parser-js (req.headers[\user-agent] or "")
url
query-tokens: (require \querystring) .parse ((require \url) .parse url .query)
|> obj-to-pairs
|> map ([key, value])->
key .= replace \., \_
value-parser =
| (/^\d+$/g.test value) => parse-int
| (/^(\d|\.)+$/g.test value) => parse-float
| value == \true => -> true
| value == \false => -> false
| value == '' => -> undefined
| _ => id
[key, if key == \eventArgs then {} else value-parser value]
|> pairs-to-obj
} <<< event-object
{record, record-req}