-
Notifications
You must be signed in to change notification settings - Fork 687
/
Copy pathmiddleware.js
113 lines (109 loc) · 3.83 KB
/
middleware.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
const debug = require('debug')('upward-js:middleware');
const jsYaml = require('js-yaml');
const UpwardServerError = require('./UpwardServerError');
const IOAdapter = require('./IOAdapter');
const buildResponse = require('./buildResponse');
class UpwardMiddleware {
constructor(upwardPath, env, io) {
this.env = env;
this.upwardPath = upwardPath;
debug(`created for path ${upwardPath}`);
this.io = io;
}
async load() {
const { upwardPath } = this;
try {
this.yamlTxt = await this.io.readFile(upwardPath);
} catch (e) {
throw new UpwardServerError(e, `unable to read file ${upwardPath}`);
}
debug(`read upward.yml file successfully`);
try {
this.definition = await jsYaml.safeLoad(this.yamlTxt);
} catch (e) {
throw new UpwardServerError(
e,
`error parsing ${upwardPath} contents: \n\n${this.yamlTxt}`
);
}
debug(`parsed upward.yml file successfully: %o`, this.definition);
}
async getHandler() {
return async (req, res, next) => {
const errors = [];
let response;
try {
response = await buildResponse(
this.io,
this.env,
this.definition,
req
);
if (typeof response === 'function') {
debug('buildResponse returned function');
response(req, res, next);
return;
}
if (isNaN(response.status)) {
errors.push(
`Non-numeric status! Status was '${response.status}'`
);
}
if (typeof response.headers !== 'object') {
errors.push(
`Resolved with a non-compliant headers object! Headers are: ${
response.headers
}`
);
}
if (
typeof response.body !== 'string' &&
typeof response.body.toString !== 'function'
) {
errors.push(
`Resolved with a non-serializable body! Body was '${Object.prototype.toString.call(
response.body
)}'`
);
}
} catch (e) {
errors.push(e.message);
}
if (errors.length > 0) {
if (req.accepts('json')) {
res.json({
errors: errors.map(message => ({ message }))
});
} else {
next(
new UpwardServerError(
`Request did not evaluate to a valid response, because: \n${errors.join(
'\n'
)}`
)
);
}
} else {
debug('status, headers, and body valid. responding');
res.status(response.status)
.set(response.headers)
.send(
typeof response.body === 'string'
? response.body
: response.body.toString()
);
}
};
}
}
async function upwardJSMiddlewareFactory(
upwardPath,
env,
io = IOAdapter.default(upwardPath)
) {
const middleware = new UpwardMiddleware(upwardPath, env, io);
await middleware.load();
return middleware.getHandler();
}
upwardJSMiddlewareFactory.UpwardMiddleware = UpwardMiddleware;
module.exports = upwardJSMiddlewareFactory;