@athenna/http 4.23.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@athenna/http",
3
- "version": "4.23.0",
3
+ "version": "4.24.0",
4
4
  "description": "The Athenna Http server. Built on top of fastify.",
5
5
  "license": "MIT",
6
6
  "author": "João Lenon <lenon@athenna.io>",
@@ -72,14 +72,14 @@
72
72
  "#tests": "./tests/index.js"
73
73
  },
74
74
  "devDependencies": {
75
- "@athenna/artisan": "^4.37.0",
76
- "@athenna/common": "^4.34.0",
77
- "@athenna/config": "^4.16.0",
78
- "@athenna/ioc": "^4.16.0",
79
- "@athenna/logger": "^4.17.0",
75
+ "@athenna/artisan": "^4.38.0",
76
+ "@athenna/common": "^4.35.0",
77
+ "@athenna/config": "^4.18.0",
78
+ "@athenna/ioc": "^4.18.0",
79
+ "@athenna/logger": "^4.18.0",
80
80
  "@athenna/test": "^4.22.0",
81
81
  "@athenna/tsconfig": "^4.12.0",
82
- "@athenna/view": "^4.18.0",
82
+ "@athenna/view": "^4.20.0",
83
83
  "@fastify/cors": "^8.4.2",
84
84
  "@fastify/helmet": "^11.1.1",
85
85
  "@fastify/rate-limit": "^8.1.1",
@@ -8,8 +8,8 @@
8
8
  */
9
9
  import { sep } from 'node:path';
10
10
  import { Config } from '@athenna/config';
11
- import { Module } from '@athenna/common';
12
11
  import { BaseCommand } from '@athenna/artisan';
12
+ import { Path, Module } from '@athenna/common';
13
13
  import { Route, HttpKernel, HttpRouteProvider, HttpServerProvider } from '#src';
14
14
  export class RouteListCommand extends BaseCommand {
15
15
  static signature() {
@@ -16,121 +16,225 @@ export declare class Request {
16
16
  /**
17
17
  * Get the request id.
18
18
  *
19
- * @example 12345
19
+ * @example
20
+ * ```ts
21
+ * console.log(request.id) // '12345'
22
+ * ```
20
23
  */
21
24
  get id(): string;
22
25
  /**
23
26
  * Get the request ip.
24
27
  *
25
- * @example 192.168.0.1
28
+ * @example
29
+ * ```ts
30
+ * console.log(request.ip) // '192.168.0.1'
31
+ * ```
26
32
  */
27
33
  get ip(): string;
28
34
  /**
29
35
  * Get the request hostname.
30
36
  *
31
- * @example localhost
37
+ * @example
38
+ * ```ts
39
+ * console.log(request.hostname) // 'localhost'
40
+ * ```
32
41
  */
33
42
  get hostname(): string;
43
+ /**
44
+ * Get the server port.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * console.log(request.port) // 3000
49
+ * ```
50
+ */
51
+ get port(): number;
52
+ /**
53
+ * Get the http version.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * console.log(request.version) // 1
58
+ * ```
59
+ */
60
+ get version(): string;
34
61
  /**
35
62
  * Get the request protocol.
36
63
  *
37
- * @example http
64
+ * @example
65
+ * ```ts
66
+ * console.log(request.protocol) // 'http'
67
+ * ```
38
68
  */
39
69
  get protocol(): 'http' | 'https';
40
70
  /**
41
71
  * Get the request method.
42
72
  *
43
- * @example GET
73
+ * @example
74
+ * ```ts
75
+ * console.log(request.method) // 'GET'
76
+ * ```
44
77
  */
45
78
  get method(): string;
46
79
  /**
47
80
  * Get the base url from request.
48
81
  *
49
- * @example /users/1
82
+ * @example
83
+ * ```ts
84
+ * console.log(request.baseUrl) // '/users/1'
85
+ * ```
50
86
  */
51
87
  get baseUrl(): string;
52
88
  /**
53
89
  * Get the base url with host and port info from request.
54
90
  *
55
- * @example http://localhost:3030/users/1
91
+ * @example
92
+ * ```ts
93
+ * console.log(request.baseHostUrl) // 'http://localhost:3030/users/1'
94
+ * ```
56
95
  */
57
96
  get baseHostUrl(): string;
58
97
  /**
59
98
  * Get the route url from request.
60
99
  *
61
- * @example /users/:id
100
+ * @example
101
+ * ```ts
102
+ * console.log(request.routeUrl) // '/users/:id'
103
+ * ```
62
104
  */
63
105
  get routeUrl(): string;
64
106
  /**
65
107
  * Get the route url with host and port info from request.
66
108
  *
67
- * @example http://localhost:3030/users/:id
109
+ * @example
110
+ * ```ts
111
+ * console.log(request.routeHostUrl) // 'http://localhost:3030/users/:id'
112
+ * ```
68
113
  */
69
114
  get routeHostUrl(): string;
70
115
  /**
71
116
  * Get the original url from request.
72
117
  *
73
- * @example /users/1?query=true
118
+ * @example
119
+ * ```ts
120
+ * console.log(request.originalUrl) // '/users/1?query=true'
121
+ * ```
74
122
  */
75
123
  get originalUrl(): string;
76
124
  /**
77
125
  * Get the original url with host and port info from request.
78
126
  *
79
- * @example /users/1?query=true
127
+ * @example
128
+ * ```ts
129
+ * console.log(request.originalHostUrl) // 'http://localhost:3000/users/1?query=true'
130
+ * ```
80
131
  */
81
132
  get originalHostUrl(): string;
82
133
  /**
83
134
  * Get all body from request.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const { name, email } = request.body
139
+ * ```
84
140
  */
85
141
  get body(): any | any[];
86
142
  /**
87
143
  * Get all params from request.
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * const { id } = request.params
148
+ * ```
88
149
  */
89
150
  get params(): any;
90
151
  /**
91
152
  * Get all queries from request.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * const { page, limit } = request.queries
157
+ * ```
92
158
  */
93
159
  get queries(): any;
94
160
  /**
95
161
  * Get all headers from request.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * const { accept } = request.headers
166
+ * ```
96
167
  */
97
168
  get headers(): any;
98
169
  /**
99
- * Get the server port.
100
- */
101
- get port(): number;
102
- /**
103
- * Get the http version.
104
- */
105
- get version(): string;
106
- /**
107
- * Get a value from the request params or the default value.
170
+ * Get a value from the request params or return
171
+ * the default value.
172
+ *
173
+ * @example
174
+ * ```ts
175
+ * const id = request.param('id', '1')
176
+ * ```
108
177
  */
109
178
  param(param: string, defaultValue?: any): any;
110
179
  /**
111
- * Get a value from the request query param or the default value.
180
+ * Get a value from the request query param or return
181
+ * the default value.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const page = request.query('page', '1')
186
+ * ```
112
187
  */
113
188
  query(query: string, defaultValue?: any): any;
114
189
  /**
115
- * Get a value from the request header or the default value.
190
+ * Get a value from the request header or return
191
+ * the default value.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * const accept = request.header('accept', 'application/json')
196
+ * ```
116
197
  */
117
198
  header(header: string, defaultValue?: any): any;
118
199
  /**
119
- * Get only the selected values from the request body.
200
+ * Get a value from the request body or return
201
+ * the default value.
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * const name = request.input('name', 'lenon')
206
+ * ```
120
207
  */
121
- only(keys: string[]): any;
208
+ input(key: string, defaultValue?: any): any;
122
209
  /**
123
- * Get all the values from the request body except the selected ones.
210
+ * Get a value from the request body or return
211
+ * the default value.
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * const name = request.payload('name', 'lenon')
216
+ * ```
124
217
  */
125
- except(keys: string[]): any;
218
+ payload(key: string, defaultValue?: any): any;
126
219
  /**
127
- * Get a value from the request body or the default value.
220
+ * Get only the selected values from the request body.
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * const body = request.only(['name', 'email'])
225
+ * ```
128
226
  */
129
- input(key: string, defaultValue?: any): any;
227
+ only(keys: string[]): any;
130
228
  /**
131
- * Get a value from the request body or the default value.
229
+ * Get all the values from the request body except the
230
+ * selected ones.
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * const body = request.except(['name'])
235
+ * ```
132
236
  */
133
- payload(key: string, defaultValue?: any): any;
237
+ except(keys: string[]): any;
134
238
  /**
135
239
  * Add the hostname and port to the url.
136
240
  */
@@ -14,7 +14,10 @@ export class Request {
14
14
  /**
15
15
  * Get the request id.
16
16
  *
17
- * @example 12345
17
+ * @example
18
+ * ```ts
19
+ * console.log(request.id) // '12345'
20
+ * ```
18
21
  */
19
22
  get id() {
20
23
  return this.request.id;
@@ -22,7 +25,10 @@ export class Request {
22
25
  /**
23
26
  * Get the request ip.
24
27
  *
25
- * @example 192.168.0.1
28
+ * @example
29
+ * ```ts
30
+ * console.log(request.ip) // '192.168.0.1'
31
+ * ```
26
32
  */
27
33
  get ip() {
28
34
  return this.request.ip;
@@ -30,15 +36,43 @@ export class Request {
30
36
  /**
31
37
  * Get the request hostname.
32
38
  *
33
- * @example localhost
39
+ * @example
40
+ * ```ts
41
+ * console.log(request.hostname) // 'localhost'
42
+ * ```
34
43
  */
35
44
  get hostname() {
36
45
  return this.request.hostname;
37
46
  }
47
+ /**
48
+ * Get the server port.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * console.log(request.port) // 3000
53
+ * ```
54
+ */
55
+ get port() {
56
+ return this.getAddressInfo().port;
57
+ }
58
+ /**
59
+ * Get the http version.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * console.log(request.version) // 1
64
+ * ```
65
+ */
66
+ get version() {
67
+ return this.request.raw.httpVersion;
68
+ }
38
69
  /**
39
70
  * Get the request protocol.
40
71
  *
41
- * @example http
72
+ * @example
73
+ * ```ts
74
+ * console.log(request.protocol) // 'http'
75
+ * ```
42
76
  */
43
77
  get protocol() {
44
78
  return this.request.protocol;
@@ -46,7 +80,10 @@ export class Request {
46
80
  /**
47
81
  * Get the request method.
48
82
  *
49
- * @example GET
83
+ * @example
84
+ * ```ts
85
+ * console.log(request.method) // 'GET'
86
+ * ```
50
87
  */
51
88
  get method() {
52
89
  return this.request.method;
@@ -54,7 +91,10 @@ export class Request {
54
91
  /**
55
92
  * Get the base url from request.
56
93
  *
57
- * @example /users/1
94
+ * @example
95
+ * ```ts
96
+ * console.log(request.baseUrl) // '/users/1'
97
+ * ```
58
98
  */
59
99
  get baseUrl() {
60
100
  return this.request.url.split('?')[0];
@@ -62,7 +102,10 @@ export class Request {
62
102
  /**
63
103
  * Get the base url with host and port info from request.
64
104
  *
65
- * @example http://localhost:3030/users/1
105
+ * @example
106
+ * ```ts
107
+ * console.log(request.baseHostUrl) // 'http://localhost:3030/users/1'
108
+ * ```
66
109
  */
67
110
  get baseHostUrl() {
68
111
  return this.getHostUrlFor(this.baseUrl);
@@ -70,7 +113,10 @@ export class Request {
70
113
  /**
71
114
  * Get the route url from request.
72
115
  *
73
- * @example /users/:id
116
+ * @example
117
+ * ```ts
118
+ * console.log(request.routeUrl) // '/users/:id'
119
+ * ```
74
120
  */
75
121
  get routeUrl() {
76
122
  return this.request.routeOptions.url;
@@ -78,7 +124,10 @@ export class Request {
78
124
  /**
79
125
  * Get the route url with host and port info from request.
80
126
  *
81
- * @example http://localhost:3030/users/:id
127
+ * @example
128
+ * ```ts
129
+ * console.log(request.routeHostUrl) // 'http://localhost:3030/users/:id'
130
+ * ```
82
131
  */
83
132
  get routeHostUrl() {
84
133
  return this.getHostUrlFor(this.routeUrl);
@@ -86,7 +135,10 @@ export class Request {
86
135
  /**
87
136
  * Get the original url from request.
88
137
  *
89
- * @example /users/1?query=true
138
+ * @example
139
+ * ```ts
140
+ * console.log(request.originalUrl) // '/users/1?query=true'
141
+ * ```
90
142
  */
91
143
  get originalUrl() {
92
144
  return this.request.url;
@@ -94,67 +146,125 @@ export class Request {
94
146
  /**
95
147
  * Get the original url with host and port info from request.
96
148
  *
97
- * @example /users/1?query=true
149
+ * @example
150
+ * ```ts
151
+ * console.log(request.originalHostUrl) // 'http://localhost:3000/users/1?query=true'
152
+ * ```
98
153
  */
99
154
  get originalHostUrl() {
100
155
  return this.getHostUrlFor(this.originalUrl);
101
156
  }
102
157
  /**
103
158
  * Get all body from request.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const { name, email } = request.body
163
+ * ```
104
164
  */
105
165
  get body() {
106
166
  return this.request.body || {};
107
167
  }
108
168
  /**
109
169
  * Get all params from request.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * const { id } = request.params
174
+ * ```
110
175
  */
111
176
  get params() {
112
177
  return this.request.params || {};
113
178
  }
114
179
  /**
115
180
  * Get all queries from request.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const { page, limit } = request.queries
185
+ * ```
116
186
  */
117
187
  get queries() {
118
188
  return this.request.query || {};
119
189
  }
120
190
  /**
121
191
  * Get all headers from request.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * const { accept } = request.headers
196
+ * ```
122
197
  */
123
198
  get headers() {
124
199
  return this.request.headers || {};
125
200
  }
126
201
  /**
127
- * Get the server port.
202
+ * Get a value from the request params or return
203
+ * the default value.
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const id = request.param('id', '1')
208
+ * ```
128
209
  */
129
- get port() {
130
- return this.getAddressInfo().port;
210
+ param(param, defaultValue) {
211
+ return Json.get(this.params, param, defaultValue);
131
212
  }
132
213
  /**
133
- * Get the http version.
214
+ * Get a value from the request query param or return
215
+ * the default value.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * const page = request.query('page', '1')
220
+ * ```
134
221
  */
135
- get version() {
136
- return this.request.raw.httpVersion;
222
+ query(query, defaultValue) {
223
+ return Json.get(this.queries, query, defaultValue);
137
224
  }
138
225
  /**
139
- * Get a value from the request params or the default value.
226
+ * Get a value from the request header or return
227
+ * the default value.
228
+ *
229
+ * @example
230
+ * ```ts
231
+ * const accept = request.header('accept', 'application/json')
232
+ * ```
140
233
  */
141
- param(param, defaultValue) {
142
- return this.params[param] || defaultValue;
234
+ header(header, defaultValue) {
235
+ return Json.get(this.headers, header, defaultValue);
143
236
  }
144
237
  /**
145
- * Get a value from the request query param or the default value.
238
+ * Get a value from the request body or return
239
+ * the default value.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * const name = request.input('name', 'lenon')
244
+ * ```
146
245
  */
147
- query(query, defaultValue) {
148
- return this.queries[query] || defaultValue;
246
+ input(key, defaultValue) {
247
+ return this.payload(key, defaultValue);
149
248
  }
150
249
  /**
151
- * Get a value from the request header or the default value.
250
+ * Get a value from the request body or return
251
+ * the default value.
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * const name = request.payload('name', 'lenon')
256
+ * ```
152
257
  */
153
- header(header, defaultValue) {
154
- return this.headers[header] || defaultValue;
258
+ payload(key, defaultValue) {
259
+ return Json.get(this.body, key, defaultValue);
155
260
  }
156
261
  /**
157
262
  * Get only the selected values from the request body.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * const body = request.only(['name', 'email'])
267
+ * ```
158
268
  */
159
269
  only(keys) {
160
270
  const body = {};
@@ -167,7 +277,13 @@ export class Request {
167
277
  return body;
168
278
  }
169
279
  /**
170
- * Get all the values from the request body except the selected ones.
280
+ * Get all the values from the request body except the
281
+ * selected ones.
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * const body = request.except(['name'])
286
+ * ```
171
287
  */
172
288
  except(keys) {
173
289
  const body = {};
@@ -179,18 +295,6 @@ export class Request {
179
295
  });
180
296
  return body;
181
297
  }
182
- /**
183
- * Get a value from the request body or the default value.
184
- */
185
- input(key, defaultValue) {
186
- return this.payload(key, defaultValue);
187
- }
188
- /**
189
- * Get a value from the request body or the default value.
190
- */
191
- payload(key, defaultValue) {
192
- return Json.get(this.body, key, defaultValue);
193
- }
194
298
  /**
195
299
  * Add the hostname and port to the url.
196
300
  */
@@ -21,67 +21,196 @@ export declare class Response {
21
21
  request: Request;
22
22
  constructor(response: FastifyReply, request?: Request);
23
23
  /**
24
- * Verify if the response has been already sent.
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
+ * ```
25
36
  */
26
37
  get sent(): boolean;
27
38
  /**
28
- * 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
+ * ```
29
49
  */
30
50
  get body(): any | any[];
31
51
  /**
32
- * 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
+ * ```
33
64
  */
34
65
  get statusCode(): number;
35
66
  /**
36
- * Get the headers sent in response.
67
+ * Get the headers set in the response.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * const headers = response.headers
72
+ * ```
37
73
  */
38
74
  get headers(): any;
39
75
  /**
40
- * Get the time in MS of how much the request has taken to response.
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
+ * ```
41
86
  */
42
87
  get responseTime(): number;
43
88
  /**
44
- * Terminated the request sending a view to be rendered.
89
+ * Terminate the request sending a view to be rendered.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * return response.view('welcome', { name: 'lenon' })
94
+ * ```
45
95
  */
46
96
  view(view: string, data?: any): Promise<Response>;
47
97
  /**
48
98
  * Terminate the request sending the response body or not.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * return response.send({ name: 'lenon' })
103
+ * ```
49
104
  */
50
105
  send(data?: any): Promise<Response>;
106
+ /**
107
+ * @example
108
+ * ```ts
109
+ * return response.sendFile('img.png')
110
+ * ```
111
+ */
51
112
  sendFile(filename: string, filepath?: string): Promise<Response>;
113
+ /**
114
+ * @example
115
+ * ```ts
116
+ * return response.sendFile('img.png', { cacheControl: false })
117
+ * ```
118
+ */
52
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
+ */
53
128
  sendFile(filename: string, filepath?: string, options?: SendOptions): Promise<Response>;
54
- download(filepath: string, filename?: string): Promise<Response>;
55
- download(filepath: string, options?: string | SendOptions): Promise<Response>;
56
- download(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>;
57
145
  /**
58
146
  * Set the response status code.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * return response.status(200).send()
151
+ * ```
59
152
  */
60
153
  status(code: number): Response;
61
154
  /**
62
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
+ * ```
63
163
  */
64
164
  header(header: string, value: any): Response;
65
165
  /**
66
166
  * Verify if response has some header.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * if (response.hasHeader('content-type')) {
171
+ * // do something
172
+ * }
173
+ * ```
67
174
  */
68
175
  hasHeader(header: string): boolean;
69
176
  /**
70
- * Add some header safely to the response. This means that the header is not
71
- * 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
+ * ```
72
184
  */
73
185
  safeHeader(header: string, value: any): Response;
74
186
  /**
75
187
  * Remove some header from the response.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * response.removeHeader('content-type')
192
+ * ```
76
193
  */
77
194
  removeHeader(header: string): Response;
78
195
  /**
79
- * Redirect the response to other url. You can also set a different status code
80
- * 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
+ * ```
81
203
  */
82
204
  redirectTo(url: string, status?: number): Promise<Response>;
83
205
  /**
84
206
  * Apply helmet in response.
207
+ *
208
+ * @example
209
+ * ```ts
210
+ * return response
211
+ * .helmet({ enableCSPNonces: false })
212
+ * .view('profile', user)
213
+ * ```
85
214
  */
86
215
  helmet(options: FastifyHelmetOptions): Response;
87
216
  }
@@ -13,37 +13,87 @@ export class Response {
13
13
  this.request = request;
14
14
  }
15
15
  /**
16
- * 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
+ * ```
17
28
  */
18
29
  get sent() {
19
30
  return this.response.sent;
20
31
  }
21
32
  /**
22
- * 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
+ * ```
23
43
  */
24
44
  get body() {
25
45
  return this.response.body;
26
46
  }
27
47
  /**
28
- * 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
+ * ```
29
60
  */
30
61
  get statusCode() {
31
62
  return this.response.statusCode;
32
63
  }
33
64
  /**
34
- * Get the headers sent in response.
65
+ * Get the headers set in the response.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * const headers = response.headers
70
+ * ```
35
71
  */
36
72
  get headers() {
37
73
  return this.response.getHeaders();
38
74
  }
39
75
  /**
40
- * Get the time in MS of how much the request has taken to response.
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
+ * ```
41
86
  */
42
87
  get responseTime() {
43
88
  return this.response.elapsedTime;
44
89
  }
45
90
  /**
46
- * Terminated the request sending a view to be rendered.
91
+ * Terminate the request sending a view to be rendered.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * return response.view('welcome', { name: 'lenon' })
96
+ * ```
47
97
  */
48
98
  async view(view, data) {
49
99
  const content = await View.render(view, { ...data, request: this.request });
@@ -53,6 +103,11 @@ export class Response {
53
103
  }
54
104
  /**
55
105
  * Terminate the request sending the response body or not.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * return response.send({ name: 'lenon' })
110
+ * ```
56
111
  */
57
112
  async send(data) {
58
113
  await this.response.send(data);
@@ -60,18 +115,36 @@ export class Response {
60
115
  return this;
61
116
  }
62
117
  /**
63
- * Terminated the request sending a file.
118
+ * Terminate the request sending a file.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * return response.sendFile('img.png')
123
+ * ```
64
124
  */
65
125
  async sendFile(filename, filepath, options) {
66
126
  await this.response.sendFile(filename, filepath, options);
67
127
  return this;
68
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
+ */
69
137
  async download(filepath, filename, options) {
70
138
  await this.response.download(filename, filepath, options);
71
139
  return this;
72
140
  }
73
141
  /**
74
142
  * Set the response status code.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * return response.status(200).send()
147
+ * ```
75
148
  */
76
149
  status(code) {
77
150
  this.response.status(code);
@@ -79,6 +152,13 @@ export class Response {
79
152
  }
80
153
  /**
81
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
+ * ```
82
162
  */
83
163
  header(header, value) {
84
164
  this.response.header(header, value);
@@ -86,13 +166,25 @@ export class Response {
86
166
  }
87
167
  /**
88
168
  * Verify if response has some header.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * if (response.hasHeader('content-type')) {
173
+ * // do something
174
+ * }
175
+ * ```
89
176
  */
90
177
  hasHeader(header) {
91
178
  return this.response.hasHeader(header);
92
179
  }
93
180
  /**
94
- * Add some header safely to the response. This means that the header is not
95
- * 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
+ * ```
96
188
  */
97
189
  safeHeader(header, value) {
98
190
  this.response.header(header, value);
@@ -100,14 +192,24 @@ export class Response {
100
192
  }
101
193
  /**
102
194
  * Remove some header from the response.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * response.removeHeader('content-type')
199
+ * ```
103
200
  */
104
201
  removeHeader(header) {
105
202
  this.response.removeHeader(header);
106
203
  return this;
107
204
  }
108
205
  /**
109
- * Redirect the response to other url. You can also set a different status code
110
- * 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
+ * ```
111
213
  */
112
214
  async redirectTo(url, status) {
113
215
  if (status) {
@@ -119,6 +221,13 @@ export class Response {
119
221
  }
120
222
  /**
121
223
  * Apply helmet in response.
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * return response
228
+ * .helmet({ enableCSPNonces: false })
229
+ * .view('profile', user)
230
+ * ```
122
231
  */
123
232
  helmet(options) {
124
233
  this.response.helmet(options);
@@ -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
19
  if (!req.data) {
21
20
  req.data = {};
22
21
  }
22
+ const request = new Request(req);
23
23
  const response = new Response(res, request);
24
- await handler({
25
- request,
26
- response,
27
- data: req.data,
28
- body: req.body,
29
- params: req.params,
30
- queries: req.query,
31
- headers: req.headers
32
- });
24
+ return handler({ request, response, data: req.data });
33
25
  };
34
26
  }
35
27
  /**
@@ -43,10 +35,10 @@ export class FastifyHandler {
43
35
  */
44
36
  static intercept(handler) {
45
37
  return async (req, res, payload) => {
46
- const request = new Request(req);
47
38
  if (!req.data) {
48
39
  req.data = {};
49
40
  }
41
+ const request = new Request(req);
50
42
  const response = new Response(res, request);
51
43
  if (Is.Json(payload)) {
52
44
  payload = JSON.parse(payload);
@@ -56,11 +48,7 @@ export class FastifyHandler {
56
48
  request,
57
49
  response,
58
50
  status: response.statusCode,
59
- data: req.data,
60
- body: res.body,
61
- params: req.params,
62
- queries: req.query,
63
- headers: req.headers
51
+ data: req.data
64
52
  });
65
53
  res.body = payload;
66
54
  if (Is.Object(payload)) {
@@ -74,19 +62,15 @@ export class FastifyHandler {
74
62
  */
75
63
  static terminate(handler) {
76
64
  return async (req, res) => {
77
- const request = new Request(req);
78
65
  if (!req.data) {
79
66
  req.data = {};
80
67
  }
68
+ const request = new Request(req);
81
69
  const response = new Response(res, request);
82
70
  await handler({
83
71
  request,
84
72
  response,
85
- params: req.params,
86
- queries: req.query,
87
73
  data: req.data,
88
- body: res.body || req.body,
89
- headers: res.getHeaders(),
90
74
  status: res.statusCode,
91
75
  responseTime: res.elapsedTime
92
76
  });
@@ -97,19 +81,15 @@ export class FastifyHandler {
97
81
  */
98
82
  static error(handler) {
99
83
  return async (error, req, res) => {
100
- const request = new Request(req);
101
84
  if (!req.data) {
102
85
  req.data = {};
103
86
  }
87
+ const request = new Request(req);
104
88
  const response = new Response(res, request);
105
89
  await handler({
106
90
  request,
107
91
  response,
108
92
  data: req.data,
109
- body: res.body || req.body,
110
- params: req.params,
111
- queries: req.query,
112
- headers: req.headers,
113
93
  error
114
94
  });
115
95
  };
@@ -13,7 +13,7 @@ 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');
@@ -151,17 +151,22 @@ export class ServerImpl {
151
151
  });
152
152
  return;
153
153
  }
154
- this.fastify.route({
154
+ const { middlewares, interceptors, terminators } = options.middlewares;
155
+ const route = {
155
156
  url: options.url,
156
157
  method: options.methods,
157
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
158
- // @ts-ignore
159
- handler: FastifyHandler.request(options.handler),
160
- preHandler: options.middlewares.middlewares.map(m => FastifyHandler.handle(m)),
161
- onSend: options.middlewares.interceptors.map(m => FastifyHandler.intercept(m)),
162
- onResponse: options.middlewares.terminators.map(m => FastifyHandler.terminate(m)),
163
- ...options.fastify
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.
@@ -12,9 +12,5 @@ export type Context = {
12
12
  request: Request;
13
13
  response: Response;
14
14
  data: any;
15
- body: any;
16
- params: any;
17
- queries: any;
18
- headers: any;
19
15
  };
20
16
  export type RequestHandler = (ctx: Context) => any | Promise<any>;
@@ -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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
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>;
@@ -6,5 +6,4 @@
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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
9
+ export {};
@@ -6,15 +6,7 @@
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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
11
- export type InterceptContext = {
12
- request: Request;
13
- response: Response;
14
- data: any;
15
- body: any;
16
- params: any;
17
- queries: any;
18
- headers: any;
9
+ import type { Context } from '#src/types/contexts/Context';
10
+ export type InterceptContext = Context & {
19
11
  status: number;
20
12
  };
@@ -6,5 +6,4 @@
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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
9
+ export {};
@@ -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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
11
- export type TerminateContext = {
12
- request: Request;
13
- response: Response;
14
- data: any;
15
- body: any;
16
- params: any;
17
- queries: any;
18
- headers: any;
9
+ import type { Context } from '#src/types/contexts/Context';
10
+ export type TerminateContext = Context & {
19
11
  status: number;
20
12
  responseTime: number;
21
13
  };
@@ -6,5 +6,4 @@
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 { Request } from '#src/context/Request';
10
- import { Response } from '#src/context/Response';
9
+ export {};
@@ -14,8 +14,8 @@ export class {{ namePascal }} {
14
14
  return response.status(200).send({})
15
15
  }
16
16
 
17
- public async update({ response, params }: Context) {
18
- return response.status(200).send({ id: params.id })
17
+ public async update({ request, response }: Context) {
18
+ return response.status(200).send({ id: request.param('id') })
19
19
  }
20
20
 
21
21
  public async delete({ response }: Context) {
@@ -4,6 +4,6 @@ import type { InterceptorContract, InterceptContext } from '@athenna/http'
4
4
  @Interceptor()
5
5
  export class {{ namePascal }} implements InterceptorContract {
6
6
  public async intercept(ctx: InterceptContext): Promise<unknown> {
7
- return ctx.body
7
+ return ctx.response.body
8
8
  }
9
9
  }