-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
129 lines (111 loc) · 3.88 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
var fs = require('fs');
var sort = require('./lib/sort_routes');
var mappingTemplate = require("api-gateway-mapping-template");
// - Parameters
// - app - `instance of express`
// - routes - `Array<map>`
// - lambda - `Function`
// - method - `String`
// - path - `String`
// - statusCode - `Number`
// - requestTemplates - `map<String, String|Buffer>`
// - responseTemplates - `map<String, String|Buffer>`
module.exports = function(app, routes) {
app.use(function(req, res, next) {
req.rawBody = '';
req.setEncoding('utf8');
req.on('data', function(chunk) { req.rawBody += chunk; });
req.on('end', function() {
next();
});
});
paramRegexp = /^{[a-zA-Z0-9._-]+}$/
normalRegexp = /^[a-zA-Z0-9._-]+$/
sort(routes);
routes.forEach(function(route) {
if (!('responses' in route)) {
throw new Error("responses is not found in route");
}
var path = route.path
.split("/")
.map(function(segment) {
if (segment !== "" && !normalRegexp.test(segment) && !paramRegexp.test(segment)) {
// follows the API Gateway's rule
throw new Error("Resource's path part only allow a-zA-Z0-9._- and curly braces at the begining and the end.");
}
// converts to express style param
if (paramRegexp.test(segment)) {
return ":" + segment.replace(/^{/, "").replace(/}$/, "")
}
return segment;
})
.join("/");
app[route.method.toLowerCase()](path, function(req, res) {
var requestContentType = req.headers['content-type'] || "application/json";
var requestTemplate = route.requestTemplates[requestContentType.toLowerCase()] || "$input.json('$')";
var event = JSON.parse(mappingTemplate({
template: requestTemplate.toString(),
payload: req.rawBody,
params: {
header: req.headers,
path: req.params,
querystring: req.query
},
}));
event['__express_req'] = req; // express's request object for debug
event['__express_res'] = res; // express's response object for debug
var context = {
done: function(err, obj) {
obj = obj || "";
var contentType, responseTemplates, responseTemplate, responseBody, statusCode;
var response;
// default
Object.keys(route.responses).forEach(function(code) {
var res = route.responses[code];
if (!res.selectionPattern) {
statusCode = code;
response = res;
}
});
if (err) {
// selection pattern
Object.keys(route.responses).forEach(function(code) {
var res = route.responses[code];
if ((new RegExp(res.selectionPattern)).test(JSON.stringify(err))) {
statusCode = code;
response = res;
}
});
}
responseTemplates = response.responseTemplates || {};
if (Object.keys(responseTemplates).length > 0) {
contentType = req.accepts(Object.keys(responseTemplates)) || "application/json";
} else {
contentType = "application/json";
}
responseTemplate = responseTemplates[contentType.toLowerCase()] || "$input.json('$')";
if (err) {
// obj = {error: err.toString()};
obj = err
}
responseBody = mappingTemplate({
template: responseTemplate.toString(),
payload: JSON.stringify(obj)
});
res.setHeader("Content-Type", contentType);
res
.status(statusCode)
.send(responseBody);
},
succeed: function(obj) {
this.done(null, obj);
},
fail: function(err) {
this.done(err, null);
},
};
route.lambda(event, context);
});
});
return app;
};