-
-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathindex.js
More file actions
108 lines (89 loc) · 2.64 KB
/
index.js
File metadata and controls
108 lines (89 loc) · 2.64 KB
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
'use strict'
/**
* restana Web Framework implementation
*
* @license MIT
*/
const requestRouter = require('./libs/request-router')
const applySecurityHeaders = require('./libs/security-headers')
const { deepFreezeObject } = require('./libs/utils')
const exts = {
request: {},
response: require('./libs/response-extensions')
}
module.exports = (options = {}) => {
options.errorHandler =
options.errorHandler ||
((err, req, res) => {
const statusCode = typeof (err.status || err.code || err.statusCode) === 'number'
? (err.status || err.code || err.statusCode)
: 500
res.send({ code: statusCode, message: 'Internal Server Error' }, statusCode)
})
const server = options.server || require('http').createServer()
const prp = undefined === options.prioRequestsProcessing ? true : options.prioRequestsProcessing
if (prp) {
server.on('request', (req, res) => {
setImmediate(() => service.handle(req, res))
})
} else {
server.on('request', (req, res) => {
service.handle(req, res)
})
}
const handle = (req, res) => {
// Default security headers (can be overridden by application or disabled via options)
if (options.securityHeaders !== false) {
applySecurityHeaders(req, res)
}
// request object population
res.send = exts.response.send(options, req, res)
service.getRouter().lookup(req, res)
}
const service = handle
let frozenConfig = null
const service_ = {
errorHandler: options.errorHandler,
newRouter () {
return requestRouter(options)
},
getServer () {
return server
},
getConfigOptions () {
if (!frozenConfig) {
const copy = { ...options }
// Deep-clone + deep-freeze nested plain objects so the user's originals
// are not mutated as a side effect of calling getConfigOptions().
for (const key of Object.keys(copy)) {
if (key !== 'server') {
copy[key] = deepFreezeObject(copy[key])
}
}
frozenConfig = Object.freeze(copy)
}
return frozenConfig
},
handle,
start: (...args) =>
new Promise((resolve, reject) => {
if (!args || !args.length) args = [3000]
server.listen(...args, (err) => {
if (err) reject(err)
resolve(server)
})
}),
close: () =>
new Promise((resolve, reject) => {
server.close((err) => {
if (err) reject(err)
resolve()
})
})
}
Object.assign(service, service_)
// apply router capabilities
requestRouter(options, service)
service.callback = () => service.handle
return service
}