@athenna/http 1.3.8 → 1.4.1
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": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
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>",
|
|
@@ -49,9 +49,10 @@
|
|
|
49
49
|
"#tests/*": "./tests/*.js"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@athenna/
|
|
53
|
-
"@athenna/
|
|
54
|
-
"@
|
|
52
|
+
"@athenna/artisan": "1.2.7",
|
|
53
|
+
"@athenna/ioc": "1.2.0",
|
|
54
|
+
"@athenna/logger": "1.2.5",
|
|
55
|
+
"@secjs/utils": "1.9.4",
|
|
55
56
|
"fastify": "3.27.4",
|
|
56
57
|
"fastify-cors": "6.0.3",
|
|
57
58
|
"fastify-rate-limit": "5.8.0"
|
|
@@ -89,7 +90,11 @@
|
|
|
89
90
|
"html"
|
|
90
91
|
],
|
|
91
92
|
"report-dir": "./tests/Coverage",
|
|
92
|
-
"check-coverage": true
|
|
93
|
+
"check-coverage": true,
|
|
94
|
+
"statements": "70",
|
|
95
|
+
"branches": "70",
|
|
96
|
+
"functions": "70",
|
|
97
|
+
"lines": "70"
|
|
93
98
|
},
|
|
94
99
|
"husky": {
|
|
95
100
|
"hooks": {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/artisan
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { join } from 'node:path'
|
|
11
|
+
import { Folder, Path, String } from '@secjs/utils'
|
|
12
|
+
import { Artisan, Command, TemplateHelper } from '@athenna/artisan'
|
|
13
|
+
|
|
14
|
+
export class MakeController extends Command {
|
|
15
|
+
/**
|
|
16
|
+
* The name and signature of the console command.
|
|
17
|
+
*/
|
|
18
|
+
signature = 'make:controller <name>'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The console command description.
|
|
22
|
+
*/
|
|
23
|
+
description = 'Make a new controller file.'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Set additional flags in the commander instance.
|
|
27
|
+
* This method is executed when registering your command.
|
|
28
|
+
*
|
|
29
|
+
* @param {import('commander').Command} commander
|
|
30
|
+
* @return {import('commander').Command}
|
|
31
|
+
*/
|
|
32
|
+
addFlags(commander) {
|
|
33
|
+
return commander.option(
|
|
34
|
+
'--no-lint',
|
|
35
|
+
'Do not run eslint in the controller.',
|
|
36
|
+
true,
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Execute the console command.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} name
|
|
44
|
+
* @param {any} options
|
|
45
|
+
* @return {Promise<void>}
|
|
46
|
+
*/
|
|
47
|
+
async handle(name, options) {
|
|
48
|
+
TemplateHelper.setTemplatesFolder(
|
|
49
|
+
new Folder(join(__dirname, '..', '..', '..', 'templates')).loadSync(),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const resource = 'Controller'
|
|
53
|
+
const subPath = Path.app(`Http/${String.pluralize(resource)}`)
|
|
54
|
+
|
|
55
|
+
this.simpleLog(
|
|
56
|
+
`[ MAKING ${resource.toUpperCase()} ]\n`,
|
|
57
|
+
'rmNewLineStart',
|
|
58
|
+
'bold',
|
|
59
|
+
'green',
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const file = await TemplateHelper.getResourceFile(name, resource, subPath)
|
|
63
|
+
|
|
64
|
+
this.success(`${resource} ({yellow} "${file.name}") successfully created.`)
|
|
65
|
+
|
|
66
|
+
if (options.lint) {
|
|
67
|
+
await Artisan.call(`eslint:fix ${file.path} --resource ${resource}`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
TemplateHelper.setOriginalTemplatesFolder()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/artisan
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { join } from 'node:path'
|
|
11
|
+
import { Folder, Path, String } from '@secjs/utils'
|
|
12
|
+
import { Artisan, Command, TemplateHelper } from '@athenna/artisan'
|
|
13
|
+
|
|
14
|
+
export class MakeMiddleware extends Command {
|
|
15
|
+
/**
|
|
16
|
+
* The name and signature of the console command.
|
|
17
|
+
*/
|
|
18
|
+
signature = 'make:middleware <name>'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The console command description.
|
|
22
|
+
*/
|
|
23
|
+
description = 'Make a new middleware file.'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Set additional flags in the commander instance.
|
|
27
|
+
* This method is executed when registering your command.
|
|
28
|
+
*
|
|
29
|
+
* @param {import('commander').Command} commander
|
|
30
|
+
* @return {import('commander').Command}
|
|
31
|
+
*/
|
|
32
|
+
addFlags(commander) {
|
|
33
|
+
return commander
|
|
34
|
+
.option(
|
|
35
|
+
'--no-register',
|
|
36
|
+
'Do not register the middleware inside Kernel.',
|
|
37
|
+
true,
|
|
38
|
+
)
|
|
39
|
+
.option('--no-lint', 'Do not run eslint in the middleware.', true)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Execute the console command.
|
|
44
|
+
*
|
|
45
|
+
* @param {string} name
|
|
46
|
+
* @param {any} options
|
|
47
|
+
* @return {Promise<void>}
|
|
48
|
+
*/
|
|
49
|
+
async handle(name, options) {
|
|
50
|
+
TemplateHelper.setTemplatesFolder(
|
|
51
|
+
new Folder(join(__dirname, '..', '..', '..', 'templates')).loadSync(),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const resource = 'Middleware'
|
|
55
|
+
const subPath = Path.app(`Http/${String.pluralize(resource)}`)
|
|
56
|
+
|
|
57
|
+
this.simpleLog(
|
|
58
|
+
`[ MAKING ${resource.toUpperCase()} ]\n`,
|
|
59
|
+
'rmNewLineStart',
|
|
60
|
+
'bold',
|
|
61
|
+
'green',
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
const file = await TemplateHelper.getResourceFile(name, resource, subPath)
|
|
65
|
+
|
|
66
|
+
this.success(`${resource} ({yellow} "${file.name}") successfully created.`)
|
|
67
|
+
|
|
68
|
+
if (options.lint) {
|
|
69
|
+
await Artisan.call(`eslint:fix ${file.path} --resource ${resource}`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (options.register) {
|
|
73
|
+
await TemplateHelper.replaceObjectProperty(
|
|
74
|
+
Path.http('Kernel.js'),
|
|
75
|
+
'namedMiddlewares =',
|
|
76
|
+
file.name,
|
|
77
|
+
`#app/Http/Middlewares/${file.name}`,
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
TemplateHelper.setOriginalTemplatesFolder()
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/artisan
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { pathToFileURL } from 'node:url'
|
|
11
|
+
import { Command } from '@athenna/artisan'
|
|
12
|
+
import { Exec, Path, String } from '@secjs/utils'
|
|
13
|
+
|
|
14
|
+
export class RouteList extends Command {
|
|
15
|
+
/**
|
|
16
|
+
* The name and signature of the console command.
|
|
17
|
+
*/
|
|
18
|
+
signature = 'route:list'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The console command description.
|
|
22
|
+
*/
|
|
23
|
+
description = 'List all the routes of your application.'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Set additional flags in the commander instance.
|
|
27
|
+
* This method is executed when registering your command.
|
|
28
|
+
*
|
|
29
|
+
* @param {import('commander').Command} commander
|
|
30
|
+
* @return {import('commander').Command}
|
|
31
|
+
*/
|
|
32
|
+
addFlags(commander) {
|
|
33
|
+
return commander.option(
|
|
34
|
+
'-m, --middleware',
|
|
35
|
+
'List the middlewares of each route.',
|
|
36
|
+
false,
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Execute the console command.
|
|
42
|
+
*
|
|
43
|
+
* @param {any} options
|
|
44
|
+
* @return {Promise<void>}
|
|
45
|
+
*/
|
|
46
|
+
async handle(options) {
|
|
47
|
+
this.simpleLog('[ ROUTE LISTING ]', 'rmNewLineStart', 'bold', 'green')
|
|
48
|
+
|
|
49
|
+
const Route = ioc.safeUse('Athenna/Core/HttpRoute')
|
|
50
|
+
|
|
51
|
+
const Kernel = await Exec.getModule(
|
|
52
|
+
import(pathToFileURL(Path.http('Kernel.js')).href),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const kernel = new Kernel()
|
|
56
|
+
|
|
57
|
+
await kernel.registerCors()
|
|
58
|
+
await kernel.registerRateLimit()
|
|
59
|
+
await kernel.registerMiddlewares()
|
|
60
|
+
await kernel.registerErrorHandler()
|
|
61
|
+
await kernel.registerLogMiddleware()
|
|
62
|
+
await kernel.registerRequestIdMiddleware()
|
|
63
|
+
|
|
64
|
+
const routePath = Path.routes('http.js')
|
|
65
|
+
|
|
66
|
+
await import(routePath)
|
|
67
|
+
const routes = Route.listRoutes()
|
|
68
|
+
|
|
69
|
+
const header = ['Method', 'Route', 'Handler']
|
|
70
|
+
const rows = []
|
|
71
|
+
|
|
72
|
+
if (options.middleware) header.push('Middlewares')
|
|
73
|
+
|
|
74
|
+
routes.forEach(route => {
|
|
75
|
+
const row = [route.methods.join('|'), route.url, 'Closure']
|
|
76
|
+
|
|
77
|
+
if (options.middleware) {
|
|
78
|
+
let middlewares = ''
|
|
79
|
+
|
|
80
|
+
Object.keys(route.middlewares).forEach(key => {
|
|
81
|
+
if (route.middlewares[key].length) {
|
|
82
|
+
const number = route.middlewares[key].length
|
|
83
|
+
|
|
84
|
+
if (middlewares) {
|
|
85
|
+
middlewares = middlewares + '\n'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
middlewares = middlewares + `${String.toPascalCase(key)}: ${number}`
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
if (!middlewares) middlewares = 'Not found'
|
|
93
|
+
|
|
94
|
+
row.push(middlewares)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
rows.push(row)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
this.logTable({ head: header }, ...rows)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -64,11 +64,11 @@ export class HttpExceptionHandler {
|
|
|
64
64
|
return
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
const exception = new Exception(body.message, body.statusCode, body.code)
|
|
68
|
+
|
|
69
|
+
exception.stack = body.stack
|
|
70
|
+
|
|
71
|
+
const prettyError = await exception.prettify()
|
|
72
72
|
|
|
73
73
|
Log.channel('exception').error(prettyError.concat('\n'))
|
|
74
74
|
}
|
package/src/index.js
CHANGED
|
@@ -19,6 +19,10 @@ export * from './Facades/Server.js'
|
|
|
19
19
|
export * from './Kernels/HttpKernel.js'
|
|
20
20
|
export * from './Handlers/HttpExceptionHandler.js'
|
|
21
21
|
|
|
22
|
+
export * from './Commands/Route/List.js'
|
|
23
|
+
export * from './Commands/Make/Controller.js'
|
|
24
|
+
export * from './Commands/Make/Middleware.js'
|
|
25
|
+
|
|
22
26
|
export class Http {
|
|
23
27
|
/**
|
|
24
28
|
* Holds the fastify server instance.
|