-
Notifications
You must be signed in to change notification settings - Fork 417
/
Copy pathserve.js
127 lines (113 loc) · 3.44 KB
/
serve.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
'use strict';
const BbPromise = require('bluebird');
const webpack = require('webpack');
const express = require('express');
const bodyParser = require('body-parser');
module.exports = {
serve() {
this.serverless.cli.log('Serving functions...');
const compiler = webpack(this.webpackConfig);
const funcConfs = this._getFuncConfigs();
const app = this._newExpressApp(funcConfs);
const port = this._getPort();
app.listen(port, () =>
compiler.watch({}, (err, stats) => {
if (err) {
throw err;
}
const loadedModules = [];
for (let funcConf of funcConfs) {
funcConf.handlerFunc = this.loadHandler(
stats,
funcConf.id,
loadedModules.indexOf(funcConf.moduleName) < 0
);
loadedModules.push(funcConf.moduleName);
}
})
);
return BbPromise.resolve();
},
_newExpressApp(funcConfs) {
const app = express();
app.use(bodyParser.json({ limit: '5mb' }));
for (let funcConf of funcConfs) {
for (let httpEvent of funcConf.events) {
const method = httpEvent.method.toLowerCase();
let endpoint = `/${httpEvent.path}`;
if (this.options.stage) {
endpoint = `/${this.options.stage}${endpoint}`;
}
const path = endpoint.replace(/\{(.+?)\}/g, ':$1');
let handler = this._handlerBase(funcConf);
let optionsHandler = this._optionsHandler;
if (httpEvent.cors) {
handler = this._handlerAddCors(handler);
optionsHandler = this._handlerAddCors(optionsHandler);
}
app.options(path, optionsHandler);
app[method](
path,
handler
);
this.serverless.cli.consoleLog(` ${method.toUpperCase()} - http://localhost:${this._getPort()}${endpoint}`);
}
}
return app;
},
_getFuncConfigs() {
const funcConfs = [];
const inputfuncConfs = this.serverless.service.functions;
for (let funcName in inputfuncConfs) {
const funcConf = inputfuncConfs[funcName];
const httpEvents = funcConf.events
.filter(e => e.hasOwnProperty('http'))
.map(e => e.http);
if (httpEvents.length > 0) {
funcConfs.push(Object.assign({}, funcConf, {
id: funcName,
events: httpEvents,
moduleName: funcConf.handler.split('.')[0],
handlerFunc: null,
}));
}
}
return funcConfs;
},
_getPort() {
return this.options.port || 8000;
},
_handlerAddCors(handler) {
return (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,HEAD,PATCH,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Authorization,Content-Type,x-amz-date,x-amz-security-token');
handler(req, res, next);
};
},
_handlerBase(funcConf) {
return (req, res) => {
const func = funcConf.handlerFunc;
const event = {
method: req.method,
headers: req.headers,
body: req.body,
path: req.params,
query: req.query,
// principalId,
// stageVariables,
};
const context = this.getContext(funcConf.id);
func(event, context, (err, resp) => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(resp);
}
});
}
},
_optionsHandler(req, res) {
res.sendStatus(200);
},
};