-
Notifications
You must be signed in to change notification settings - Fork 1
/
context.js
72 lines (60 loc) · 2.01 KB
/
context.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
68
69
70
71
72
const R = require("ramda");
const {string, number} = require("../data");
const {parse: urlParse} = require("url");
/**
* State and atom store for data event emitters. Prevents multiple attempts to consume the body
*/
function Content(request) {
let consumed = false;
this.consumeContent = function (f) {
if (consumed) {
throw new Error("Content has already been consumed");
}
consumed = true;
return f(request);
};
}
const isEmptyString = R.compose(R.equals(0), string.length);
const split = R.compose(R.filter(R.complement(isEmptyString)), string.split("/"));
const urlStruct = (url) => {
const {query, pathname} = urlParse(url, true);
return {
query,
path: pathname,
pathSplit: split(pathname)
};
};
/**
* Value constructor for context objects. Construct a context object with the listed fields from the request and
* containing a Content object built from the request in the content field
*/
const makeContext = (request) => R.mergeAll([
R.pick(["socket", "httpVersion", "method", "headers"], request),
R.compose(R.objOf("content"), R.construct(Content))(request),
R.compose(urlStruct, R.prop("url"))(request)
]);
const contextParamsLens = R.lensProp("params");
/**
* Run a continuation for consuming the body on a context
*/
const contextConsumeContent = R.curry((f, context) => context.content.consumeContent(f));
/**
* Run a continuation for consuming a body (content)
*/
const consumeContent = R.curry((f, content) => content.consumeContent(f));
const contextHeadersLens = R.lensProp("headers");
const contextContentLens = R.lensProp("content");
const contentLengthLens = R.compose(contextHeadersLens, R.lensProp("content-length"));
const hasBody = (ctx) =>
number.parseInt10(R.view(contentLengthLens, ctx)) > 0;
module.exports = {
urlStruct,
makeContext,
contextParamsLens,
contextConsumeContent,
consumeContent,
contextHeadersLens,
contextContentLens,
contentLengthLens,
hasBody
};