@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.
@@ -7,82 +7,319 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import { Is, Json } from '@athenna/common';
10
- export function request(req) {
11
- const request = {
12
- request: req,
13
- id: req.id,
14
- ip: req.ip,
15
- hostname: req.hostname,
16
- get port() {
17
- return request.getAddressInfo().port;
18
- },
19
- version: req.raw.httpVersion,
20
- protocol: req.protocol,
21
- method: req.method,
22
- baseUrl: req.url.split('?')[0],
23
- get baseHostUrl() {
24
- return request.getHostUrlFor(request.baseUrl);
25
- },
26
- routeUrl: req.routeOptions.url,
27
- get routeHostUrl() {
28
- return request.getHostUrlFor(request.routeUrl);
29
- },
30
- originalUrl: req.url,
31
- get originalHostUrl() {
32
- return request.getHostUrlFor(request.originalUrl);
33
- },
34
- body: req.body || {},
35
- params: req.params || {},
36
- queries: req.query || {},
37
- headers: req.headers || {},
38
- param(param, defaultValue) {
39
- return Json.get(request.params, param, defaultValue);
40
- },
41
- query(query, defaultValue) {
42
- return Json.get(request.queries, query, defaultValue);
43
- },
44
- header(header, defaultValue) {
45
- return Json.get(request.headers, header, defaultValue);
46
- },
47
- input(key, defaultValue) {
48
- return request.payload(key, defaultValue);
49
- },
50
- payload(key, defaultValue) {
51
- return Json.get(request.body, key, defaultValue);
52
- },
53
- only(keys) {
54
- const body = {};
55
- Object.keys(request.body).forEach(key => {
56
- if (!keys.includes(key)) {
57
- return;
58
- }
59
- body[key] = request.body[key];
60
- });
61
- return body;
62
- },
63
- except(keys) {
64
- const body = {};
65
- Object.keys(request.body).forEach(key => {
66
- if (keys.includes(key)) {
67
- return;
68
- }
69
- body[key] = request.body[key];
70
- });
71
- return body;
72
- },
73
- getHostUrlFor(url) {
74
- let { address, port } = request.getAddressInfo();
75
- if (address === '::1') {
76
- address = '127.0.0.1';
10
+ export class Request {
11
+ constructor(request) {
12
+ this.request = request;
13
+ }
14
+ /**
15
+ * Get the request id.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * console.log(request.id) // '12345'
20
+ * ```
21
+ */
22
+ get id() {
23
+ return this.request.id;
24
+ }
25
+ /**
26
+ * Get the request ip.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * console.log(request.ip) // '192.168.0.1'
31
+ * ```
32
+ */
33
+ get ip() {
34
+ return this.request.ip;
35
+ }
36
+ /**
37
+ * Get the request hostname.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * console.log(request.hostname) // 'localhost'
42
+ * ```
43
+ */
44
+ get hostname() {
45
+ return this.request.hostname;
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
+ }
69
+ /**
70
+ * Get the request protocol.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * console.log(request.protocol) // 'http'
75
+ * ```
76
+ */
77
+ get protocol() {
78
+ return this.request.protocol;
79
+ }
80
+ /**
81
+ * Get the request method.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * console.log(request.method) // 'GET'
86
+ * ```
87
+ */
88
+ get method() {
89
+ return this.request.method;
90
+ }
91
+ /**
92
+ * Get the base url from request.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * console.log(request.baseUrl) // '/users/1'
97
+ * ```
98
+ */
99
+ get baseUrl() {
100
+ return this.request.url.split('?')[0];
101
+ }
102
+ /**
103
+ * Get the base url with host and port info from request.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * console.log(request.baseHostUrl) // 'http://localhost:3030/users/1'
108
+ * ```
109
+ */
110
+ get baseHostUrl() {
111
+ return this.getHostUrlFor(this.baseUrl);
112
+ }
113
+ /**
114
+ * Get the route url from request.
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * console.log(request.routeUrl) // '/users/:id'
119
+ * ```
120
+ */
121
+ get routeUrl() {
122
+ return this.request.routeOptions.url;
123
+ }
124
+ /**
125
+ * Get the route url with host and port info from request.
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * console.log(request.routeHostUrl) // 'http://localhost:3030/users/:id'
130
+ * ```
131
+ */
132
+ get routeHostUrl() {
133
+ return this.getHostUrlFor(this.routeUrl);
134
+ }
135
+ /**
136
+ * Get the original url from request.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * console.log(request.originalUrl) // '/users/1?query=true'
141
+ * ```
142
+ */
143
+ get originalUrl() {
144
+ return this.request.url;
145
+ }
146
+ /**
147
+ * Get the original url with host and port info from request.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * console.log(request.originalHostUrl) // 'http://localhost:3000/users/1?query=true'
152
+ * ```
153
+ */
154
+ get originalHostUrl() {
155
+ return this.getHostUrlFor(this.originalUrl);
156
+ }
157
+ /**
158
+ * Get all body from request.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const { name, email } = request.body
163
+ * ```
164
+ */
165
+ get body() {
166
+ return this.request.body || {};
167
+ }
168
+ /**
169
+ * Get all params from request.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * const { id } = request.params
174
+ * ```
175
+ */
176
+ get params() {
177
+ return this.request.params || {};
178
+ }
179
+ /**
180
+ * Get all queries from request.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const { page, limit } = request.queries
185
+ * ```
186
+ */
187
+ get queries() {
188
+ return this.request.query || {};
189
+ }
190
+ /**
191
+ * Get all headers from request.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * const { accept } = request.headers
196
+ * ```
197
+ */
198
+ get headers() {
199
+ return this.request.headers || {};
200
+ }
201
+ /**
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
+ * ```
209
+ */
210
+ param(param, defaultValue) {
211
+ return Json.get(this.params, param, defaultValue);
212
+ }
213
+ /**
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
+ * ```
221
+ */
222
+ query(query, defaultValue) {
223
+ return Json.get(this.queries, query, defaultValue);
224
+ }
225
+ /**
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
+ * ```
233
+ */
234
+ header(header, defaultValue) {
235
+ return Json.get(this.headers, header, defaultValue);
236
+ }
237
+ /**
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
+ * ```
245
+ */
246
+ input(key, defaultValue) {
247
+ return this.payload(key, defaultValue);
248
+ }
249
+ /**
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
+ * ```
257
+ */
258
+ payload(key, defaultValue) {
259
+ return Json.get(this.body, key, defaultValue);
260
+ }
261
+ /**
262
+ * Get only the selected values from the request body.
263
+ *
264
+ * @example
265
+ * ```ts
266
+ * const body = request.only(['name', 'email'])
267
+ * ```
268
+ */
269
+ only(keys) {
270
+ const body = {};
271
+ Object.keys(this.body).forEach(key => {
272
+ if (!keys.includes(key)) {
273
+ return;
77
274
  }
78
- if (!Is.Ip(address) && address !== 'localhost') {
79
- return `${request.protocol}://${address}${url}`;
275
+ body[key] = this.body[key];
276
+ });
277
+ return body;
278
+ }
279
+ /**
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
+ * ```
287
+ */
288
+ except(keys) {
289
+ const body = {};
290
+ Object.keys(this.body).forEach(key => {
291
+ if (keys.includes(key)) {
292
+ return;
80
293
  }
81
- return `${request.protocol}://${address}:${port}${url}`;
82
- },
83
- getAddressInfo() {
84
- return req.server.server.address();
294
+ body[key] = this.body[key];
295
+ });
296
+ return body;
297
+ }
298
+ /**
299
+ * Get the original fastify request.
300
+ */
301
+ getFastifyRequest() {
302
+ return this.request;
303
+ }
304
+ /**
305
+ * Add the hostname and port to the url.
306
+ */
307
+ getHostUrlFor(url) {
308
+ let { address, port } = this.getAddressInfo();
309
+ if (address === '::1') {
310
+ address = '127.0.0.1';
85
311
  }
86
- };
87
- return request;
312
+ if (!Is.Ip(address) && address !== 'localhost') {
313
+ return `${this.protocol}://${address}${url}`;
314
+ }
315
+ return `${this.protocol}://${address}:${port}${url}`;
316
+ }
317
+ /**
318
+ * Get the address info of the server. This method will return the
319
+ * port used to listen the server, the family (IPv4, IPv6) and the
320
+ * server address (127.0.0.1).
321
+ */
322
+ getAddressInfo() {
323
+ return this.request.server.server.address();
324
+ }
88
325
  }
@@ -7,8 +7,213 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import type { FastifyReply } from 'fastify';
10
- import type { Request, Response } from '#src/types';
11
- /**
12
- * Create the Athenna response object
13
- */
14
- export declare function response(reply: FastifyReply, request?: Request): Response;
10
+ import type { SendOptions } from '@fastify/static';
11
+ import type { FastifyHelmetOptions } from '@fastify/helmet';
12
+ export declare class Response {
13
+ /**
14
+ * The fastify response object.
15
+ */
16
+ private response;
17
+ /**
18
+ * The request object from request context.
19
+ */
20
+ private request;
21
+ constructor(response: FastifyReply, request?: Request);
22
+ /**
23
+ * Verify if the response has been already sent. Keep
24
+ * in mind that this method will only return `true`
25
+ * after `response.send()`, `response.view()`,
26
+ * `response.sendFile()` or `response.download()` methods
27
+ * call.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * if (response.sent) {
32
+ * // do something
33
+ * }
34
+ * ```
35
+ */
36
+ get sent(): boolean;
37
+ /**
38
+ * Get the response body sent in response. Keep
39
+ * in mind that this method will only return `true`
40
+ * after `response.send()`, `response.view()`,
41
+ * `response.sendFile()` or `response.download()` methods
42
+ * call.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const { createdAt, updatedAt } = response.body
47
+ * ```
48
+ */
49
+ get body(): any | any[];
50
+ /**
51
+ * Get the status code sent in response. Keep
52
+ * in mind that this method will only return `true`
53
+ * after `response.send()`, `response.view()`,
54
+ * `response.sendFile()` or `response.download()` methods
55
+ * call.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * if (response.statusCode !== 200) {
60
+ * // do something
61
+ * }
62
+ * ```
63
+ */
64
+ get statusCode(): number;
65
+ /**
66
+ * Get the headers set in the response.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * const headers = response.headers
71
+ * ```
72
+ */
73
+ get headers(): any;
74
+ /**
75
+ * Get the time in MS of how much the request has
76
+ * taken to response. Keep in mind that this method
77
+ * will only return `true` after `response.send()`,
78
+ * `response.view()`, `response.sendFile()` or
79
+ * `response.download()` methods call.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * console.log(response.responseTime) // 1000
84
+ * ```
85
+ */
86
+ get responseTime(): number;
87
+ /**
88
+ * Terminate the request sending a view to be rendered.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * return response.view('welcome', { name: 'lenon' })
93
+ * ```
94
+ */
95
+ view(view: string, data?: any): Promise<Response>;
96
+ /**
97
+ * Terminate the request sending the response body or not.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * return response.send({ name: 'lenon' })
102
+ * ```
103
+ */
104
+ send(data?: any): Promise<Response>;
105
+ /**
106
+ * @example
107
+ * ```ts
108
+ * return response.sendFile('img.png')
109
+ * ```
110
+ */
111
+ sendFile(filename: string, filepath?: string): Promise<Response>;
112
+ /**
113
+ * @example
114
+ * ```ts
115
+ * return response.sendFile('img.png', { cacheControl: false })
116
+ * ```
117
+ */
118
+ sendFile(filename: string, options?: string | SendOptions): Promise<Response>;
119
+ /**
120
+ * @example
121
+ * ```ts
122
+ * return response.sendFile('img.png', Path.tmp(), {
123
+ * cacheControl: false
124
+ * })
125
+ * ```
126
+ */
127
+ sendFile(filename: string, filepath?: string, options?: SendOptions): Promise<Response>;
128
+ /**
129
+ * @example
130
+ * ```ts
131
+ * return response.download('img.png', 'custom-img.png')
132
+ * ```
133
+ */
134
+ download(filepath: string, filename: string): Promise<Response>;
135
+ /**
136
+ * @example
137
+ * ```ts
138
+ * return response.download('img.png', 'custom-img.png', {
139
+ * cacheControl: false
140
+ * })
141
+ * ```
142
+ */
143
+ download(filepath: string, filename: string, options?: SendOptions): Promise<Response>;
144
+ /**
145
+ * Set the response status code.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * return response.status(200).send()
150
+ * ```
151
+ */
152
+ status(code: number): Response;
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: string, value: any): Response;
164
+ /**
165
+ * Verify if response has some header.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * if (response.hasHeader('content-type')) {
170
+ * // do something
171
+ * }
172
+ * ```
173
+ */
174
+ hasHeader(header: string): boolean;
175
+ /**
176
+ * Add some header safely to the response. This means that
177
+ * the header is not going to be added if is already set.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * response.safeHeader('content-type', 'application/json')
182
+ * ```
183
+ */
184
+ safeHeader(header: string, value: any): Response;
185
+ /**
186
+ * Remove some header from the response.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * response.removeHeader('content-type')
191
+ * ```
192
+ */
193
+ removeHeader(header: string): Response;
194
+ /**
195
+ * Redirect the response to other url. You can also set a
196
+ * different status code for the redirect.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * return response.redirect('users', 304)
201
+ * ```
202
+ */
203
+ redirectTo(url: string, status?: number): Promise<Response>;
204
+ /**
205
+ * Apply helmet in response.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * return response
210
+ * .helmet({ enableCSPNonces: false })
211
+ * .view('profile', user)
212
+ * ```
213
+ */
214
+ helmet(options: FastifyHelmetOptions): Response;
215
+ /**
216
+ * Get the original fastify response.
217
+ */
218
+ getFastifyResponse(): FastifyReply;
219
+ }