expressed-example-app 1.0.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/app.js ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Aplicación principal
3
+ * Integración de @hooked, @router y @queued con una arquitectura limpia
4
+ */
5
+
6
+ const express = require('express');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const ExpressHooked = require('express-hooked');
10
+ const ExpressRouterIntegration = require('express-router-bds');
11
+ const ExpressQueueIntegration = require('express-queued');
12
+ const AppHooks = require('./hooks/AppHooks');
13
+ const { captureBodyMiddleware } = require('./middleware/bodyCapture');
14
+
15
+ // Crear la aplicación Express
16
+ const app = express();
17
+ const port = 3001;
18
+
19
+ // Leer la configuración de rutas desde el archivo JSON
20
+ const routesConfig = JSON.parse(fs.readFileSync(path.join(__dirname, 'config/routes.json'), 'utf8'));
21
+
22
+ // Inicializar el sistema de hooks
23
+ const hooked = new ExpressHooked(app);
24
+
25
+ // Inicializar el sistema de enrutamiento
26
+ const router = new ExpressRouterIntegration();
27
+
28
+ // Inicializar el sistema de colas
29
+ const queueSystem = new ExpressQueueIntegration();
30
+
31
+ // Registrar los hooks de la aplicación
32
+ AppHooks.registerHooks(hooked);
33
+
34
+ // Middleware para capturar el body
35
+ app.use(captureBodyMiddleware);
36
+
37
+ // Middleware para servir archivos estáticos
38
+ app.use(express.static(path.join(__dirname, 'public')));
39
+
40
+ // Cargar dinámicamente los controladores y registrar las rutas
41
+ for (const route of routesConfig.routes) {
42
+ // Extraer el nombre del controlador y la acción
43
+ const [controllerName, actionName] = route.controller.split('.');
44
+
45
+ // Construir la ruta del archivo del controlador
46
+ const controllerPath = path.join(__dirname, 'controllers', `${controllerName}.js`);
47
+
48
+ // Verificar si el archivo del controlador existe
49
+ if (fs.existsSync(controllerPath)) {
50
+ // Importar el controlador
51
+ const Controller = require(controllerPath);
52
+
53
+ // Verificar si la acción existe en el controlador
54
+ if (Controller[actionName]) {
55
+ // Registrar la ruta con el método HTTP, la ruta y el controlador
56
+ router.addRoute(route.method, route.path, (req, res) => {
57
+ // Disparar hook antes de ejecutar la acción
58
+ hooked.doAction('before_controller_action', req, res, route);
59
+
60
+ // Disparar hook para mostrar información detallada de la solicitud
61
+ // Usar el body capturado en lugar del body original que puede estar vacío
62
+ if (req.capturedBody) {
63
+ req.body = req.capturedBody;
64
+ }
65
+ hooked.doAction('request_details_log', req, res, route);
66
+
67
+ // Ejecutar la acción del controlador
68
+ Controller[actionName](req, res);
69
+
70
+ // Disparar hook después de ejecutar la acción
71
+ hooked.doAction('after_controller_action', req, res, route);
72
+ });
73
+ } else {
74
+ console.error(`La acción "${actionName}" no existe en el controlador "${controllerName}"`);
75
+ }
76
+ } else {
77
+ console.error(`El archivo del controlador "${controllerPath}" no existe`);
78
+ }
79
+ }
80
+
81
+ // Aplicar el middleware de colas para inyectar el sistema en las solicitudes
82
+ app.use(queueSystem.queueMiddleware());
83
+
84
+ // Aplicar el router a la aplicación
85
+ router.applyToApp(app);
86
+
87
+ // Iniciar el sistema de colas
88
+ queueSystem.start();
89
+
90
+ // Iniciar el sistema de hooks
91
+ hooked.init();
92
+
93
+ // Middleware para manejo de errores
94
+ app.use((err, req, res, next) => {
95
+ console.error('Error:', err);
96
+ res.status(500).json({
97
+ error: 'Ocurrió un error en el servidor',
98
+ message: err.message
99
+ });
100
+ });
101
+
102
+ // Iniciar el servidor
103
+ app.listen(port, () => {
104
+ console.log(`Servidor corriendo en http://localhost:${port}`);
105
+ console.log('Módulos integrados:');
106
+ console.log('- @hooked: Sistema de hooks activo');
107
+ console.log('- @router: Sistema de enrutamiento activo');
108
+ console.log('- @queued: Sistema de colas activo');
109
+
110
+ // Mostrar rutas registradas
111
+ console.log('\nRutas disponibles:');
112
+ routesConfig.routes.forEach(route => {
113
+ console.log(`${route.method} ${route.path} -> ${route.controller}.${route.action}`);
114
+ });
115
+ });
@@ -0,0 +1,70 @@
1
+ {
2
+ "routes": [
3
+ {
4
+ "method": "GET",
5
+ "path": "/",
6
+ "controller": "HomeController.index",
7
+ "action": "index"
8
+ },
9
+ {
10
+ "method": "GET",
11
+ "path": "/users",
12
+ "controller": "UserController.list",
13
+ "action": "list"
14
+ },
15
+ {
16
+ "method": "GET",
17
+ "path": "/users/:id",
18
+ "controller": "UserController.show",
19
+ "action": "show"
20
+ },
21
+ {
22
+ "method": "POST",
23
+ "path": "/users",
24
+ "controller": "UserController.create",
25
+ "action": "create"
26
+ },
27
+ {
28
+ "method": "PUT",
29
+ "path": "/users/:id",
30
+ "controller": "UserController.update",
31
+ "action": "update"
32
+ },
33
+ {
34
+ "method": "DELETE",
35
+ "path": "/users/:id",
36
+ "controller": "UserController.destroy",
37
+ "action": "destroy"
38
+ },
39
+ {
40
+ "method": "GET",
41
+ "path": "/products",
42
+ "controller": "ProductController.list",
43
+ "action": "list"
44
+ },
45
+ {
46
+ "method": "GET",
47
+ "path": "/products/:id",
48
+ "controller": "ProductController.show",
49
+ "action": "show"
50
+ },
51
+ {
52
+ "method": "POST",
53
+ "path": "/products",
54
+ "controller": "ProductController.create",
55
+ "action": "create"
56
+ },
57
+ {
58
+ "method": "GET",
59
+ "path": "/queue/status",
60
+ "controller": "QueueController.status",
61
+ "action": "status"
62
+ },
63
+ {
64
+ "method": "GET",
65
+ "path": "/endpoints",
66
+ "controller": "EndpointController.listEndpoints",
67
+ "action": "listEndpoints"
68
+ }
69
+ ]
70
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Controlador de endpoints
3
+ */
4
+ class EndpointController {
5
+ /**
6
+ * Lista todos los endpoints disponibles
7
+ * @param {Object} req - Objeto de solicitud
8
+ * @param {Object} res - Objeto de respuesta
9
+ */
10
+ static listEndpoints(req, res) {
11
+ // El sistema de hooks será utilizado para obtener la lista de endpoints
12
+ if (req.app.locals.hooks) {
13
+ // Simular la recopilación de endpoints desde el sistema de rutas
14
+ const routes = [
15
+ { method: 'GET', path: '/', description: 'Inicio de la aplicación' },
16
+ { method: 'GET', path: '/users', description: 'Lista todos los usuarios' },
17
+ { method: 'GET', path: '/users/:id', description: 'Muestra un usuario específico' },
18
+ { method: 'POST', path: '/users', description: 'Crea un nuevo usuario' },
19
+ { method: 'PUT', path: '/users/:id', description: 'Actualiza un usuario' },
20
+ { method: 'DELETE', path: '/users/:id', description: 'Elimina un usuario' },
21
+ { method: 'GET', path: '/products', description: 'Lista todos los productos' },
22
+ { method: 'GET', path: '/products/:id', description: 'Muestra un producto específico' },
23
+ { method: 'POST', path: '/products', description: 'Crea un nuevo producto' },
24
+ { method: 'GET', path: '/queue/status', description: 'Estado del sistema de colas' },
25
+ { method: 'GET', path: '/endpoints', description: 'Lista todos los endpoints disponibles' }
26
+ ];
27
+
28
+ // Permitir que los hooks modifiquen la lista de endpoints
29
+ const processedEndpoints = req.app.locals.hooks.applyFilters('endpoints_list', routes);
30
+
31
+ res.json({
32
+ message: 'Lista de endpoints disponibles',
33
+ endpoints: processedEndpoints
34
+ });
35
+ } else {
36
+ res.status(500).json({
37
+ error: 'Sistema de hooks no disponible'
38
+ });
39
+ }
40
+ }
41
+ }
42
+
43
+ module.exports = EndpointController;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Controlador de inicio
3
+ */
4
+ class HomeController {
5
+ /**
6
+ * Acción de inicio
7
+ * @param {Object} req - Objeto de solicitud
8
+ * @param {Object} res - Objeto de respuesta
9
+ */
10
+ static index(req, res) {
11
+ res.json({
12
+ message: 'Bienvenido a la aplicación de ejemplo',
13
+ version: '1.0.0',
14
+ timestamp: new Date().toISOString()
15
+ });
16
+ }
17
+ }
18
+
19
+ module.exports = HomeController;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Controlador de productos
3
+ */
4
+ class ProductController {
5
+ /**
6
+ * Lista todos los productos
7
+ * @param {Object} req - Objeto de solicitud
8
+ * @param {Object} res - Objeto de respuesta
9
+ */
10
+ static list(req, res) {
11
+ res.json({
12
+ message: 'Lista de productos',
13
+ products: [
14
+ { id: 1, name: 'Laptop', price: 999.99 },
15
+ { id: 2, name: 'Mouse', price: 29.99 }
16
+ ]
17
+ });
18
+ }
19
+
20
+ /**
21
+ * Muestra un producto específico
22
+ * @param {Object} req - Objeto de solicitud
23
+ * @param {Object} res - Objeto de respuesta
24
+ */
25
+ static show(req, res) {
26
+ const productId = req.params.id;
27
+ res.json({
28
+ message: `Información del producto ${productId}`,
29
+ product: { id: productId, name: `Product ${productId}`, price: 19.99 }
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Crea un nuevo producto
35
+ * @param {Object} req - Objeto de solicitud
36
+ * @param {Object} res - Objeto de respuesta
37
+ */
38
+ static create(req, res) {
39
+ const productData = req.body;
40
+ res.status(201).json({
41
+ message: 'Producto creado exitosamente',
42
+ product: { id: Date.now(), ...productData }
43
+ });
44
+ }
45
+ }
46
+
47
+ module.exports = ProductController;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Controlador del sistema de colas
3
+ */
4
+ class QueueController {
5
+ /**
6
+ * Obtiene el estado del sistema de colas
7
+ * @param {Object} req - Objeto de solicitud
8
+ * @param {Object} res - Objeto de respuesta
9
+ */
10
+ static status(req, res) {
11
+ // El sistema de colas será inyectado por el middleware
12
+ if (req.queueSystem) {
13
+ const status = req.queueSystem.getStatus();
14
+ res.json({
15
+ message: 'Estado del sistema de colas',
16
+ status: status
17
+ });
18
+ } else {
19
+ res.status(500).json({
20
+ error: 'Sistema de colas no disponible'
21
+ });
22
+ }
23
+ }
24
+ }
25
+
26
+ module.exports = QueueController;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Controlador de usuarios
3
+ */
4
+ class UserController {
5
+ /**
6
+ * Lista todos los usuarios
7
+ * @param {Object} req - Objeto de solicitud
8
+ * @param {Object} res - Objeto de respuesta
9
+ */
10
+ static list(req, res) {
11
+ res.json({
12
+ message: 'Lista de usuarios',
13
+ users: [
14
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
15
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
16
+ ]
17
+ });
18
+ }
19
+
20
+ /**
21
+ * Muestra un usuario específico
22
+ * @param {Object} req - Objeto de solicitud
23
+ * @param {Object} res - Objeto de respuesta
24
+ */
25
+ static show(req, res) {
26
+ const userId = req.params.id;
27
+ res.json({
28
+ message: `Información del usuario ${userId}`,
29
+ user: { id: userId, name: `User ${userId}`, email: `user${userId}@example.com` }
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Crea un nuevo usuario
35
+ * @param {Object} req - Objeto de solicitud
36
+ * @param {Object} res - Objeto de respuesta
37
+ */
38
+ static create(req, res) {
39
+ const userData = req.body;
40
+ res.status(201).json({
41
+ message: 'Usuario creado exitosamente',
42
+ user: { id: Date.now(), ...userData }
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Actualiza un usuario
48
+ * @param {Object} req - Objeto de solicitud
49
+ * @param {Object} res - Objeto de respuesta
50
+ */
51
+ static update(req, res) {
52
+ const userId = req.params.id;
53
+ const userData = req.body;
54
+ res.json({
55
+ message: `Usuario ${userId} actualizado`,
56
+ user: { id: userId, ...userData }
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Elimina un usuario
62
+ * @param {Object} req - Objeto de solicitud
63
+ * @param {Object} res - Objeto de respuesta
64
+ */
65
+ static destroy(req, res) {
66
+ const userId = req.params.id;
67
+ res.json({
68
+ message: `Usuario ${userId} eliminado`
69
+ });
70
+ }
71
+ }
72
+
73
+ module.exports = UserController;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Archivo de hooks para la aplicación
3
+ * Define todos los hooks utilizados en la aplicación
4
+ */
5
+
6
+ class AppHooks {
7
+ /**
8
+ * Registra todos los hooks de la aplicación
9
+ * @param {ExpressHooked} hooked - Instancia del sistema de hooks
10
+ */
11
+ static registerHooks(hooked) {
12
+ // Hook para registrar información cuando comienza una solicitud
13
+ hooked.addAction('request_started', (req, res, next) => {
14
+ console.log(`[${new Date().toISOString()}] Nueva solicitud: ${req.method} ${req.url}`);
15
+ next();
16
+ });
17
+
18
+ // Hook para registrar información cuando se procesa una solicitud
19
+ hooked.addAction('request_processed', (req, res) => {
20
+ console.log(`[${new Date().toISOString()}] Solicitud procesada: ${req.method} ${req.url}`);
21
+ });
22
+
23
+ // Hook para registrar información detallada de cada solicitud
24
+ hooked.addAction('request_details_log', (req, res, routeInfo) => {
25
+ console.log(`\n--- Información de la Solicitud (mediante hook) ---`);
26
+ console.log(`Fecha/Hora: ${new Date().toISOString()}`);
27
+ console.log(`Método HTTP: ${req.method}`);
28
+ console.log(`Ruta: ${req.url}`);
29
+ if (routeInfo) {
30
+ console.log(`Ruta definida: ${routeInfo.method} ${routeInfo.path}`);
31
+ console.log(`Controlador: ${routeInfo.controller}`);
32
+ console.log(`Acción: ${routeInfo.action}`);
33
+ }
34
+ console.log(`IP Cliente: ${req.ip}`);
35
+ console.log(`Headers:`, req.headers);
36
+ if (Object.keys(req.params).length > 0) {
37
+ console.log(`Parámetros:`, req.params);
38
+ }
39
+ if (Object.keys(req.query).length > 0) {
40
+ console.log(`Query params:`, req.query);
41
+ }
42
+ if (req.body && Object.keys(req.body).length > 0) {
43
+ console.log(`Body:`, req.body);
44
+ }
45
+ console.log(`-----------------------------\n`);
46
+ });
47
+
48
+ // Hook para filtrar y modificar la lista de endpoints
49
+ hooked.addFilter('endpoints_list', (endpoints) => {
50
+ // Agregar información adicional a la lista de endpoints
51
+ return endpoints.map(endpoint => ({
52
+ ...endpoint,
53
+ addedBy: 'hook-system',
54
+ timestamp: new Date().toISOString()
55
+ }));
56
+ });
57
+ }
58
+ }
59
+
60
+ module.exports = AppHooks;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Middleware para capturar el body de las solicitudes
3
+ * Permite que el body esté disponible para los hooks
4
+ */
5
+
6
+ const express = require('express');
7
+
8
+ // Middleware para capturar el body
9
+ const captureBodyMiddleware = express.json({
10
+ verify: (req, res, buf, encoding) => {
11
+ req.rawBody = buf;
12
+ try {
13
+ req.capturedBody = JSON.parse(buf.toString(encoding));
14
+ } catch (e) {
15
+ req.capturedBody = buf.toString(encoding);
16
+ }
17
+ }
18
+ });
19
+
20
+ module.exports = { captureBodyMiddleware };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "expressed-example-app",
3
+ "version": "1.0.0",
4
+ "description": "Example application integrating @hooked, @router and @queued",
5
+ "main": "app.js",
6
+ "scripts": {
7
+ "start": "node app.js",
8
+ "dev": "nodemon app.js"
9
+ },
10
+ "dependencies": {
11
+ "express": "^4.22.1",
12
+ "express-hooked": "^1.0.1",
13
+ "express-queued": "^1.0.0",
14
+ "express-router-bds": "^1.0.0"
15
+ },
16
+ "keywords": [
17
+ "express",
18
+ "hooks",
19
+ "middleware",
20
+ "router",
21
+ "routing",
22
+ "queues",
23
+ "queue-system",
24
+ "hook-system",
25
+ "event-driven",
26
+ "plugin-architecture",
27
+ "modular",
28
+ "scalable",
29
+ "example",
30
+ "demo",
31
+ "boilerplate",
32
+ "framework",
33
+ "web-framework",
34
+ "api",
35
+ "rest-api",
36
+ "microservices",
37
+ "async",
38
+ "asynchronous",
39
+ "background-jobs",
40
+ "task-queue",
41
+ "express-plugins",
42
+ "express-middleware",
43
+ "nodejs",
44
+ "javascript",
45
+ "backend",
46
+ "server"
47
+ ],
48
+ "author": "Benjamin Sanchez Cardenas",
49
+ "license": "Apache-2.0",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://gitlab.com/bytedogssyndicate1/expressed-example-app.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://gitlab.com/bytedogssyndicate1/expressed-example-app/issues"
56
+ },
57
+ "homepage": "https://gitlab.com/bytedogssyndicate1/expressed-example-app#readme"
58
+ }