@athenna/http 1.7.7 → 1.8.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 +12 -9
- package/src/Context/Response.js +22 -0
- package/src/Handlers/FastifyHandler.js +12 -12
- package/src/Handlers/HttpExceptionHandler.js +5 -5
- package/src/Kernels/HttpKernel.js +28 -6
- package/src/Router/Route.js +183 -1
- package/src/Router/RouteGroup.js +30 -2
- package/src/Router/RouteResource.js +59 -5
- package/src/Router/Router.js +15 -0
- package/src/index.d.ts +381 -27
- package/src/index.js +60 -31
- package/templates/middleware.edge +5 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@athenna/http",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.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>",
|
|
@@ -54,14 +54,17 @@
|
|
|
54
54
|
"#tests/*": "./tests/*.js"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@athenna/artisan": "1.5.
|
|
58
|
-
"@athenna/
|
|
59
|
-
"@athenna/
|
|
60
|
-
"@athenna/
|
|
61
|
-
"@athenna/
|
|
62
|
-
"fastify": "
|
|
63
|
-
"fastify
|
|
64
|
-
"fastify
|
|
57
|
+
"@athenna/artisan": "1.5.9",
|
|
58
|
+
"@athenna/common": "1.0.1",
|
|
59
|
+
"@athenna/config": "1.2.0",
|
|
60
|
+
"@athenna/ioc": "1.2.9",
|
|
61
|
+
"@athenna/logger": "1.3.7",
|
|
62
|
+
"@fastify/cors": "8.1.1",
|
|
63
|
+
"@fastify/helmet": "10.0.2",
|
|
64
|
+
"@fastify/rate-limit": "7.5.0",
|
|
65
|
+
"@fastify/swagger": "8.1.0",
|
|
66
|
+
"@fastify/swagger-ui": "1.1.0",
|
|
67
|
+
"fastify": "4.9.2"
|
|
65
68
|
},
|
|
66
69
|
"devDependencies": {
|
|
67
70
|
"@japa/assert": "1.3.4",
|
package/src/Context/Response.js
CHANGED
|
@@ -35,6 +35,28 @@ export class Response {
|
|
|
35
35
|
this.#response.send(data)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Terminate the request sending the response body.
|
|
40
|
+
*
|
|
41
|
+
* @param {any} [data]
|
|
42
|
+
* @return {void}
|
|
43
|
+
*/
|
|
44
|
+
json(data) {
|
|
45
|
+
this.#response.send(data)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Apply helmet in response.
|
|
50
|
+
*
|
|
51
|
+
* @param {import('@fastify/helmet').FastifyHelmetOptions} [options]
|
|
52
|
+
* @return {void}
|
|
53
|
+
*/
|
|
54
|
+
async helmet(options) {
|
|
55
|
+
await this.#response.helmet(options)
|
|
56
|
+
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
/**
|
|
39
61
|
* Set the response status code.
|
|
40
62
|
*
|
|
@@ -25,25 +25,27 @@ export class FastifyHandler {
|
|
|
25
25
|
|
|
26
26
|
if (!req.data) req.data = {}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const isJson = Is.Json(payload)
|
|
29
29
|
|
|
30
|
-
if (
|
|
31
|
-
|
|
30
|
+
if (isJson) {
|
|
31
|
+
payload = JSON.parse(payload)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
payload = await handler({
|
|
35
35
|
request,
|
|
36
36
|
response,
|
|
37
|
-
body,
|
|
37
|
+
body: payload,
|
|
38
38
|
status: res.statusCode,
|
|
39
39
|
params: req.params,
|
|
40
40
|
queries: req.query,
|
|
41
41
|
data: req.data,
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
if (
|
|
44
|
+
if (isJson) {
|
|
45
|
+
payload = JSON.stringify(payload)
|
|
46
|
+
}
|
|
45
47
|
|
|
46
|
-
return
|
|
48
|
+
return payload
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -54,7 +56,7 @@ export class FastifyHandler {
|
|
|
54
56
|
* @return {any}
|
|
55
57
|
*/
|
|
56
58
|
static createDoneHandler(handler) {
|
|
57
|
-
return (req, res
|
|
59
|
+
return async (req, res) => {
|
|
58
60
|
const request = new Request(req)
|
|
59
61
|
const response = new Response(res)
|
|
60
62
|
|
|
@@ -66,7 +68,6 @@ export class FastifyHandler {
|
|
|
66
68
|
params: req.params,
|
|
67
69
|
queries: req.query,
|
|
68
70
|
data: req.data,
|
|
69
|
-
next: done,
|
|
70
71
|
})
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -78,7 +79,7 @@ export class FastifyHandler {
|
|
|
78
79
|
* @return {any}
|
|
79
80
|
*/
|
|
80
81
|
static createOnResponseHandler(handler) {
|
|
81
|
-
return (req, res
|
|
82
|
+
return async (req, res) => {
|
|
82
83
|
const request = new Request(req)
|
|
83
84
|
const response = new Response(res)
|
|
84
85
|
|
|
@@ -94,7 +95,6 @@ export class FastifyHandler {
|
|
|
94
95
|
headers: res.getHeaders(),
|
|
95
96
|
status: res.statusCode,
|
|
96
97
|
responseTime: res.getResponseTime(),
|
|
97
|
-
next: done,
|
|
98
98
|
})
|
|
99
99
|
}
|
|
100
100
|
}
|
|
@@ -106,7 +106,7 @@ export class FastifyHandler {
|
|
|
106
106
|
* @return {any}
|
|
107
107
|
*/
|
|
108
108
|
static createErrorHandler(handler) {
|
|
109
|
-
return (error, req, res) => {
|
|
109
|
+
return async (error, req, res) => {
|
|
110
110
|
const request = new Request(req)
|
|
111
111
|
const response = new Response(res)
|
|
112
112
|
|
|
@@ -52,7 +52,7 @@ export class HttpExceptionHandler {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
const isInternalServerError = statusCode === 500
|
|
55
|
-
const isDebugMode = Config.get('app.debug')
|
|
55
|
+
const isDebugMode = Config.get('app.debug', false)
|
|
56
56
|
|
|
57
57
|
if (isInternalServerError && !isDebugMode) {
|
|
58
58
|
body.name = 'Internal server error'
|
|
@@ -61,15 +61,15 @@ export class HttpExceptionHandler {
|
|
|
61
61
|
delete body.stack
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
response.status(statusCode).send(body)
|
|
65
|
+
|
|
64
66
|
if (
|
|
65
67
|
this.ignoreCodes.includes(code) ||
|
|
66
68
|
this.ignoreStatuses.includes(statusCode)
|
|
67
69
|
) {
|
|
68
|
-
return
|
|
70
|
+
return
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
response.status(statusCode).send(body)
|
|
72
|
-
|
|
73
73
|
if (error.prettify) {
|
|
74
74
|
const prettyError = await error.prettify()
|
|
75
75
|
|
|
@@ -80,7 +80,7 @@ export class HttpExceptionHandler {
|
|
|
80
80
|
|
|
81
81
|
const exception = new Exception(body.message, body.statusCode, body.code)
|
|
82
82
|
|
|
83
|
-
exception.stack =
|
|
83
|
+
exception.stack = error.stack
|
|
84
84
|
|
|
85
85
|
const prettyError = await exception.prettify()
|
|
86
86
|
|
|
@@ -97,7 +97,33 @@ export class HttpKernel {
|
|
|
97
97
|
return
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
Server.registerCors(Config.get('http.cors'))
|
|
100
|
+
await Server.registerCors(Config.get('http.cors'))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Register helmet plugin.
|
|
105
|
+
*
|
|
106
|
+
* @return {Promise<void>}
|
|
107
|
+
*/
|
|
108
|
+
async registerHelmet() {
|
|
109
|
+
if (Config.get('http.noHelmet')) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
await Server.registerHelmet(Config.get('http.helmet'))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Register swagger plugin.
|
|
118
|
+
*
|
|
119
|
+
* @return {Promise<void>}
|
|
120
|
+
*/
|
|
121
|
+
async registerSwagger() {
|
|
122
|
+
if (Config.get('http.noSwagger')) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
await Server.registerSwagger(Config.get('http.swagger'))
|
|
101
127
|
}
|
|
102
128
|
|
|
103
129
|
/**
|
|
@@ -110,7 +136,7 @@ export class HttpKernel {
|
|
|
110
136
|
return
|
|
111
137
|
}
|
|
112
138
|
|
|
113
|
-
Server.registerRateLimit(Config.get('http.rateLimit'))
|
|
139
|
+
await Server.registerRateLimit(Config.get('http.rateLimit'))
|
|
114
140
|
}
|
|
115
141
|
|
|
116
142
|
/**
|
|
@@ -142,8 +168,6 @@ export class HttpKernel {
|
|
|
142
168
|
|
|
143
169
|
Server.use(async ctx => {
|
|
144
170
|
await Log.channel('request').info(ctx)
|
|
145
|
-
|
|
146
|
-
return ctx.next()
|
|
147
171
|
}, 'terminate')
|
|
148
172
|
}
|
|
149
173
|
|
|
@@ -159,8 +183,6 @@ export class HttpKernel {
|
|
|
159
183
|
|
|
160
184
|
Server.use(async ctx => {
|
|
161
185
|
ctx.data.requestId = Uuid.generate('ath')
|
|
162
|
-
|
|
163
|
-
return ctx.next()
|
|
164
186
|
}, 'handle')
|
|
165
187
|
}
|
|
166
188
|
}
|
package/src/Router/Route.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* file that was distributed with this source code.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { Is } from '@athenna/common'
|
|
10
|
+
import { Is, Options, Route as RouteHelper } from '@athenna/common'
|
|
11
11
|
import { removeSlashes } from '#src/Utils/removeSlashes'
|
|
12
12
|
import { isMiddlewareContract } from '#src/Utils/isMiddlewareContract'
|
|
13
13
|
import { UndefinedMethodException } from '#src/Exceptions/UndefinedMethodException'
|
|
@@ -62,6 +62,20 @@ export class Route {
|
|
|
62
62
|
*/
|
|
63
63
|
#prefixes
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Helmet options of this route.
|
|
67
|
+
*
|
|
68
|
+
* @type {any}
|
|
69
|
+
*/
|
|
70
|
+
#helmetOptions
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Swagger options of this route.
|
|
74
|
+
*
|
|
75
|
+
* @type {any}
|
|
76
|
+
*/
|
|
77
|
+
#swaggerOptions
|
|
78
|
+
|
|
65
79
|
/**
|
|
66
80
|
* Creates a new instance of Route.
|
|
67
81
|
*
|
|
@@ -79,6 +93,11 @@ export class Route {
|
|
|
79
93
|
this.#handler = handler
|
|
80
94
|
this.#routeMiddlewares = { handlers: [], terminators: [], interceptors: [] }
|
|
81
95
|
|
|
96
|
+
this.#helmetOptions = {}
|
|
97
|
+
this.#swaggerOptions = {}
|
|
98
|
+
|
|
99
|
+
RouteHelper.getParamsName(url).forEach(param => this.param(param))
|
|
100
|
+
|
|
82
101
|
if (name) {
|
|
83
102
|
this.name = name
|
|
84
103
|
}
|
|
@@ -164,11 +183,174 @@ export class Route {
|
|
|
164
183
|
return this
|
|
165
184
|
}
|
|
166
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Set up all helmet options for route.
|
|
188
|
+
*
|
|
189
|
+
* @param {any} options
|
|
190
|
+
* @param {boolean} [override]
|
|
191
|
+
* @return {Route}
|
|
192
|
+
*/
|
|
193
|
+
helmet(options, override = true) {
|
|
194
|
+
if (!override) {
|
|
195
|
+
this.#helmetOptions = Options.create(this.#helmetOptions, options)
|
|
196
|
+
|
|
197
|
+
return this
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this.#helmetOptions = options
|
|
201
|
+
|
|
202
|
+
return this
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Set up all swagger options for route.
|
|
207
|
+
*
|
|
208
|
+
* @param {any} options
|
|
209
|
+
* @param {boolean} [override]
|
|
210
|
+
* @return {Route}
|
|
211
|
+
*/
|
|
212
|
+
swagger(options, override = true) {
|
|
213
|
+
if (!override) {
|
|
214
|
+
this.#swaggerOptions = Options.create(this.#swaggerOptions, options)
|
|
215
|
+
|
|
216
|
+
return this
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
this.#swaggerOptions = options
|
|
220
|
+
|
|
221
|
+
return this
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Set a summary for the route swagger docs.
|
|
226
|
+
*
|
|
227
|
+
* @param {string} summary
|
|
228
|
+
* @return {Route}
|
|
229
|
+
*/
|
|
230
|
+
summary(summary) {
|
|
231
|
+
this.#swaggerOptions.summary = summary
|
|
232
|
+
|
|
233
|
+
return this
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Set a description for the route swagger docs.
|
|
238
|
+
*
|
|
239
|
+
* @param {string} description
|
|
240
|
+
* @return {Route}
|
|
241
|
+
*/
|
|
242
|
+
description(description) {
|
|
243
|
+
this.#swaggerOptions.description = description
|
|
244
|
+
|
|
245
|
+
return this
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Set tags for the route swagger docs.
|
|
250
|
+
*
|
|
251
|
+
* @param {string} tags
|
|
252
|
+
* @return {Route}
|
|
253
|
+
*/
|
|
254
|
+
tags(...tags) {
|
|
255
|
+
if (!this.#swaggerOptions.tags) {
|
|
256
|
+
this.#swaggerOptions.tags = []
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
tags.forEach(tag => this.#swaggerOptions.tags.push(tag))
|
|
260
|
+
|
|
261
|
+
return this
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Set body param for the route swagger docs.
|
|
266
|
+
*
|
|
267
|
+
* @param {string} name
|
|
268
|
+
* @param {string} [type]
|
|
269
|
+
* @param {string} [description]
|
|
270
|
+
* @return {Route}
|
|
271
|
+
*/
|
|
272
|
+
body(name, type = 'string', description = '') {
|
|
273
|
+
if (!this.#swaggerOptions.body) {
|
|
274
|
+
this.#swaggerOptions.body = {}
|
|
275
|
+
this.#swaggerOptions.body.type = 'object'
|
|
276
|
+
this.#swaggerOptions.body.properties = {}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this.#swaggerOptions.body.properties[name] = { type, description }
|
|
280
|
+
|
|
281
|
+
return this
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Set param for the route swagger docs.
|
|
286
|
+
*
|
|
287
|
+
* @param {string} name
|
|
288
|
+
* @param {string} [type]
|
|
289
|
+
* @param {string} [description]
|
|
290
|
+
* @return {Route}
|
|
291
|
+
*/
|
|
292
|
+
param(name, type = 'string', description = '') {
|
|
293
|
+
if (!this.#swaggerOptions.params) {
|
|
294
|
+
this.#swaggerOptions.params = {}
|
|
295
|
+
this.#swaggerOptions.params.type = 'object'
|
|
296
|
+
this.#swaggerOptions.params.properties = {}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
this.#swaggerOptions.params.properties[name] = { type, description }
|
|
300
|
+
|
|
301
|
+
return this
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Set query string for the route swagger docs.
|
|
306
|
+
*
|
|
307
|
+
* @param {string} name
|
|
308
|
+
* @param {string} [type]
|
|
309
|
+
* @param {string} [description]
|
|
310
|
+
* @return {Route}
|
|
311
|
+
*/
|
|
312
|
+
queryString(name, type = 'string', description = '') {
|
|
313
|
+
if (!this.#swaggerOptions.queryString) {
|
|
314
|
+
this.#swaggerOptions.querystring = {}
|
|
315
|
+
this.#swaggerOptions.querystring.type = 'object'
|
|
316
|
+
this.#swaggerOptions.querystring.properties = {}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
this.#swaggerOptions.querystring.properties[name] = { type, description }
|
|
320
|
+
|
|
321
|
+
return this
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Set response for the route swagger docs.
|
|
326
|
+
*
|
|
327
|
+
* @param {number|any} statusCode
|
|
328
|
+
* @param {any} [response]
|
|
329
|
+
* @return {Route}
|
|
330
|
+
*/
|
|
331
|
+
response(statusCode, response) {
|
|
332
|
+
if (!this.#swaggerOptions.response) {
|
|
333
|
+
this.#swaggerOptions.response = {}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (!response) {
|
|
337
|
+
this.#swaggerOptions.response.default = response
|
|
338
|
+
|
|
339
|
+
return this
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
this.#swaggerOptions.response[statusCode] = response
|
|
343
|
+
|
|
344
|
+
return this
|
|
345
|
+
}
|
|
346
|
+
|
|
167
347
|
toJSON() {
|
|
168
348
|
const json = {
|
|
169
349
|
url: this.#getUrl(),
|
|
170
350
|
methods: this.#methods,
|
|
171
351
|
middlewares: this.#routeMiddlewares,
|
|
352
|
+
helmetOptions: this.#helmetOptions,
|
|
353
|
+
swaggerOptions: this.#swaggerOptions,
|
|
172
354
|
}
|
|
173
355
|
|
|
174
356
|
if (Is.String(this.#handler)) {
|
package/src/Router/RouteGroup.js
CHANGED
|
@@ -13,14 +13,14 @@ export class RouteGroup {
|
|
|
13
13
|
/**
|
|
14
14
|
* All routes registered in the group.
|
|
15
15
|
*
|
|
16
|
-
* @type {(
|
|
16
|
+
* @type {(Route | RouteResource | RouteGroup)[]}
|
|
17
17
|
*/
|
|
18
18
|
routes
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Creates a new instance of RouteGroup.
|
|
22
22
|
*
|
|
23
|
-
* @param {(
|
|
23
|
+
* @param {(Route | RouteResource | RouteGroup)[]} routes
|
|
24
24
|
*/
|
|
25
25
|
constructor(routes) {
|
|
26
26
|
this.routes = routes
|
|
@@ -54,6 +54,34 @@ export class RouteGroup {
|
|
|
54
54
|
return this
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Set up helmet options for route group.
|
|
59
|
+
*
|
|
60
|
+
* @param {any} options
|
|
61
|
+
* @return {RouteGroup}
|
|
62
|
+
*/
|
|
63
|
+
helmet(options) {
|
|
64
|
+
this.routes.forEach(route => {
|
|
65
|
+
this.#invoke(route, 'helmet', [options, false])
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return this
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Set up swagger options for route group.
|
|
73
|
+
*
|
|
74
|
+
* @param {any} options
|
|
75
|
+
* @return {RouteGroup}
|
|
76
|
+
*/
|
|
77
|
+
swagger(options) {
|
|
78
|
+
this.routes.forEach(route => {
|
|
79
|
+
this.#invoke(route, 'swagger', [options, false])
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return this
|
|
83
|
+
}
|
|
84
|
+
|
|
57
85
|
/**
|
|
58
86
|
* Invoke a method from route.
|
|
59
87
|
*
|
|
@@ -76,10 +76,10 @@ export class RouteResource {
|
|
|
76
76
|
/**
|
|
77
77
|
* Register only the methods in the array.
|
|
78
78
|
*
|
|
79
|
-
* @param {string
|
|
79
|
+
* @param {string} names
|
|
80
80
|
* @return {RouteResource}
|
|
81
81
|
*/
|
|
82
|
-
only(names) {
|
|
82
|
+
only(...names) {
|
|
83
83
|
this.#filter(names, true).forEach(route => (route.deleted = true))
|
|
84
84
|
|
|
85
85
|
return this
|
|
@@ -88,22 +88,76 @@ export class RouteResource {
|
|
|
88
88
|
/**
|
|
89
89
|
* Register all methods except the methods in the array.
|
|
90
90
|
*
|
|
91
|
-
* @param {string
|
|
91
|
+
* @param {string} names
|
|
92
92
|
* @return {RouteResource}
|
|
93
93
|
*/
|
|
94
|
-
except(names) {
|
|
94
|
+
except(...names) {
|
|
95
95
|
this.#filter(names, false).forEach(route => (route.deleted = true))
|
|
96
96
|
|
|
97
97
|
return this
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Set up helmet options for route resource.
|
|
102
|
+
*
|
|
103
|
+
* @param {string|any} action
|
|
104
|
+
* @param {any} [options]
|
|
105
|
+
* @return {RouteResource}
|
|
106
|
+
*/
|
|
107
|
+
helmet(action, options) {
|
|
108
|
+
if (!options) {
|
|
109
|
+
this.routes.forEach(route => route.helmet(options))
|
|
110
|
+
|
|
111
|
+
return this
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const resourceName = `${this.#resourceName}.${action}`
|
|
115
|
+
|
|
116
|
+
this.routes.forEach(route => {
|
|
117
|
+
if (route.name !== resourceName) {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
route.helmet(options)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
return this
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Set up swagger options for route resource method.
|
|
129
|
+
*
|
|
130
|
+
* @param {string|any} action
|
|
131
|
+
* @param {any} [options]
|
|
132
|
+
* @return {RouteResource}
|
|
133
|
+
*/
|
|
134
|
+
swagger(action, options) {
|
|
135
|
+
if (!options) {
|
|
136
|
+
this.routes.forEach(route => route.swagger(options))
|
|
137
|
+
|
|
138
|
+
return this
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const resourceName = `${this.#resourceName}.${action}`
|
|
142
|
+
|
|
143
|
+
this.routes.forEach(route => {
|
|
144
|
+
if (route.name !== resourceName) {
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
route.swagger(options)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
return this
|
|
152
|
+
}
|
|
153
|
+
|
|
100
154
|
/**
|
|
101
155
|
* Create the route.
|
|
102
156
|
*
|
|
103
157
|
* @param {string} url
|
|
104
158
|
* @param {string[]} methods
|
|
105
159
|
* @param {string} action
|
|
106
|
-
* return {void}
|
|
160
|
+
* @return {void}
|
|
107
161
|
*/
|
|
108
162
|
#makeRoute(url, methods, action) {
|
|
109
163
|
let handler = ''
|
package/src/Router/Router.js
CHANGED
|
@@ -91,6 +91,17 @@ export class Router {
|
|
|
91
91
|
return route
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Register a new vanila route using fastify options
|
|
96
|
+
* directly.
|
|
97
|
+
*
|
|
98
|
+
* @param {import('fastify').RouteOptions} options
|
|
99
|
+
* @return {void}
|
|
100
|
+
*/
|
|
101
|
+
vanilaRoute(options) {
|
|
102
|
+
Server.getFastify().route(options)
|
|
103
|
+
}
|
|
104
|
+
|
|
94
105
|
/**
|
|
95
106
|
* Creates a new route group.
|
|
96
107
|
*
|
|
@@ -256,6 +267,10 @@ export class Router {
|
|
|
256
267
|
route.url,
|
|
257
268
|
route.handler,
|
|
258
269
|
route.middlewares,
|
|
270
|
+
{
|
|
271
|
+
helmet: route.helmetOptions,
|
|
272
|
+
schema: route.swaggerOptions,
|
|
273
|
+
},
|
|
259
274
|
)
|
|
260
275
|
})
|
|
261
276
|
})
|
package/src/index.d.ts
CHANGED
|
@@ -8,12 +8,34 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Facade } from '@athenna/ioc'
|
|
11
|
-
import { FastifyReply, FastifyRequest } from 'fastify'
|
|
12
11
|
import { Exception } from '@athenna/common'
|
|
12
|
+
import { OpenAPIV2, OpenAPIV3 } from 'openapi-types'
|
|
13
|
+
import { FastifyHelmetOptions } from '@fastify/helmet'
|
|
14
|
+
import { FastifyReply, FastifyRequest, RouteOptions } from 'fastify'
|
|
13
15
|
|
|
14
16
|
export const Server: Facade & Http
|
|
15
17
|
export const Route: Facade & Router.Router
|
|
16
18
|
|
|
19
|
+
interface FastifySwaggerSchema {
|
|
20
|
+
hide?: boolean
|
|
21
|
+
deprecated?: boolean
|
|
22
|
+
tags?: string[]
|
|
23
|
+
description?: string
|
|
24
|
+
summary?: string
|
|
25
|
+
body?: any
|
|
26
|
+
response?: any
|
|
27
|
+
consumes?: string[]
|
|
28
|
+
produces?: string[]
|
|
29
|
+
externalDocs?:
|
|
30
|
+
| OpenAPIV2.ExternalDocumentationObject
|
|
31
|
+
| OpenAPIV3.ExternalDocumentationObject
|
|
32
|
+
security?: Array<{ [securityLabel: string]: string[] }>
|
|
33
|
+
/**
|
|
34
|
+
* OpenAPI operation unique identifier
|
|
35
|
+
*/
|
|
36
|
+
operationId?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
export class HttpKernel {
|
|
18
40
|
/**
|
|
19
41
|
* The application's global HTTP middlewares.
|
|
@@ -47,6 +69,20 @@ export class HttpKernel {
|
|
|
47
69
|
*/
|
|
48
70
|
registerCors(): Promise<void>
|
|
49
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Register helmet plugin.
|
|
74
|
+
*
|
|
75
|
+
* @return {Promise<void>}
|
|
76
|
+
*/
|
|
77
|
+
registerHelmet(): Promise<void>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Register swagger plugin.
|
|
81
|
+
*
|
|
82
|
+
* @return {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
registerSwagger(): Promise<void>
|
|
85
|
+
|
|
50
86
|
/**
|
|
51
87
|
* Register rate limit plugin.
|
|
52
88
|
*
|
|
@@ -127,19 +163,35 @@ export class Http {
|
|
|
127
163
|
/**
|
|
128
164
|
* Register the cors plugin to fastify server.
|
|
129
165
|
*
|
|
130
|
-
* @param {import('fastify
|
|
166
|
+
* @param {import('@fastify/cors').FastifyCorsOptions} [options]
|
|
131
167
|
* @return {Http}
|
|
132
168
|
*/
|
|
133
|
-
registerCors(options?: import('fastify
|
|
169
|
+
registerCors(options?: import('@fastify/cors').FastifyCorsOptions): Http
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Register the helmet plugin to fastify server.
|
|
173
|
+
*
|
|
174
|
+
* @param {import('@fastify/helmet').FastifyHelmetOptions} [options]
|
|
175
|
+
* @return {Http}
|
|
176
|
+
*/
|
|
177
|
+
registerHelmet(options?: import('@fastify/helmet').FastifyHelmetOptions): Http
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Register the swagger plugin to fastify server.
|
|
181
|
+
*
|
|
182
|
+
* @param {import('@fastify/swagger').SwaggerOptions} [options]
|
|
183
|
+
* @return {Http}
|
|
184
|
+
*/
|
|
185
|
+
registerSwagger(options?: import('@fastify/swagger').SwaggerOptions): Http
|
|
134
186
|
|
|
135
187
|
/**
|
|
136
188
|
* Register the rate limit plugin to fastify server.
|
|
137
189
|
*
|
|
138
|
-
* @param {import('fastify
|
|
190
|
+
* @param {import('@fastify/rate-limit').RateLimitOptions} [options]
|
|
139
191
|
* @return {Http}
|
|
140
192
|
*/
|
|
141
193
|
registerRateLimit(
|
|
142
|
-
options?: import('fastify
|
|
194
|
+
options?: import('@fastify/rate-limit').RateLimitOptions,
|
|
143
195
|
): Http
|
|
144
196
|
|
|
145
197
|
/**
|
|
@@ -322,6 +374,93 @@ declare module Router {
|
|
|
322
374
|
prepend?: boolean,
|
|
323
375
|
): this
|
|
324
376
|
|
|
377
|
+
/**
|
|
378
|
+
* Set up all helmet options for route.
|
|
379
|
+
*
|
|
380
|
+
* @param {any} options
|
|
381
|
+
* @return {Route}
|
|
382
|
+
*/
|
|
383
|
+
helmet(options: FastifyHelmetOptions): this
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Set up all swagger options for route.
|
|
387
|
+
*
|
|
388
|
+
* @param {any} options
|
|
389
|
+
* @return {Route}
|
|
390
|
+
*/
|
|
391
|
+
swagger(options: FastifySwaggerSchema): this
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Set a summary for the route swagger docs.
|
|
395
|
+
*
|
|
396
|
+
* @param {string} summary
|
|
397
|
+
* @return {Route}
|
|
398
|
+
*/
|
|
399
|
+
summary(summary: string): this
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Set a description for the route swagger docs.
|
|
403
|
+
*
|
|
404
|
+
* @param {string} description
|
|
405
|
+
* @return {Route}
|
|
406
|
+
*/
|
|
407
|
+
description(description: string): this
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Set tags for the route swagger docs.
|
|
411
|
+
*
|
|
412
|
+
* @param {string} tags
|
|
413
|
+
* @return {Route}
|
|
414
|
+
*/
|
|
415
|
+
tags(...tags: string[]): this
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Set body param for the route swagger docs.
|
|
419
|
+
*
|
|
420
|
+
* @param {string} name
|
|
421
|
+
* @param {string} [type]
|
|
422
|
+
* @param {string} [description]
|
|
423
|
+
* @return {Route}
|
|
424
|
+
*/
|
|
425
|
+
body(name: string, type?: string, description?: string): Route
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Set param for the route swagger docs.
|
|
429
|
+
*
|
|
430
|
+
* @param {string} name
|
|
431
|
+
* @param {string} [type]
|
|
432
|
+
* @param {string} [description]
|
|
433
|
+
* @return {Route}
|
|
434
|
+
*/
|
|
435
|
+
param(name, type?: string, description?: string): Route
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Set query string for the route swagger docs.
|
|
439
|
+
*
|
|
440
|
+
* @param {string} name
|
|
441
|
+
* @param {string} [type]
|
|
442
|
+
* @param {string} [description]
|
|
443
|
+
* @return {Route}
|
|
444
|
+
*/
|
|
445
|
+
queryString(name, type?: string, description?: string): Route
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Set response for the route swagger docs.
|
|
449
|
+
*
|
|
450
|
+
* @param {any} response
|
|
451
|
+
* @return {Route}
|
|
452
|
+
*/
|
|
453
|
+
response(response: any): this
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Set response for the route swagger docs.
|
|
457
|
+
*
|
|
458
|
+
* @param {number} statusCode
|
|
459
|
+
* @param {any} response
|
|
460
|
+
* @return {Route}
|
|
461
|
+
*/
|
|
462
|
+
response(statusCode: number, response: any): this
|
|
463
|
+
|
|
325
464
|
toJSON(): any
|
|
326
465
|
}
|
|
327
466
|
|
|
@@ -360,9 +499,57 @@ declare module Router {
|
|
|
360
499
|
prepend?: boolean,
|
|
361
500
|
): this
|
|
362
501
|
|
|
502
|
+
/**
|
|
503
|
+
* Register only the methods in the array.
|
|
504
|
+
*
|
|
505
|
+
* @param {string} names
|
|
506
|
+
* @return {RouteResource}
|
|
507
|
+
*/
|
|
363
508
|
only(names: string[]): this
|
|
509
|
+
only(...names: string[]): this
|
|
364
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Register all methods except the methods in the array.
|
|
513
|
+
*
|
|
514
|
+
* @param {string} names
|
|
515
|
+
* @return {RouteResource}
|
|
516
|
+
*/
|
|
365
517
|
except(names: string[]): this
|
|
518
|
+
except(...names: string[]): this
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Set up helmet options for route resource.
|
|
522
|
+
*
|
|
523
|
+
* @param {FastifyHelmetOptions} options
|
|
524
|
+
* @return {RouteResource}
|
|
525
|
+
*/
|
|
526
|
+
helmet(options: FastifyHelmetOptions): this
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Set up helmet options for route resource.
|
|
530
|
+
*
|
|
531
|
+
* @param {string} action
|
|
532
|
+
* @param {FastifyHelmetOptions} options
|
|
533
|
+
* @return {RouteResource}
|
|
534
|
+
*/
|
|
535
|
+
helmet(action: string, options: FastifyHelmetOptions): this
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Set up swagger options for route resource method.
|
|
539
|
+
*
|
|
540
|
+
* @param {FastifySwaggerSchema} options
|
|
541
|
+
* @return {RouteResource}
|
|
542
|
+
*/
|
|
543
|
+
swagger(options: FastifySwaggerSchema): this
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Set up swagger options for route resource method.
|
|
547
|
+
*
|
|
548
|
+
* @param {string} action
|
|
549
|
+
* @param {FastifySwaggerSchema} options
|
|
550
|
+
* @return {RouteResource}
|
|
551
|
+
*/
|
|
552
|
+
swagger(action: string, options: FastifySwaggerSchema): this
|
|
366
553
|
}
|
|
367
554
|
|
|
368
555
|
export class RouteGroup {
|
|
@@ -401,6 +588,22 @@ declare module Router {
|
|
|
401
588
|
type?: 'terminate',
|
|
402
589
|
prepend?: boolean,
|
|
403
590
|
): this
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Set up helmet options for route group.
|
|
594
|
+
*
|
|
595
|
+
* @param {any} options
|
|
596
|
+
* @return {RouteGroup}
|
|
597
|
+
*/
|
|
598
|
+
helmet(options: FastifyHelmetOptions): this
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Set up swagger options for route group.
|
|
602
|
+
*
|
|
603
|
+
* @param {any} options
|
|
604
|
+
* @return {RouteGroup}
|
|
605
|
+
*/
|
|
606
|
+
swagger(options: FastifySwaggerSchema): this
|
|
404
607
|
}
|
|
405
608
|
|
|
406
609
|
export class Router {
|
|
@@ -433,6 +636,15 @@ declare module Router {
|
|
|
433
636
|
handler: string | HandlerContract,
|
|
434
637
|
): Route
|
|
435
638
|
|
|
639
|
+
/**
|
|
640
|
+
* Register a new vanila route using fastify options
|
|
641
|
+
* directly.
|
|
642
|
+
*
|
|
643
|
+
* @param {import('fastify').RouteOptions} options
|
|
644
|
+
* @return {void}
|
|
645
|
+
*/
|
|
646
|
+
vanilaRoute(options: RouteOptions): void
|
|
647
|
+
|
|
436
648
|
/**
|
|
437
649
|
* Creates a new route group.
|
|
438
650
|
*
|
|
@@ -549,44 +761,192 @@ declare module Router {
|
|
|
549
761
|
}
|
|
550
762
|
|
|
551
763
|
export interface RequestContract {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
764
|
+
/**
|
|
765
|
+
* Get the request ip.
|
|
766
|
+
*
|
|
767
|
+
* @return {string}
|
|
768
|
+
*/
|
|
769
|
+
get ip(): string
|
|
770
|
+
/**
|
|
771
|
+
* Get the request method.
|
|
772
|
+
*
|
|
773
|
+
* @return {string}
|
|
774
|
+
*/
|
|
775
|
+
get method(): string
|
|
561
776
|
|
|
562
|
-
|
|
777
|
+
/**
|
|
778
|
+
* Get the host url from request.
|
|
779
|
+
*
|
|
780
|
+
* @return {string}
|
|
781
|
+
*/
|
|
782
|
+
get hostUrl(): string
|
|
563
783
|
|
|
564
|
-
|
|
784
|
+
/**
|
|
785
|
+
* Get the base request url.
|
|
786
|
+
*
|
|
787
|
+
* @return {string}
|
|
788
|
+
*/
|
|
789
|
+
get baseUrl(): string
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Get the original request url.
|
|
793
|
+
*
|
|
794
|
+
* @return {string}
|
|
795
|
+
*/
|
|
796
|
+
get originalUrl(): string
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Get all body from request.
|
|
800
|
+
*
|
|
801
|
+
* @return {any}
|
|
802
|
+
*/
|
|
803
|
+
get body(): any
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Get all params from request.
|
|
807
|
+
*
|
|
808
|
+
* @return {any}
|
|
809
|
+
*/
|
|
810
|
+
get params(): any
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Get all queries from request.
|
|
814
|
+
*
|
|
815
|
+
* @return {any}
|
|
816
|
+
*/
|
|
817
|
+
get queries(): any
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Get all headers from request.
|
|
821
|
+
*
|
|
822
|
+
* @return {any}
|
|
823
|
+
*/
|
|
824
|
+
get headers(): any
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Get a value from the request params or the default value.
|
|
828
|
+
*
|
|
829
|
+
* @param {string} param
|
|
830
|
+
* @param {string} [defaultValue]
|
|
831
|
+
* @return {any}
|
|
832
|
+
*/
|
|
833
|
+
param(param, defaultValue): any
|
|
565
834
|
|
|
566
|
-
|
|
835
|
+
/**
|
|
836
|
+
* Get a value from the request query param or the default value.
|
|
837
|
+
*
|
|
838
|
+
* @param {string} query
|
|
839
|
+
* @param {string} [defaultValue]
|
|
840
|
+
* @return {any}
|
|
841
|
+
*/
|
|
842
|
+
query(query, defaultValue): any
|
|
567
843
|
|
|
568
|
-
|
|
844
|
+
/**
|
|
845
|
+
* Get a value from the request header or the default value.
|
|
846
|
+
*
|
|
847
|
+
* @param {string} header
|
|
848
|
+
* @param {string} [defaultValue]
|
|
849
|
+
* @return {any}
|
|
850
|
+
*/
|
|
851
|
+
header(header, defaultValue): any
|
|
569
852
|
|
|
853
|
+
/**
|
|
854
|
+
* Get a value from the request body or the default value.
|
|
855
|
+
*
|
|
856
|
+
* @param {string} payload
|
|
857
|
+
* @param {string} [defaultValue]
|
|
858
|
+
* @return {any}
|
|
859
|
+
*/
|
|
860
|
+
payload(payload, defaultValue): any
|
|
861
|
+
/**
|
|
862
|
+
* Get the default fastify request object.
|
|
863
|
+
*
|
|
864
|
+
* @return {import('fastify').FastifyRequest}
|
|
865
|
+
*/
|
|
570
866
|
getFastifyRequest(): FastifyRequest
|
|
571
867
|
}
|
|
572
868
|
|
|
573
869
|
export interface ResponseContract {
|
|
574
|
-
|
|
870
|
+
/**
|
|
871
|
+
* Terminate the request sending the response body.
|
|
872
|
+
*
|
|
873
|
+
* @param {any} [data]
|
|
874
|
+
* @return {void}
|
|
875
|
+
*/
|
|
876
|
+
send(data?: any): Promise<void>
|
|
575
877
|
|
|
576
|
-
|
|
878
|
+
/**
|
|
879
|
+
* Terminate the request sending the response body.
|
|
880
|
+
*
|
|
881
|
+
* @param {any} [data]
|
|
882
|
+
* @return {void}
|
|
883
|
+
*/
|
|
884
|
+
json(data?: any): Promise<void>
|
|
577
885
|
|
|
886
|
+
/**
|
|
887
|
+
* Apply helmet in response.
|
|
888
|
+
*
|
|
889
|
+
* @param {import('@fastify/helmet').FastifyHelmetOptions} [options]
|
|
890
|
+
* @return {void}
|
|
891
|
+
*/
|
|
892
|
+
helmet(options?: FastifyHelmetOptions): Promise<void>
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Set the response status code.
|
|
896
|
+
*
|
|
897
|
+
* @param {number} code
|
|
898
|
+
* @return {Response}
|
|
899
|
+
*/
|
|
578
900
|
status(code: number): this
|
|
579
901
|
|
|
902
|
+
/**
|
|
903
|
+
* Remove some header from the response.
|
|
904
|
+
*
|
|
905
|
+
* @param {string} header
|
|
906
|
+
* @return {Response}
|
|
907
|
+
*/
|
|
580
908
|
removeHeader(header: string): this
|
|
581
909
|
|
|
910
|
+
/**
|
|
911
|
+
* Add some header to the response.
|
|
912
|
+
*
|
|
913
|
+
* @param {string} header
|
|
914
|
+
* @param {any} value
|
|
915
|
+
* @return {Response}
|
|
916
|
+
*/
|
|
582
917
|
header(header: string, value: any): this
|
|
583
918
|
|
|
919
|
+
/**
|
|
920
|
+
* Only add some header to the response if it's not defined yet.
|
|
921
|
+
*
|
|
922
|
+
* @param {string} header
|
|
923
|
+
* @param {any} value
|
|
924
|
+
* @return {Response}
|
|
925
|
+
*/
|
|
584
926
|
safeHeader(header: string, value: any): this
|
|
585
927
|
|
|
928
|
+
/**
|
|
929
|
+
* Redirect the response to other url with different status code.
|
|
930
|
+
*
|
|
931
|
+
* @param {string} url
|
|
932
|
+
* @return {void}
|
|
933
|
+
*/
|
|
586
934
|
redirectTo(url: string): Promise<void> | void
|
|
587
935
|
|
|
588
|
-
|
|
936
|
+
/**
|
|
937
|
+
* Redirect the response to other url with different status code.
|
|
938
|
+
*
|
|
939
|
+
* @param {string} url
|
|
940
|
+
* @param {number} statusCode
|
|
941
|
+
* @return {void}
|
|
942
|
+
*/
|
|
943
|
+
redirectTo(url: string, statusCode: number): Promise<void>
|
|
589
944
|
|
|
945
|
+
/**
|
|
946
|
+
* Get the default fastify response object.
|
|
947
|
+
*
|
|
948
|
+
* @return {import('fastify').FastifyReply}
|
|
949
|
+
*/
|
|
590
950
|
getFastifyResponse(): FastifyReply
|
|
591
951
|
}
|
|
592
952
|
|
|
@@ -606,10 +966,6 @@ export class HttpLoader {
|
|
|
606
966
|
static loadTemplates(): any[]
|
|
607
967
|
}
|
|
608
968
|
|
|
609
|
-
export interface NextContract {
|
|
610
|
-
(...params: any[]): void
|
|
611
|
-
}
|
|
612
|
-
|
|
613
969
|
export interface ContextContract {
|
|
614
970
|
request: RequestContract
|
|
615
971
|
response: ResponseContract
|
|
@@ -633,7 +989,6 @@ export interface HandleContextContract {
|
|
|
633
989
|
data: any
|
|
634
990
|
params: any
|
|
635
991
|
queries: any
|
|
636
|
-
next: NextContract
|
|
637
992
|
}
|
|
638
993
|
|
|
639
994
|
export interface InterceptContextContract {
|
|
@@ -656,7 +1011,6 @@ export interface TerminateContextContract {
|
|
|
656
1011
|
headers: any
|
|
657
1012
|
status: number
|
|
658
1013
|
responseTime: number
|
|
659
|
-
next: NextContract
|
|
660
1014
|
}
|
|
661
1015
|
|
|
662
1016
|
export interface ErrorHandlerContract {
|
package/src/index.js
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
import { Options } from '@athenna/common'
|
|
11
11
|
|
|
12
12
|
import fastify from 'fastify'
|
|
13
|
-
|
|
14
|
-
import fastifyRateLimit from 'fastify-rate-limit'
|
|
13
|
+
|
|
15
14
|
import { FastifyHandler } from '#src/Handlers/FastifyHandler'
|
|
16
15
|
|
|
17
16
|
export * from './Facades/Route.js'
|
|
@@ -82,12 +81,12 @@ export class Http {
|
|
|
82
81
|
/**
|
|
83
82
|
* Register a new fastify plugin.
|
|
84
83
|
*
|
|
85
|
-
* @param {
|
|
86
|
-
* @param {
|
|
84
|
+
* @param {any} plugin
|
|
85
|
+
* @param {any} [options]
|
|
87
86
|
* @return {Http}
|
|
88
87
|
*/
|
|
89
|
-
register(plugin, options) {
|
|
90
|
-
this.#server.register(plugin, options)
|
|
88
|
+
async register(plugin, options = {}) {
|
|
89
|
+
await this.#server.register(plugin, options)
|
|
91
90
|
|
|
92
91
|
return this
|
|
93
92
|
}
|
|
@@ -95,25 +94,46 @@ export class Http {
|
|
|
95
94
|
/**
|
|
96
95
|
* Register the cors plugin to fastify server.
|
|
97
96
|
*
|
|
98
|
-
* @param {import('fastify
|
|
97
|
+
* @param {import('@fastify/cors').FastifyCorsOptions} [options]
|
|
99
98
|
* @return {Http}
|
|
100
99
|
*/
|
|
101
|
-
registerCors(options) {
|
|
102
|
-
this.register(
|
|
100
|
+
async registerCors(options) {
|
|
101
|
+
return this.register(import('@fastify/cors'), options)
|
|
102
|
+
}
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Register the helmet plugin to fastify server.
|
|
106
|
+
*
|
|
107
|
+
* @param {import('@fastify/helmet').FastifyHelmetOptions} [options]
|
|
108
|
+
* @return {Http}
|
|
109
|
+
*/
|
|
110
|
+
async registerHelmet(options) {
|
|
111
|
+
return this.register(import('@fastify/helmet'), options)
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
/**
|
|
108
|
-
* Register the
|
|
115
|
+
* Register the swagger plugin to fastify server.
|
|
109
116
|
*
|
|
110
|
-
* @param {
|
|
117
|
+
* @param {{
|
|
118
|
+
* ui: import('@fastify/swagger-ui').FastifySwaggerUiOptions,
|
|
119
|
+
* configurations: import('@fastify/swagger').SwaggerOptions
|
|
120
|
+
* }} [options]
|
|
111
121
|
* @return {Http}
|
|
112
122
|
*/
|
|
113
|
-
|
|
114
|
-
this.register(
|
|
123
|
+
async registerSwagger(options = {}) {
|
|
124
|
+
await this.register(import('@fastify/swagger'), options.configurations)
|
|
115
125
|
|
|
116
|
-
return this
|
|
126
|
+
return this.register(import('@fastify/swagger-ui'), options.ui)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Register the rate limit plugin to fastify server.
|
|
131
|
+
*
|
|
132
|
+
* @param {import('@fastify/rate-limit').RateLimitOptions} [options]
|
|
133
|
+
* @return {Http}
|
|
134
|
+
*/
|
|
135
|
+
async registerRateLimit(options) {
|
|
136
|
+
return this.register(import('@fastify/rate-limit'), options)
|
|
117
137
|
}
|
|
118
138
|
|
|
119
139
|
/**
|
|
@@ -186,7 +206,7 @@ export class Http {
|
|
|
186
206
|
async listen(port = 1335, host = '0.0.0.0') {
|
|
187
207
|
this.#isListening = true
|
|
188
208
|
|
|
189
|
-
return this.#server.listen(port, host)
|
|
209
|
+
return this.#server.listen({ port, host })
|
|
190
210
|
}
|
|
191
211
|
|
|
192
212
|
/**
|
|
@@ -209,9 +229,10 @@ export class Http {
|
|
|
209
229
|
* @param {string[]} methods
|
|
210
230
|
* @param {any} handler
|
|
211
231
|
* @param {any} [middlewares]
|
|
232
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
212
233
|
* @return {void}
|
|
213
234
|
*/
|
|
214
|
-
route(url, methods, handler, middlewares) {
|
|
235
|
+
route(url, methods, handler, middlewares, otherOptions = {}) {
|
|
215
236
|
const { handlers, terminators, interceptors } = Options.create(
|
|
216
237
|
middlewares,
|
|
217
238
|
{
|
|
@@ -230,6 +251,7 @@ export class Http {
|
|
|
230
251
|
handler: FastifyHandler.createRequestHandler(handler),
|
|
231
252
|
preHandler: handlers.map(m => FastifyHandler.createDoneHandler(m)),
|
|
232
253
|
onSend: interceptors.map(m => FastifyHandler.createOnSendHandler(m)),
|
|
254
|
+
...otherOptions,
|
|
233
255
|
})
|
|
234
256
|
}
|
|
235
257
|
|
|
@@ -239,10 +261,11 @@ export class Http {
|
|
|
239
261
|
* @param {string} url
|
|
240
262
|
* @param {any} handler
|
|
241
263
|
* @param {any} [middlewares]
|
|
264
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
242
265
|
* @return {void}
|
|
243
266
|
*/
|
|
244
|
-
get(url, handler, middlewares) {
|
|
245
|
-
this.route(url, ['GET'], handler, middlewares)
|
|
267
|
+
get(url, handler, middlewares, otherOptions) {
|
|
268
|
+
this.route(url, ['GET'], handler, middlewares, otherOptions)
|
|
246
269
|
}
|
|
247
270
|
|
|
248
271
|
/**
|
|
@@ -251,10 +274,11 @@ export class Http {
|
|
|
251
274
|
* @param {string} url
|
|
252
275
|
* @param {any} handler
|
|
253
276
|
* @param {any} [middlewares]
|
|
277
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
254
278
|
* @return {void}
|
|
255
279
|
*/
|
|
256
|
-
head(url, handler, middlewares) {
|
|
257
|
-
this.route(url, ['HEAD'], handler, middlewares)
|
|
280
|
+
head(url, handler, middlewares, otherOptions) {
|
|
281
|
+
this.route(url, ['HEAD'], handler, middlewares, otherOptions)
|
|
258
282
|
}
|
|
259
283
|
|
|
260
284
|
/**
|
|
@@ -263,10 +287,11 @@ export class Http {
|
|
|
263
287
|
* @param {string} url
|
|
264
288
|
* @param {any} handler
|
|
265
289
|
* @param {any} [middlewares]
|
|
290
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
266
291
|
* @return {void}
|
|
267
292
|
*/
|
|
268
|
-
post(url, handler, middlewares) {
|
|
269
|
-
this.route(url, ['POST'], handler, middlewares)
|
|
293
|
+
post(url, handler, middlewares, otherOptions) {
|
|
294
|
+
this.route(url, ['POST'], handler, middlewares, otherOptions)
|
|
270
295
|
}
|
|
271
296
|
|
|
272
297
|
/**
|
|
@@ -275,10 +300,11 @@ export class Http {
|
|
|
275
300
|
* @param {string} url
|
|
276
301
|
* @param {any} handler
|
|
277
302
|
* @param {any} [middlewares]
|
|
303
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
278
304
|
* @return {void}
|
|
279
305
|
*/
|
|
280
|
-
put(url, handler, middlewares) {
|
|
281
|
-
this.route(url, ['PUT'], handler, middlewares)
|
|
306
|
+
put(url, handler, middlewares, otherOptions) {
|
|
307
|
+
this.route(url, ['PUT'], handler, middlewares, otherOptions)
|
|
282
308
|
}
|
|
283
309
|
|
|
284
310
|
/**
|
|
@@ -287,10 +313,11 @@ export class Http {
|
|
|
287
313
|
* @param {string} url
|
|
288
314
|
* @param {any} handler
|
|
289
315
|
* @param {any} [middlewares]
|
|
316
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
290
317
|
* @return {void}
|
|
291
318
|
*/
|
|
292
|
-
patch(url, handler, middlewares) {
|
|
293
|
-
this.route(url, ['PATCH'], handler, middlewares)
|
|
319
|
+
patch(url, handler, middlewares, otherOptions) {
|
|
320
|
+
this.route(url, ['PATCH'], handler, middlewares, otherOptions)
|
|
294
321
|
}
|
|
295
322
|
|
|
296
323
|
/**
|
|
@@ -299,10 +326,11 @@ export class Http {
|
|
|
299
326
|
* @param {string} url
|
|
300
327
|
* @param {any} handler
|
|
301
328
|
* @param {any} [middlewares]
|
|
329
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
302
330
|
* @return {void}
|
|
303
331
|
*/
|
|
304
|
-
delete(url, handler, middlewares) {
|
|
305
|
-
this.route(url, ['DELETE'], handler, middlewares)
|
|
332
|
+
delete(url, handler, middlewares, otherOptions) {
|
|
333
|
+
this.route(url, ['DELETE'], handler, middlewares, otherOptions)
|
|
306
334
|
}
|
|
307
335
|
|
|
308
336
|
/**
|
|
@@ -311,9 +339,10 @@ export class Http {
|
|
|
311
339
|
* @param {string} url
|
|
312
340
|
* @param {any} handler
|
|
313
341
|
* @param {any} [middlewares]
|
|
342
|
+
* @param {import('fastify').RouteOptions} [otherOptions]
|
|
314
343
|
* @return {void}
|
|
315
344
|
*/
|
|
316
|
-
options(url, handler, middlewares) {
|
|
317
|
-
this.route(url, ['OPTIONS'], handler, middlewares)
|
|
345
|
+
options(url, handler, middlewares, otherOptions) {
|
|
346
|
+
this.route(url, ['OPTIONS'], handler, middlewares, otherOptions)
|
|
318
347
|
}
|
|
319
348
|
}
|
|
@@ -10,16 +10,16 @@ export class {{ namePascal }} {
|
|
|
10
10
|
* in your controller.
|
|
11
11
|
*
|
|
12
12
|
* @param {import('@athenna/http').HandleContextContract} ctx
|
|
13
|
+
* @return {Promise<void>}
|
|
13
14
|
*/
|
|
14
|
-
async handle(
|
|
15
|
-
next()
|
|
16
|
-
}
|
|
15
|
+
async handle(ctx) {}
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Intercept method is executed before the response
|
|
20
19
|
* has been sent.
|
|
21
20
|
*
|
|
22
21
|
* @param {import('@athenna/http').InterceptContextContract} ctx
|
|
22
|
+
* @return {Promise<any>}
|
|
23
23
|
*/
|
|
24
24
|
async intercept({ body }) {
|
|
25
25
|
body.intercepted = true
|
|
@@ -32,9 +32,7 @@ export class {{ namePascal }} {
|
|
|
32
32
|
* has been sent.
|
|
33
33
|
*
|
|
34
34
|
* @param {import('@athenna/http').TerminateContextContract} ctx
|
|
35
|
-
* @return
|
|
35
|
+
* @return {Promise<void>}
|
|
36
36
|
*/
|
|
37
|
-
async terminate(
|
|
38
|
-
next()
|
|
39
|
-
}
|
|
37
|
+
async terminate(ctx) {}
|
|
40
38
|
}
|