@superhero/http-server 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.json +3 -3
- package/{middleware → dispatcher}/upstream/header/accept.js +12 -3
- package/{middleware → dispatcher}/upstream/header/content-type/application/json.js +3 -3
- package/{middleware → dispatcher}/upstream/header/content-type.js +14 -5
- package/{middleware → dispatcher}/upstream/method.js +3 -3
- package/index.test.js +5 -5
- package/package.json +1 -1
package/config.json
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
"locator":
|
|
7
7
|
{
|
|
8
8
|
"@superhero/http-server": true,
|
|
9
|
-
"@superhero/http-server/
|
|
10
|
-
"@superhero/http-server/
|
|
11
|
-
"@superhero/http-server/
|
|
9
|
+
"@superhero/http-server/dispatcher/*/*": "./dispatcher/*/*.js",
|
|
10
|
+
"@superhero/http-server/dispatcher/*/*/*": "./dispatcher/*/*/*.js",
|
|
11
|
+
"@superhero/http-server/dispatcher/*/*/*/*/*": "./dispatcher/*/*/*/*/*.js"
|
|
12
12
|
},
|
|
13
13
|
"http-server":
|
|
14
14
|
{
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @memberof @superhero/http-server:
|
|
2
|
+
* @memberof @superhero/http-server:dispatcher/upstream/header
|
|
3
3
|
*/
|
|
4
|
-
export default new class
|
|
4
|
+
export default new class AcceptHeaderUpstreamDispatcher
|
|
5
5
|
{
|
|
6
6
|
#listFormat = new Intl.ListFormat('en', { style:'long', type:'disjunction' })
|
|
7
7
|
#normalize = (route) => route.replace('accept.', '').trim()
|
|
8
8
|
|
|
9
9
|
dispatch(request, session)
|
|
10
10
|
{
|
|
11
|
+
if(false === !!request.headers['accept'])
|
|
12
|
+
{
|
|
13
|
+
const error = new Error(`The requested resource "${request.method} ${request.url}" requires a accept header`)
|
|
14
|
+
error.code = 'E_HTTP_SERVER_ACCEPT_HEADER_MISSING'
|
|
15
|
+
error.status = 406
|
|
16
|
+
error.cause = `The requested resource requires a accept header to be set`
|
|
17
|
+
return session.abortion.abort(error)
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
const
|
|
12
21
|
splitHeader = request.headers['accept']?.toLowerCase().split(',') || [],
|
|
13
22
|
accepts = splitHeader.map(this.#normalize),
|
|
@@ -42,7 +51,7 @@ export default new class AcceptHeaderUpstreamMiddleware
|
|
|
42
51
|
allowed = supports.map(([ supported ]) => supported),
|
|
43
52
|
error = new Error(`The requested resource "${request.method} ${request.url}" can not be delivered in requested header accept media types: ${this.#listFormat.format(accepts) || 'none are defined'}`)
|
|
44
53
|
|
|
45
|
-
error.code = '
|
|
54
|
+
error.code = 'E_HTTP_SERVER_ACCEPT_HEADER_NO_ROUTE'
|
|
46
55
|
error.status = 406
|
|
47
56
|
error.headers = { accept:allowed.join(',') }
|
|
48
57
|
error.cause = `Supported accept header media types are: ${this.#listFormat.format(allowed) || 'none are defined'}`
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Does not validate headers, just assumes that the body is a JSON string
|
|
3
3
|
*
|
|
4
|
-
* @memberof @superhero/http-server:
|
|
4
|
+
* @memberof @superhero/http-server:dispatcher/upstream/header/content-type/application
|
|
5
5
|
*/
|
|
6
|
-
export default new class
|
|
6
|
+
export default new class ContentTypeApplicationJsonHeaderUpstreamDispatcher
|
|
7
7
|
{
|
|
8
8
|
async dispatch(request, session)
|
|
9
9
|
{
|
|
@@ -18,7 +18,7 @@ export default new class ContentTypeApplicationJsonHeaderUpstreamMiddleware
|
|
|
18
18
|
catch(reason)
|
|
19
19
|
{
|
|
20
20
|
const error = new Error('The body is not a valid JSON string')
|
|
21
|
-
error.code = '
|
|
21
|
+
error.code = 'E_HTTP_SERVER_CONTENT_TYPE_HEADER_APPLICATION_JSON'
|
|
22
22
|
error.status = 400
|
|
23
23
|
error.cause = 'The buffered body could not be parsed as a JSON string'
|
|
24
24
|
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @memberof @superhero/http-server:
|
|
2
|
+
* @memberof @superhero/http-server:dispatcher/upstream/header
|
|
3
3
|
*/
|
|
4
|
-
export default new class
|
|
4
|
+
export default new class ContentTypeHeaderUpstreamDispatcher
|
|
5
5
|
{
|
|
6
6
|
#listFormat = new Intl.ListFormat('en', { style:'long', type:'disjunction' })
|
|
7
7
|
|
|
8
8
|
dispatch(request, session)
|
|
9
9
|
{
|
|
10
|
+
if(false === !!request.headers['content-type'])
|
|
11
|
+
{
|
|
12
|
+
const error = new Error(`The requested resource "${request.method} ${request.url}" requires a content-type header`)
|
|
13
|
+
error.code = 'E_HTTP_SERVER_CONTENT_TYPE_HEADER_MISSING'
|
|
14
|
+
error.status = 415
|
|
15
|
+
error.cause = `The requested resource requires a content-type header to be set`
|
|
16
|
+
return session.abortion.abort(error)
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
const
|
|
11
|
-
contentType = request.headers['content-type']
|
|
20
|
+
contentType = request.headers['content-type'].toLowerCase().split(';')[0].split('*')[0].trim(),
|
|
12
21
|
routes = Object.keys(session.route).filter((key) => key.startsWith('content-type.') && session.route[key]),
|
|
13
22
|
supports = routes.map((route) => [route.replace('content-type.', '').trim(), route])
|
|
14
23
|
|
|
@@ -30,12 +39,12 @@ export default new class ContentTypeHeaderUpstreamMiddleware
|
|
|
30
39
|
return
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
|
-
|
|
42
|
+
|
|
34
43
|
const
|
|
35
44
|
allowed = supports.map(([ supported ]) => supported),
|
|
36
45
|
error = new Error(`The requested resource "${request.method} ${request.url}" does not support content-type "${request.headers['content-type']}"`)
|
|
37
46
|
|
|
38
|
-
error.code = '
|
|
47
|
+
error.code = 'E_HTTP_SERVER_CONTENT_TYPE_HEADER_NO_ROUTE'
|
|
39
48
|
error.status = 415
|
|
40
49
|
error.headers = { accept:allowed.join(',') }
|
|
41
50
|
error.cause = `Supported content-type headers are: ${this.#listFormat.format(allowed) || 'none are defined'}`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @memberof @superhero/http-server:
|
|
2
|
+
* @memberof @superhero/http-server:dispatcher/upstream
|
|
3
3
|
*/
|
|
4
|
-
export default new class
|
|
4
|
+
export default new class MethodUpstreamDispatcher
|
|
5
5
|
{
|
|
6
6
|
#listFormat = new Intl.ListFormat('en', { style:'long', type:'disjunction' })
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ export default new class MethodUpstreamMiddleware
|
|
|
28
28
|
allowed = supports.map((supported) => supported.replace('method.', '').toUpperCase()).sort(),
|
|
29
29
|
error = new Error(`The requested resource "${request.url}" does not support method "${request.method}"`)
|
|
30
30
|
|
|
31
|
-
error.code = '
|
|
31
|
+
error.code = 'E_HTTP_SERVER_METHOD_NO_ROUTE'
|
|
32
32
|
error.status = 405
|
|
33
33
|
error.headers = { allow:allowed.join(',') }
|
|
34
34
|
error.cause = `Supported methods are: ${this.#listFormat.format(allowed) || 'none are defined'}`
|
package/index.test.js
CHANGED
|
@@ -75,12 +75,12 @@ suite('@superhero/http-server', () =>
|
|
|
75
75
|
assert.ok(config.find('http-server/router/routes'))
|
|
76
76
|
|
|
77
77
|
await locator.eagerload(config.find('locator'))
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
assert.ok(locator.has('@superhero/http-server'))
|
|
80
|
-
assert.ok(locator.has('@superhero/http-server/
|
|
81
|
-
assert.ok(locator.has('@superhero/http-server/
|
|
82
|
-
assert.ok(locator.has('@superhero/http-server/
|
|
83
|
-
assert.ok(locator.has('@superhero/http-server/
|
|
80
|
+
assert.ok(locator.has('@superhero/http-server/dispatcher/upstream/method'))
|
|
81
|
+
assert.ok(locator.has('@superhero/http-server/dispatcher/upstream/header/accept'))
|
|
82
|
+
assert.ok(locator.has('@superhero/http-server/dispatcher/upstream/header/content-type'))
|
|
83
|
+
assert.ok(locator.has('@superhero/http-server/dispatcher/upstream/header/content-type/application/json'))
|
|
84
84
|
})
|
|
85
85
|
|
|
86
86
|
test('Listens and closes the server as expected', async () =>
|