@athenna/http 4.25.0 → 4.27.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/package.json +4 -1
- package/src/context/Request.d.ts +243 -34
- package/src/context/Request.js +312 -75
- package/src/context/Response.d.ts +210 -5
- package/src/context/Response.js +231 -78
- package/src/handlers/FastifyHandler.js +12 -12
- package/src/kernels/HttpKernel.js +6 -2
- package/src/server/ServerImpl.js +1 -1
- package/src/types/contexts/Context.d.ts +2 -452
package/src/context/Response.js
CHANGED
|
@@ -7,83 +7,236 @@
|
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
9
|
import { View } from '@athenna/view';
|
|
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
|
-
|
|
10
|
+
export class Response {
|
|
11
|
+
constructor(response, request) {
|
|
12
|
+
this.response = response;
|
|
13
|
+
this.request = request;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Verify if the response has been already sent. Keep
|
|
17
|
+
* in mind that this method will only return `true`
|
|
18
|
+
* after `response.send()`, `response.view()`,
|
|
19
|
+
* `response.sendFile()` or `response.download()` methods
|
|
20
|
+
* call.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* if (response.sent) {
|
|
25
|
+
* // do something
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
get sent() {
|
|
30
|
+
return this.response.sent;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the response body sent in response. Keep
|
|
34
|
+
* in mind that this method will only return `true`
|
|
35
|
+
* after `response.send()`, `response.view()`,
|
|
36
|
+
* `response.sendFile()` or `response.download()` methods
|
|
37
|
+
* call.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const { createdAt, updatedAt } = response.body
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
get body() {
|
|
45
|
+
return this.response.body;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the status code sent in response. Keep
|
|
49
|
+
* in mind that this method will only return `true`
|
|
50
|
+
* after `response.send()`, `response.view()`,
|
|
51
|
+
* `response.sendFile()` or `response.download()` methods
|
|
52
|
+
* call.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* if (response.statusCode !== 200) {
|
|
57
|
+
* // do something
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
get statusCode() {
|
|
62
|
+
return this.response.statusCode;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get the headers set in the response.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const headers = response.headers
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
get headers() {
|
|
73
|
+
return this.response.getHeaders();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the time in MS of how much the request has
|
|
77
|
+
* taken to response. Keep in mind that this method
|
|
78
|
+
* will only return `true` after `response.send()`,
|
|
79
|
+
* `response.view()`, `response.sendFile()` or
|
|
80
|
+
* `response.download()` methods call.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* console.log(response.responseTime) // 1000
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
get responseTime() {
|
|
88
|
+
return this.response.elapsedTime;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Terminate the request sending a view to be rendered.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* return response.view('welcome', { name: 'lenon' })
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
async view(view, data) {
|
|
99
|
+
const content = await View.render(view, { ...data, request: this.request });
|
|
100
|
+
await this.safeHeader('Content-Type', 'text/html; charset=utf-8').send(content);
|
|
101
|
+
this.response.body = content;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Terminate the request sending the response body or not.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* return response.send({ name: 'lenon' })
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
async send(data) {
|
|
113
|
+
await this.response.send(data);
|
|
114
|
+
this.response.body = data;
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Terminate the request sending a file.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* return response.sendFile('img.png')
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
async sendFile(filename, filepath, options) {
|
|
126
|
+
await this.response.sendFile(filename, filepath, options);
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Terminate the request sending a file with custom name.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* return response.download('img.png', 'custom-img.png')
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
async download(filepath, filename, options) {
|
|
138
|
+
await this.response.download(filename, filepath, options);
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Set the response status code.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* return response.status(200).send()
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
status(code) {
|
|
150
|
+
this.response.status(code);
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Add some header to the response.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* response.header('content-type', 'application/json')
|
|
159
|
+
*
|
|
160
|
+
* return response.header('accept-encoding', 'gzip').send(user)
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
header(header, value) {
|
|
164
|
+
this.response.header(header, value);
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Verify if response has some header.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* if (response.hasHeader('content-type')) {
|
|
173
|
+
* // do something
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
hasHeader(header) {
|
|
178
|
+
return this.response.hasHeader(header);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Add some header safely to the response. This means that
|
|
182
|
+
* the header is not going to be added if is already set.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```ts
|
|
186
|
+
* response.safeHeader('content-type', 'application/json')
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
safeHeader(header, value) {
|
|
190
|
+
this.response.header(header, value);
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Remove some header from the response.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* response.removeHeader('content-type')
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
removeHeader(header) {
|
|
202
|
+
this.response.removeHeader(header);
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Redirect the response to other url. You can also set a
|
|
207
|
+
* different status code for the redirect.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* return response.redirect('users', 304)
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
async redirectTo(url, status) {
|
|
215
|
+
if (status) {
|
|
216
|
+
await this.response.redirect(status, url);
|
|
217
|
+
return this;
|
|
86
218
|
}
|
|
87
|
-
|
|
88
|
-
|
|
219
|
+
await this.response.redirect(url);
|
|
220
|
+
return this;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Apply helmet in response.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* return response
|
|
228
|
+
* .helmet({ enableCSPNonces: false })
|
|
229
|
+
* .view('profile', user)
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
helmet(options) {
|
|
233
|
+
this.response.helmet(options);
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get the original fastify response.
|
|
238
|
+
*/
|
|
239
|
+
getFastifyResponse() {
|
|
240
|
+
return this.response;
|
|
241
|
+
}
|
|
89
242
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
9
|
import { Is } from '@athenna/common';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { Request } from '#src/context/Request';
|
|
11
|
+
import { Response } from '#src/context/Response';
|
|
12
12
|
export class FastifyHandler {
|
|
13
13
|
/**
|
|
14
14
|
* Parse the fastify request handler and the preHandler hook to an Athenna
|
|
@@ -21,9 +21,9 @@ export class FastifyHandler {
|
|
|
21
21
|
}
|
|
22
22
|
const ctx = {};
|
|
23
23
|
ctx.data = req.data;
|
|
24
|
-
ctx.request =
|
|
25
|
-
ctx.response =
|
|
26
|
-
|
|
24
|
+
ctx.request = new Request(req);
|
|
25
|
+
ctx.response = new Response(res, ctx.request);
|
|
26
|
+
await handler(ctx);
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -46,11 +46,11 @@ export class FastifyHandler {
|
|
|
46
46
|
res.body = payload;
|
|
47
47
|
const ctx = {};
|
|
48
48
|
ctx.data = req.data;
|
|
49
|
-
ctx.request =
|
|
50
|
-
ctx.response =
|
|
49
|
+
ctx.request = new Request(req);
|
|
50
|
+
ctx.response = new Response(res, ctx.request);
|
|
51
51
|
ctx.status = ctx.response.statusCode;
|
|
52
52
|
payload = await handler(ctx);
|
|
53
|
-
|
|
53
|
+
req.body = payload;
|
|
54
54
|
if (Is.Object(payload)) {
|
|
55
55
|
payload = JSON.stringify(payload);
|
|
56
56
|
}
|
|
@@ -67,8 +67,8 @@ export class FastifyHandler {
|
|
|
67
67
|
}
|
|
68
68
|
const ctx = {};
|
|
69
69
|
ctx.data = req.data;
|
|
70
|
-
ctx.request =
|
|
71
|
-
ctx.response =
|
|
70
|
+
ctx.request = new Request(req);
|
|
71
|
+
ctx.response = new Response(res, ctx.request);
|
|
72
72
|
ctx.status = ctx.response.statusCode;
|
|
73
73
|
ctx.responseTime = ctx.response.elapsedTime;
|
|
74
74
|
await handler(ctx);
|
|
@@ -84,8 +84,8 @@ export class FastifyHandler {
|
|
|
84
84
|
}
|
|
85
85
|
const ctx = {};
|
|
86
86
|
ctx.data = req.data;
|
|
87
|
-
ctx.request =
|
|
88
|
-
ctx.response =
|
|
87
|
+
ctx.request = new Request(req);
|
|
88
|
+
ctx.response = new Response(res, ctx.request);
|
|
89
89
|
ctx.error = error;
|
|
90
90
|
await handler(ctx);
|
|
91
91
|
};
|
|
@@ -60,11 +60,12 @@ export class HttpKernel {
|
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
if (swaggerPlugin) {
|
|
63
|
-
debug('Not able to register swagger plugin. Install @fastify/swagger package.');
|
|
64
63
|
await Server.plugin(swaggerPlugin, Config.get('http.swagger.configurations'));
|
|
65
64
|
}
|
|
65
|
+
else {
|
|
66
|
+
debug('Not able to register swagger plugin. Install @fastify/swagger package.');
|
|
67
|
+
}
|
|
66
68
|
if (swaggerUiPlugin) {
|
|
67
|
-
debug('Not able to register swagger-ui plugin. Install @fastify/swagger-ui package.');
|
|
68
69
|
const swaggerUiConfig = Config.get('http.swagger.ui', {});
|
|
69
70
|
if (!swaggerUiConfig.logo) {
|
|
70
71
|
const __dirname = Module.createDirname(import.meta.url);
|
|
@@ -76,6 +77,9 @@ export class HttpKernel {
|
|
|
76
77
|
}
|
|
77
78
|
await Server.plugin(swaggerUiPlugin, swaggerUiConfig);
|
|
78
79
|
}
|
|
80
|
+
else {
|
|
81
|
+
debug('Not able to register swagger-ui plugin. Install @fastify/swagger-ui package.');
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
/**
|
|
81
85
|
* Register the @fastify/rate-limit plugin in the Http server.
|
package/src/server/ServerImpl.js
CHANGED
|
@@ -125,7 +125,7 @@ export class ServerImpl {
|
|
|
125
125
|
if (!this.isListening) {
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
await this.fastify.close().then(() => (this.isListening =
|
|
128
|
+
await this.fastify.close().then(() => (this.isListening = false));
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
131
|
* Add a new route to the http server.
|