@athenna/http 4.22.0 → 4.24.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 +8 -7
- package/src/commands/RouteListCommand.js +1 -1
- package/src/context/Request.d.ts +134 -30
- package/src/context/Request.js +143 -39
- package/src/context/Response.d.ts +155 -10
- package/src/context/Response.js +142 -11
- package/src/handlers/FastifyHandler.d.ts +1 -1
- package/src/handlers/FastifyHandler.js +17 -28
- package/src/kernels/HttpKernel.d.ts +4 -0
- package/src/kernels/HttpKernel.js +16 -1
- package/src/server/ServerImpl.js +14 -9
- package/src/types/contexts/Context.d.ts +0 -4
- package/src/types/contexts/ErrorContext.d.ts +2 -10
- package/src/types/contexts/ErrorContext.js +1 -2
- package/src/types/contexts/InterceptContext.d.ts +2 -10
- package/src/types/contexts/InterceptContext.js +1 -2
- package/src/types/contexts/TerminateContext.d.ts +2 -10
- package/src/types/contexts/TerminateContext.js +1 -2
- package/templates/controller.edge +2 -2
- package/templates/interceptor.edge +1 -1
|
@@ -7,65 +7,210 @@
|
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
9
|
import type { FastifyReply } from 'fastify';
|
|
10
|
+
import type { SendOptions } from '@fastify/static';
|
|
11
|
+
import type { Request } from '#src/context/Request';
|
|
10
12
|
import type { FastifyHelmetOptions } from '@fastify/helmet';
|
|
11
13
|
export declare class Response {
|
|
12
14
|
/**
|
|
13
15
|
* The fastify response object.
|
|
14
16
|
*/
|
|
15
17
|
response: FastifyReply;
|
|
16
|
-
constructor(response: FastifyReply);
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
+
* The request object from request context.
|
|
20
|
+
*/
|
|
21
|
+
request: Request;
|
|
22
|
+
constructor(response: FastifyReply, request?: Request);
|
|
23
|
+
/**
|
|
24
|
+
* Verify if the response has been already sent. Keep
|
|
25
|
+
* in mind that this method will only return `true`
|
|
26
|
+
* after `response.send()`, `response.view()`,
|
|
27
|
+
* `response.sendFile()` or `response.download()` methods
|
|
28
|
+
* call.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* if (response.sent) {
|
|
33
|
+
* // do something
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
19
36
|
*/
|
|
20
37
|
get sent(): boolean;
|
|
21
38
|
/**
|
|
22
|
-
* Get the response body sent in response.
|
|
39
|
+
* Get the response body sent in response. Keep
|
|
40
|
+
* in mind that this method will only return `true`
|
|
41
|
+
* after `response.send()`, `response.view()`,
|
|
42
|
+
* `response.sendFile()` or `response.download()` methods
|
|
43
|
+
* call.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const { createdAt, updatedAt } = response.body
|
|
48
|
+
* ```
|
|
23
49
|
*/
|
|
24
50
|
get body(): any | any[];
|
|
25
51
|
/**
|
|
26
|
-
* Get the status code sent in response.
|
|
52
|
+
* Get the status code sent in response. Keep
|
|
53
|
+
* in mind that this method will only return `true`
|
|
54
|
+
* after `response.send()`, `response.view()`,
|
|
55
|
+
* `response.sendFile()` or `response.download()` methods
|
|
56
|
+
* call.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* if (response.statusCode !== 200) {
|
|
61
|
+
* // do something
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
27
64
|
*/
|
|
28
65
|
get statusCode(): number;
|
|
29
66
|
/**
|
|
30
|
-
* Get the headers
|
|
67
|
+
* Get the headers set in the response.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* const headers = response.headers
|
|
72
|
+
* ```
|
|
31
73
|
*/
|
|
32
74
|
get headers(): any;
|
|
33
75
|
/**
|
|
34
|
-
* Get the time in MS of how much the request has
|
|
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
|
+
* ```
|
|
35
86
|
*/
|
|
36
87
|
get responseTime(): number;
|
|
88
|
+
/**
|
|
89
|
+
* Terminate the request sending a view to be rendered.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* return response.view('welcome', { name: 'lenon' })
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
view(view: string, data?: any): Promise<Response>;
|
|
37
97
|
/**
|
|
38
98
|
* Terminate the request sending the response body or not.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* return response.send({ name: 'lenon' })
|
|
103
|
+
* ```
|
|
39
104
|
*/
|
|
40
105
|
send(data?: any): Promise<Response>;
|
|
106
|
+
/**
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* return response.sendFile('img.png')
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
sendFile(filename: string, filepath?: string): Promise<Response>;
|
|
113
|
+
/**
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* return response.sendFile('img.png', { cacheControl: false })
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
sendFile(filename: string, options?: string | SendOptions): Promise<Response>;
|
|
120
|
+
/**
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* return response.sendFile('img.png', Path.tmp(), {
|
|
124
|
+
* cacheControl: false
|
|
125
|
+
* })
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
sendFile(filename: string, filepath?: string, options?: SendOptions): Promise<Response>;
|
|
129
|
+
/**
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* return response.download('img.png', 'custom-img.png')
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
download(filepath: string, filename: string): Promise<Response>;
|
|
136
|
+
/**
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* return response.download('img.png', 'custom-img.png', {
|
|
140
|
+
* cacheControl: false
|
|
141
|
+
* })
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
download(filepath: string, filename: string, options?: SendOptions): Promise<Response>;
|
|
41
145
|
/**
|
|
42
146
|
* Set the response status code.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* return response.status(200).send()
|
|
151
|
+
* ```
|
|
43
152
|
*/
|
|
44
153
|
status(code: number): Response;
|
|
45
154
|
/**
|
|
46
155
|
* Add some header to the response.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* response.header('content-type', 'application/json')
|
|
160
|
+
*
|
|
161
|
+
* return response.header('accept-encoding', 'gzip').send(user)
|
|
162
|
+
* ```
|
|
47
163
|
*/
|
|
48
164
|
header(header: string, value: any): Response;
|
|
49
165
|
/**
|
|
50
166
|
* Verify if response has some header.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* if (response.hasHeader('content-type')) {
|
|
171
|
+
* // do something
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
51
174
|
*/
|
|
52
175
|
hasHeader(header: string): boolean;
|
|
53
176
|
/**
|
|
54
|
-
* Add some header
|
|
55
|
-
* going to be added if is already set.
|
|
177
|
+
* Add some header safely to the response. This means that
|
|
178
|
+
* the header is not going to be added if is already set.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* response.safeHeader('content-type', 'application/json')
|
|
183
|
+
* ```
|
|
56
184
|
*/
|
|
57
185
|
safeHeader(header: string, value: any): Response;
|
|
58
186
|
/**
|
|
59
187
|
* Remove some header from the response.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* response.removeHeader('content-type')
|
|
192
|
+
* ```
|
|
60
193
|
*/
|
|
61
194
|
removeHeader(header: string): Response;
|
|
62
195
|
/**
|
|
63
|
-
* Redirect the response to other url. You can also set a
|
|
64
|
-
* for the redirect.
|
|
196
|
+
* Redirect the response to other url. You can also set a
|
|
197
|
+
* different status code for the redirect.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```ts
|
|
201
|
+
* return response.redirect('users', 304)
|
|
202
|
+
* ```
|
|
65
203
|
*/
|
|
66
204
|
redirectTo(url: string, status?: number): Promise<Response>;
|
|
67
205
|
/**
|
|
68
206
|
* Apply helmet in response.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* return response
|
|
211
|
+
* .helmet({ enableCSPNonces: false })
|
|
212
|
+
* .view('profile', user)
|
|
213
|
+
* ```
|
|
69
214
|
*/
|
|
70
215
|
helmet(options: FastifyHelmetOptions): Response;
|
|
71
216
|
}
|
package/src/context/Response.js
CHANGED
|
@@ -6,50 +6,145 @@
|
|
|
6
6
|
* For the full copyright and license information, please view the LICENSE
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
|
+
import { View } from '@athenna/view';
|
|
9
10
|
export class Response {
|
|
10
|
-
constructor(response) {
|
|
11
|
+
constructor(response, request) {
|
|
11
12
|
this.response = response;
|
|
13
|
+
this.request = request;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
|
-
* Verify if the response has been already sent.
|
|
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
|
+
* ```
|
|
15
28
|
*/
|
|
16
29
|
get sent() {
|
|
17
30
|
return this.response.sent;
|
|
18
31
|
}
|
|
19
32
|
/**
|
|
20
|
-
* Get the response body sent in response.
|
|
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
|
+
* ```
|
|
21
43
|
*/
|
|
22
44
|
get body() {
|
|
23
45
|
return this.response.body;
|
|
24
46
|
}
|
|
25
47
|
/**
|
|
26
|
-
* Get the status code sent in response.
|
|
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
|
+
* ```
|
|
27
60
|
*/
|
|
28
61
|
get statusCode() {
|
|
29
62
|
return this.response.statusCode;
|
|
30
63
|
}
|
|
31
64
|
/**
|
|
32
|
-
* Get the headers
|
|
65
|
+
* Get the headers set in the response.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const headers = response.headers
|
|
70
|
+
* ```
|
|
33
71
|
*/
|
|
34
72
|
get headers() {
|
|
35
73
|
return this.response.getHeaders();
|
|
36
74
|
}
|
|
37
75
|
/**
|
|
38
|
-
* Get the time in MS of how much the request has
|
|
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
|
+
* ```
|
|
39
86
|
*/
|
|
40
87
|
get responseTime() {
|
|
41
|
-
return this.response.
|
|
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').response.send(content);
|
|
101
|
+
this.response.body = content;
|
|
102
|
+
return this;
|
|
42
103
|
}
|
|
43
104
|
/**
|
|
44
105
|
* Terminate the request sending the response body or not.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* return response.send({ name: 'lenon' })
|
|
110
|
+
* ```
|
|
45
111
|
*/
|
|
46
112
|
async send(data) {
|
|
47
113
|
await this.response.send(data);
|
|
48
114
|
this.response.body = data;
|
|
49
115
|
return this;
|
|
50
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
|
+
}
|
|
51
141
|
/**
|
|
52
142
|
* Set the response status code.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* return response.status(200).send()
|
|
147
|
+
* ```
|
|
53
148
|
*/
|
|
54
149
|
status(code) {
|
|
55
150
|
this.response.status(code);
|
|
@@ -57,6 +152,13 @@ export class Response {
|
|
|
57
152
|
}
|
|
58
153
|
/**
|
|
59
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
|
+
* ```
|
|
60
162
|
*/
|
|
61
163
|
header(header, value) {
|
|
62
164
|
this.response.header(header, value);
|
|
@@ -64,13 +166,25 @@ export class Response {
|
|
|
64
166
|
}
|
|
65
167
|
/**
|
|
66
168
|
* Verify if response has some header.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* if (response.hasHeader('content-type')) {
|
|
173
|
+
* // do something
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
67
176
|
*/
|
|
68
177
|
hasHeader(header) {
|
|
69
178
|
return this.response.hasHeader(header);
|
|
70
179
|
}
|
|
71
180
|
/**
|
|
72
|
-
* Add some header
|
|
73
|
-
* going to be added if is already set.
|
|
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
|
+
* ```
|
|
74
188
|
*/
|
|
75
189
|
safeHeader(header, value) {
|
|
76
190
|
this.response.header(header, value);
|
|
@@ -78,14 +192,24 @@ export class Response {
|
|
|
78
192
|
}
|
|
79
193
|
/**
|
|
80
194
|
* Remove some header from the response.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* response.removeHeader('content-type')
|
|
199
|
+
* ```
|
|
81
200
|
*/
|
|
82
201
|
removeHeader(header) {
|
|
83
202
|
this.response.removeHeader(header);
|
|
84
203
|
return this;
|
|
85
204
|
}
|
|
86
205
|
/**
|
|
87
|
-
* Redirect the response to other url. You can also set a
|
|
88
|
-
* for the redirect.
|
|
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
|
+
* ```
|
|
89
213
|
*/
|
|
90
214
|
async redirectTo(url, status) {
|
|
91
215
|
if (status) {
|
|
@@ -97,6 +221,13 @@ export class Response {
|
|
|
97
221
|
}
|
|
98
222
|
/**
|
|
99
223
|
* Apply helmet in response.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* return response
|
|
228
|
+
* .helmet({ enableCSPNonces: false })
|
|
229
|
+
* .view('profile', user)
|
|
230
|
+
* ```
|
|
100
231
|
*/
|
|
101
232
|
helmet(options) {
|
|
102
233
|
this.response.helmet(options);
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* For the full copyright and license information, please view the LICENSE
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
|
-
import type { InterceptHandler, TerminateHandler } from '#src/types';
|
|
10
9
|
import type { RequestHandler } from '#src/types/contexts/Context';
|
|
11
10
|
import type { ErrorHandler } from '#src/types/contexts/ErrorContext';
|
|
11
|
+
import type { InterceptHandler, TerminateHandler } from '#src/types';
|
|
12
12
|
import type { FastifyReply, FastifyRequest, RouteHandlerMethod } from 'fastify';
|
|
13
13
|
export declare class FastifyHandler {
|
|
14
14
|
/**
|
|
@@ -16,20 +16,12 @@ export class FastifyHandler {
|
|
|
16
16
|
*/
|
|
17
17
|
static request(handler) {
|
|
18
18
|
return async (req, res) => {
|
|
19
|
-
const request = new Request(req);
|
|
20
|
-
const response = new Response(res);
|
|
21
19
|
if (!req.data) {
|
|
22
20
|
req.data = {};
|
|
23
21
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
data: req.data,
|
|
28
|
-
body: req.body,
|
|
29
|
-
params: req.params,
|
|
30
|
-
queries: req.query,
|
|
31
|
-
headers: req.headers
|
|
32
|
-
});
|
|
22
|
+
const request = new Request(req);
|
|
23
|
+
const response = new Response(res, request);
|
|
24
|
+
return handler({ request, response, data: req.data });
|
|
33
25
|
};
|
|
34
26
|
}
|
|
35
27
|
/**
|
|
@@ -43,8 +35,11 @@ export class FastifyHandler {
|
|
|
43
35
|
*/
|
|
44
36
|
static intercept(handler) {
|
|
45
37
|
return async (req, res, payload) => {
|
|
38
|
+
if (!req.data) {
|
|
39
|
+
req.data = {};
|
|
40
|
+
}
|
|
46
41
|
const request = new Request(req);
|
|
47
|
-
const response = new Response(res);
|
|
42
|
+
const response = new Response(res, request);
|
|
48
43
|
if (Is.Json(payload)) {
|
|
49
44
|
payload = JSON.parse(payload);
|
|
50
45
|
}
|
|
@@ -53,11 +48,7 @@ export class FastifyHandler {
|
|
|
53
48
|
request,
|
|
54
49
|
response,
|
|
55
50
|
status: response.statusCode,
|
|
56
|
-
data: req.data
|
|
57
|
-
body: res.body,
|
|
58
|
-
params: req.params,
|
|
59
|
-
queries: req.query,
|
|
60
|
-
headers: req.headers
|
|
51
|
+
data: req.data
|
|
61
52
|
});
|
|
62
53
|
res.body = payload;
|
|
63
54
|
if (Is.Object(payload)) {
|
|
@@ -71,18 +62,17 @@ export class FastifyHandler {
|
|
|
71
62
|
*/
|
|
72
63
|
static terminate(handler) {
|
|
73
64
|
return async (req, res) => {
|
|
65
|
+
if (!req.data) {
|
|
66
|
+
req.data = {};
|
|
67
|
+
}
|
|
74
68
|
const request = new Request(req);
|
|
75
|
-
const response = new Response(res);
|
|
69
|
+
const response = new Response(res, request);
|
|
76
70
|
await handler({
|
|
77
71
|
request,
|
|
78
72
|
response,
|
|
79
|
-
params: req.params,
|
|
80
|
-
queries: req.query,
|
|
81
73
|
data: req.data,
|
|
82
|
-
body: res.body || req.body,
|
|
83
|
-
headers: res.getHeaders(),
|
|
84
74
|
status: res.statusCode,
|
|
85
|
-
responseTime: res.
|
|
75
|
+
responseTime: res.elapsedTime
|
|
86
76
|
});
|
|
87
77
|
};
|
|
88
78
|
}
|
|
@@ -91,16 +81,15 @@ export class FastifyHandler {
|
|
|
91
81
|
*/
|
|
92
82
|
static error(handler) {
|
|
93
83
|
return async (error, req, res) => {
|
|
84
|
+
if (!req.data) {
|
|
85
|
+
req.data = {};
|
|
86
|
+
}
|
|
94
87
|
const request = new Request(req);
|
|
95
|
-
const response = new Response(res);
|
|
88
|
+
const response = new Response(res, request);
|
|
96
89
|
await handler({
|
|
97
90
|
request,
|
|
98
91
|
response,
|
|
99
92
|
data: req.data,
|
|
100
|
-
body: res.body || req.body,
|
|
101
|
-
params: req.params,
|
|
102
|
-
queries: req.query,
|
|
103
|
-
headers: req.headers,
|
|
104
93
|
error
|
|
105
94
|
});
|
|
106
95
|
};
|
|
@@ -24,6 +24,10 @@ export declare class HttpKernel {
|
|
|
24
24
|
* Register the @fastify/rate-limit plugin in the Http server.
|
|
25
25
|
*/
|
|
26
26
|
registerRateLimit(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Register the @fastify/static plugin in the Http server.
|
|
29
|
+
*/
|
|
30
|
+
registerStatic(): Promise<void>;
|
|
27
31
|
/**
|
|
28
32
|
* Register the cls-rtracer plugin in the Http server.
|
|
29
33
|
*/
|
|
@@ -13,13 +13,14 @@ import { Log } from '@athenna/logger';
|
|
|
13
13
|
import { Config } from '@athenna/config';
|
|
14
14
|
import { sep, isAbsolute, resolve } from 'node:path';
|
|
15
15
|
import { Annotation } from '@athenna/ioc';
|
|
16
|
-
import { File, Exec, Module, String } from '@athenna/common';
|
|
16
|
+
import { File, Path, Exec, Module, String } from '@athenna/common';
|
|
17
17
|
import { HttpExceptionHandler } from '#src/handlers/HttpExceptionHandler';
|
|
18
18
|
const corsPlugin = await Module.safeImport('@fastify/cors');
|
|
19
19
|
const helmetPlugin = await Module.safeImport('@fastify/helmet');
|
|
20
20
|
const swaggerPlugin = await Module.safeImport('@fastify/swagger');
|
|
21
21
|
const swaggerUiPlugin = await Module.safeImport('@fastify/swagger-ui');
|
|
22
22
|
const rateLimitPlugin = await Module.safeImport('@fastify/rate-limit');
|
|
23
|
+
const staticPlugin = await Module.safeImport('@fastify/static');
|
|
23
24
|
const rTracerPlugin = await Module.safeImport('cls-rtracer');
|
|
24
25
|
export class HttpKernel {
|
|
25
26
|
/**
|
|
@@ -90,6 +91,20 @@ export class HttpKernel {
|
|
|
90
91
|
}
|
|
91
92
|
await Server.plugin(rateLimitPlugin, this.getConfig('http.rateLimit'));
|
|
92
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Register the @fastify/static plugin in the Http server.
|
|
96
|
+
*/
|
|
97
|
+
async registerStatic() {
|
|
98
|
+
if (Config.is('http.static.enabled', false)) {
|
|
99
|
+
debug('Not able to register static plugin. Set the http.static.enabled configuration as true.');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!staticPlugin) {
|
|
103
|
+
debug('Not able to register static plugin. Install @fastify/static package.');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
await Server.plugin(staticPlugin, this.getConfig('http.static'));
|
|
107
|
+
}
|
|
93
108
|
/**
|
|
94
109
|
* Register the cls-rtracer plugin in the Http server.
|
|
95
110
|
*/
|
package/src/server/ServerImpl.js
CHANGED
|
@@ -151,17 +151,22 @@ export class ServerImpl {
|
|
|
151
151
|
});
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
const { middlewares, interceptors, terminators } = options.middlewares;
|
|
155
|
+
const route = {
|
|
155
156
|
url: options.url,
|
|
156
157
|
method: options.methods,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
preHandler
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
158
|
+
handler: FastifyHandler.request(options.handler)
|
|
159
|
+
};
|
|
160
|
+
if (middlewares.length) {
|
|
161
|
+
route.preHandler = middlewares.map(m => FastifyHandler.handle(m));
|
|
162
|
+
}
|
|
163
|
+
if (interceptors.length) {
|
|
164
|
+
route.onSend = interceptors.map(i => FastifyHandler.intercept(i));
|
|
165
|
+
}
|
|
166
|
+
if (terminators.length) {
|
|
167
|
+
route.onResponse = terminators.map(t => FastifyHandler.terminate(t));
|
|
168
|
+
}
|
|
169
|
+
this.fastify.route({ ...route, ...options.fastify });
|
|
165
170
|
}
|
|
166
171
|
/**
|
|
167
172
|
* Add a new GET route to the http server.
|
|
@@ -6,16 +6,8 @@
|
|
|
6
6
|
* For the full copyright and license information, please view the LICENSE
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
export type ErrorContext = {
|
|
12
|
-
request: Request;
|
|
13
|
-
response: Response;
|
|
14
|
-
data: any;
|
|
15
|
-
body: any;
|
|
9
|
+
import type { Context } from '#src/types/contexts/Context';
|
|
10
|
+
export type ErrorContext = Context & {
|
|
16
11
|
error: any;
|
|
17
|
-
params: any;
|
|
18
|
-
queries: any;
|
|
19
|
-
headers: any;
|
|
20
12
|
};
|
|
21
13
|
export type ErrorHandler = (ctx: ErrorContext) => Promise<void>;
|