jerkjs 2.5.4 → 2.5.8

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.
Files changed (69) hide show
  1. package/BENCHMARK_RESULTS.md +60 -0
  2. package/CHANGELOG.md +43 -0
  3. package/ESTADISTICAS_RENDIMIENTO.md +106 -0
  4. package/README.md +142 -423
  5. package/README_LEGACY.md +513 -0
  6. package/debug_hook.js +11 -0
  7. package/doc-2.5/ADMIN_EXTENSION_COMMANDS_MANUAL.md +261 -0
  8. package/doc-2.5/ADMIN_EXTENSION_HOOK_EXAMPLE.md +28 -0
  9. package/doc-2.5/ADMIN_EXTENSION_INTEGRATION_MANUAL.md +232 -0
  10. package/doc-2.5/CACHE_SYSTEM_MAP.md +206 -0
  11. package/doc-2.5/SESSION_SECURITY_FLAGS.md +174 -0
  12. package/doc-2.5/an/303/241lisis-completo-jerk-framework.md +213 -0
  13. package/docs/CACHE_SYSTEM_MAP.md +206 -0
  14. package/docs/SERVER_OPTIMIZATION_NOTES.md +87 -0
  15. package/index.js +7 -1
  16. package/jerk2.5.webp +0 -0
  17. package/lib/admin/AdminExtension.js +436 -0
  18. package/lib/admin/ModuleLoader.js +77 -0
  19. package/lib/admin/config.js +21 -0
  20. package/lib/admin/modules/CacheModule.js +145 -0
  21. package/lib/admin/modules/STATS_MODULE_README.md +98 -0
  22. package/lib/admin/modules/StatsModule.js +140 -0
  23. package/lib/admin/modules/SystemModule.js +140 -0
  24. package/lib/admin/modules/TimeModule.js +95 -0
  25. package/lib/cache/CacheHooks.js +141 -0
  26. package/lib/core/server.js +199 -46
  27. package/lib/middleware/session.js +11 -3
  28. package/lib/mvc/viewEngine.js +26 -1
  29. package/lib/router/RouteMatcher.js +242 -54
  30. package/lib/utils/globalStats.js +16 -0
  31. package/package.json +2 -2
  32. package/@qaLoadModel/controllers/ProductController.js +0 -143
  33. package/@qaLoadModel/controllers/UserController.js +0 -143
  34. package/@qaLoadModel/models/ProductModel.js +0 -41
  35. package/@qaLoadModel/models/UserModel.js +0 -41
  36. package/@qaLoadModel/package.json +0 -22
  37. package/@qaLoadModel/qa_report.md +0 -71
  38. package/@qaLoadModel/results.md +0 -97
  39. package/@qaLoadModel/routes.json +0 -58
  40. package/@qaLoadModel/server.js +0 -43
  41. package/@qaLoadModel/simple-test.js +0 -96
  42. package/@qaLoadModel/test-models.js +0 -144
  43. package/@qaLoadModel/test_endpoints.sh +0 -35
  44. package/@qaLoadModel/test_final.js +0 -89
  45. package/@qaLoadModel/views/products/index.html +0 -45
  46. package/@qaLoadModel/views/products/show.html +0 -27
  47. package/@qaLoadModel/views/users/index.html +0 -44
  48. package/@qaLoadModel/views/users/show.html +0 -26
  49. package/qa/INFORME_QA_JERKJS_ROUTING.md +0 -108
  50. package/qa/informe_qa_fix_enrutamiento.md +0 -93
  51. package/qa-app/controllers/homeController.js +0 -9
  52. package/qa-app/controllers/userController.js +0 -76
  53. package/qa-app/hooks-config.js +0 -65
  54. package/qa-app/models/UserModel.js +0 -36
  55. package/qa-app/package-lock.json +0 -1683
  56. package/qa-app/package.json +0 -25
  57. package/qa-app/public/css/style.css +0 -15
  58. package/qa-app/public/images/logo.png +0 -3
  59. package/qa-app/public/index.html +0 -15
  60. package/qa-app/public/js/main.js +0 -7
  61. package/qa-app/routes/api-routes.json +0 -23
  62. package/qa-app/routes/page-routes.json +0 -16
  63. package/qa-app/routes/static-routes.json +0 -20
  64. package/qa-app/server.js +0 -68
  65. package/qa-app/views/footer.html +0 -3
  66. package/qa-app/views/index.html +0 -20
  67. package/qa-app/views/users.html +0 -20
  68. package/utils/find_file_path.sh +0 -36
  69. /package/{doc2.5.3 → doc-2.5}/manual-mvc-completo.md +0 -0
@@ -0,0 +1,513 @@
1
+ # JERK Framework v2.5.6
2
+
3
+ ![JERK Framework Logo](jerk.webp)
4
+
5
+ **¿Nuevo en JERK? Comienza tu proyecto rápidamente con nuestro Starter Kit**
6
+
7
+ Nuestro Starter Kit en `standard/server.js` es la forma más rápida de comenzar con JERK. Viene con todas las funcionalidades del framework ya configuradas, permitiéndote concentrarte en desarrollar tu aplicación en lugar de configurar infraestructura.
8
+
9
+ **Características del Starter Kit:**
10
+ - Configuración lista para usar con todos los componentes principales
11
+ - Carga de rutas desde archivo JSON (`routes.json`)
12
+ - Sistema de controladores preconfigurado
13
+ - Middlewares esenciales ya integrados (autenticación, CORS, compresión, firewall, etc.)
14
+ - Sistema de logging y manejo de errores implementado
15
+ - **NUEVO: Arquitectura completa MVC con modelos y soporte para bases de datos**
16
+ - **NUEVO: Compatible con qbuilderjs para consultas SQL seguras y eficientes**
17
+
18
+ **Cómo comenzar:**
19
+ 1. Edita el archivo `routes.json` para definir tus rutas y asociarlas a tus controladores
20
+
21
+ Ejemplo básico de `routes.json`:
22
+ ```json
23
+ [
24
+ {
25
+ "path": "/",
26
+ "method": "GET",
27
+ "controller": "HomeController",
28
+ "handler": "index",
29
+ "contentType": "text/html"
30
+ },
31
+ {
32
+ "path": "/api/users",
33
+ "method": "GET",
34
+ "controller": "UserController",
35
+ "handler": "getAllUsers",
36
+ "contentType": "application/json"
37
+ }
38
+ ]
39
+ ```
40
+
41
+ 2. Crea tus controladores según las rutas definidas
42
+
43
+ Por ejemplo, para la ruta principal "/", crea un archivo `HomeController.js`:
44
+ ```javascript
45
+ class HomeController {
46
+ index(req, res) {
47
+ res.render('index.html', { data: 'Hola' });
48
+ }
49
+ }
50
+
51
+ module.exports = new HomeController();
52
+ ```
53
+
54
+ 3. ¡Tu aplicación estará listo para usar!
55
+
56
+ El Starter Kit incluye controladores de ejemplo para que puedas ver cómo funciona el sistema.
57
+
58
+ ## Ejemplo de Rutas Estáticas
59
+
60
+ Desde la versión 2.1.8, JERK Framework soporta rutas estáticas para servir archivos desde directorios locales:
61
+
62
+ ### En routes.json:
63
+ ```json
64
+ [
65
+ {
66
+ "path": "/static",
67
+ "method": "GET",
68
+ "static": {
69
+ "dir": "./public",
70
+ "index": ["index.html", "index.htm"],
71
+ "cacheControl": "public, max-age=3600"
72
+ }
73
+ },
74
+ {
75
+ "path": "/assets",
76
+ "method": "GET",
77
+ "static": {
78
+ "dir": "./public",
79
+ "index": [],
80
+ "cacheControl": "public, max-age=86400"
81
+ }
82
+ }
83
+ ]
84
+ ```
85
+
86
+ ### Usando addRoute():
87
+ ```javascript
88
+ // Ruta estática para servir archivos desde ./public
89
+ server.addRoute({
90
+ method: 'GET',
91
+ path: '/static',
92
+ static: {
93
+ dir: './public',
94
+ index: ['index.html'],
95
+ cacheControl: 'public, max-age=3600'
96
+ }
97
+ });
98
+
99
+ // Ruta estática para servir archivos JS, CSS e imágenes
100
+ server.addRoute('GET', '/assets', {
101
+ static: {
102
+ dir: './public/assets',
103
+ index: [],
104
+ cacheControl: 'public, max-age=86400'
105
+ }
106
+ });
107
+ ```
108
+
109
+ ## Novedades en v2.5.1
110
+
111
+ ### Corrección de rutas estáticas
112
+ - **Solución de error crítico con directorios**: Se corrigió un error donde el sistema de rutas estáticas intentaba leer directorios como si fueran archivos, causando el error `EISDIR: illegal operation on a directory, read`. Ahora el sistema verifica explícitamente si una ruta es un directorio y en tal caso busca el archivo índice correspondiente.
113
+
114
+ ## Carga de Rutas desde Múltiples Archivos (v2.5.0)
115
+
116
+ Desde la versión 2.5.0, JERK Framework incluye el componente `RouteDirectoryLoader` que permite cargar rutas desde múltiples archivos JSON ubicados en un directorio específico. Esta funcionalidad mejora la organización y mantenibilidad de aplicaciones grandes al permitir dividir las rutas en varios archivos en lugar de tener un único archivo `routes.json`.
117
+
118
+ ### Ventajas del RouteDirectoryLoader:
119
+ - Organización por funcionalidad (usuarios, autenticación, API, etc.)
120
+ - Mayor mantenibilidad en proyectos grandes
121
+ - Detección automática de rutas duplicadas
122
+ - Mensajes de advertencia coloreados para rutas sobreescritas
123
+ - Recarga automática de rutas en desarrollo
124
+
125
+ ### Uso del RouteDirectoryLoader:
126
+
127
+ ```javascript
128
+ const { APIServer, RouteDirectoryLoader } = require('jerkjs');
129
+
130
+ const server = new APIServer({ port: 3000 });
131
+ const routeDirectoryLoader = new RouteDirectoryLoader();
132
+
133
+ // Cargar rutas desde un directorio que contiene múltiples archivos JSON
134
+ routeDirectoryLoader.loadRoutesFromDirectory(server, './routes')
135
+ .then(routes => {
136
+ console.log(`${routes.length} rutas cargadas exitosamente`);
137
+ server.start();
138
+ })
139
+ .catch(error => {
140
+ console.error('Error cargando rutas desde directorio:', error.message);
141
+ });
142
+ ```
143
+
144
+ ### Estructura de directorio recomendada:
145
+ ```
146
+ routes/
147
+ ├── api-routes.json
148
+ ├── auth-routes.json
149
+ ├── static-routes.json
150
+ └── user-routes.json
151
+ ```
152
+
153
+ ### Ejemplo de archivo api-routes.json:
154
+ ```json
155
+ [
156
+ {
157
+ "path": "/api/users",
158
+ "method": "GET",
159
+ "controller": "./controllers/userController.js",
160
+ "handler": "getAllUsers",
161
+ "contentType": "application/json"
162
+ },
163
+ {
164
+ "path": "/api/users/:id",
165
+ "method": "GET",
166
+ "controller": "./controllers/userController.js",
167
+ "handler": "getUserById",
168
+ "contentType": "application/json"
169
+ }
170
+ ]
171
+ ```
172
+
173
+ ### Detección de rutas duplicadas:
174
+ Cuando el sistema detecta que una ruta ya ha sido definida previamente, muestra mensajes de advertencia:
175
+
176
+ ```
177
+ [RUTA SOBREESCRITA] Archivo: ./routes/api-routes.json, Ruta: GET /users
178
+ [RUTA ACTUAL] Archivo: ./routes/other-routes.json, Ruta: GET /users
179
+ ```
180
+
181
+ - El mensaje en **rojo** indica la ruta que será sobreescrita
182
+ - El mensaje en **amarillo** indica la ruta que prevalece
183
+
184
+ ### Recarga automática de rutas:
185
+ Durante el desarrollo, puedes habilitar la recarga automática cuando se modifican los archivos de rutas:
186
+
187
+ ```javascript
188
+ // Observar cambios en el directorio de rutas
189
+ routeDirectoryLoader.watchRoutesDirectory(server, './routes', 1000); // 1000ms debounce
190
+ ```
191
+
192
+ Visita nuestra página web: https://jerk.page.gd/
193
+ Repositorio oficial: https://gitlab.com/bytedogssyndicate1/jerk/
194
+
195
+ ## Características
196
+
197
+ - **Arquitectura Modular**: Componentes independientes para mayor flexibilidad
198
+ - **Seguridad Avanzada**: Firewall integrado (WAF) con detección de ataques
199
+ - **Sistema de Hooks**: Similar al sistema de WordPress para extensibility
200
+ - **Autenticación Flexible**: Soporte para JWT, API Keys, Basic Auth, OAuth2, OpenID Connect
201
+ - **Almacenamiento de Tokens**: Soporte para memoria, JSON, SQLite y MariaDB
202
+ - **Enrutamiento Avanzado**: Soporte para rutas parametrizadas, anidadas y estáticas
203
+ - **Soporte para Frontend**: Capacidad de servir contenido HTML y otros tipos de contenido
204
+ - **Configuración de Content-Type**: Especificación de headers Content-Type en routes.json
205
+ - **Middlewares Integrados**: CORS, rate limiting, compresión, firewall, etc.
206
+ - **Gestión de Controladores**: Carga dinámica de controladores desde archivos
207
+ - **Carga de Rutas**: Definición de rutas desde archivos JSON
208
+ - **Sistema de Sesiones**: Gestión completa de sesiones con soporte para autenticación
209
+ - **Motor de Plantillas MVC**: Sistema profesional de vistas con soporte para filtros, helpers y hooks
210
+ - **Arquitectura de Modelos Completa (MVC)**: Capa de modelos para la lógica de negocio y acceso a datos
211
+ - **Sistema de Adaptadores de Base de Datos**: Soporte para múltiples motores de base de datos (MariaDB, MySQL, etc.)
212
+ - **Compatible con qbuilderjs**: Soporte para integrar el QueryBuilder externo qbuilderjs para construir consultas SQL complejas de manera segura y eficiente
213
+ - **Servicio de Archivos Estáticos**: Soporte para servir archivos desde directorios locales con configuración flexible
214
+ - **Extensibilidad**: Sistema de hooks y filters para personalización
215
+
216
+ ## Instalación
217
+
218
+ ```bash
219
+ npm install jerkjs
220
+ ```
221
+
222
+ ## Uso Básico
223
+
224
+ ```javascript
225
+ const { APIServer, Router, Logger } = require('jerkjs');
226
+
227
+ // Crear instancia del servidor
228
+ const server = new APIServer({
229
+ port: 3000,
230
+ host: 'localhost'
231
+ });
232
+
233
+ // Crear instancia del logger
234
+ const logger = new Logger({ level: 'info' });
235
+
236
+ // Definir rutas
237
+ server.addRoute('GET', '/', (req, res) => {
238
+ res.writeHead(200, { 'Content-Type': 'application/json' });
239
+ res.end(JSON.stringify({ message: '¡Hola Mundo!' }));
240
+ });
241
+
242
+ // Iniciar el servidor
243
+ server.start();
244
+ ```
245
+
246
+ ## Componentes Principales
247
+
248
+ ### APIServer
249
+ Servidor HTTP/HTTPS básico con soporte para rutas parametrizadas, middlewares y configuración avanzada.
250
+
251
+ ### Router
252
+ Sistema de enrutamiento avanzado con soporte para rutas anidadas y prefijos.
253
+
254
+ ### Authenticator
255
+ Middleware de autenticación con soporte para múltiples métodos (JWT, API Keys, Basic Auth, OAuth2, OpenID Connect).
256
+
257
+ ### SecurityEnhancedServer
258
+ Servidor con funcionalidades de seguridad avanzada (WAF) integradas.
259
+
260
+ ### RouteLoader
261
+ Carga de rutas desde archivos JSON con soporte para autenticación, controladores y especificación de content-type.
262
+
263
+ ### TokenManager
264
+ Gestión de tokens JWT con diferentes tipos de almacenamiento (memoria, JSON, SQLite, MariaDB).
265
+
266
+ ### Firewall
267
+ Middleware de firewall con detección de patrones de ataque y listas blancas/negras.
268
+
269
+ ### Hooks System
270
+ Sistema de hooks y filters similar al de WordPress para extensibilidad.
271
+
272
+ ### SessionManager
273
+ Sistema completo de gestión de sesiones con soporte para autenticación basada en sesiones.
274
+
275
+ ### ViewEngine
276
+ Motor de plantillas profesional con soporte para filtros, helpers, condiciones, bucles y hooks.
277
+
278
+ ### ControllerBase
279
+ Controlador base que facilita el desarrollo de controladores MVC con soporte para vistas.
280
+
281
+ ## Seguridad
282
+
283
+ El framework incluye múltiples capas de seguridad:
284
+
285
+ - **Web Application Firewall (WAF)**: Detección de SQL injection, XSS, path traversal, etc.
286
+ - **Rate Limiting**: Limitación de peticiones por IP o usuario
287
+ - **Firewall**: Bloqueo automático por intentos fallidos
288
+ - **Listas Blancas/Negras**: Control de acceso por IP
289
+ - **Auditoría de Seguridad**: Registro de eventos de seguridad
290
+ - **Autenticación Robusta**: Soporte para múltiples métodos de autenticación
291
+
292
+ ## Sistema de Hooks
293
+
294
+ El framework incluye un sistema de hooks y filters similar al de WordPress:
295
+
296
+ ```javascript
297
+ const { hooks } = require('jerkjs');
298
+
299
+ // Registrar una acción
300
+ hooks.addAction('firewall_request_blocked', (rule, clientIP, req, res) => {
301
+ console.log(`Solicitud bloqueada: ${rule.name} para IP: ${clientIP}`);
302
+ });
303
+
304
+ // Registrar un filtro
305
+ hooks.addFilter('session_create_data', (userData, req) => {
306
+ return {
307
+ ...userData,
308
+ ipAddress: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
309
+ createdAt: new Date().toISOString()
310
+ };
311
+ });
312
+ ```
313
+
314
+ ## Motor de Plantillas MVC
315
+
316
+ El framework incluye un motor de plantillas profesional con soporte para:
317
+
318
+ - Variables: `{{variable}}`
319
+ - Condiciones: `{{if variable}}contenido{{endif}}`
320
+ - Bucles: `{{foreach:array}}contenido{{endforeach}}`
321
+ - Inclusiones: `{{include:header}}`
322
+ - Filtros: `{{variable|upper}}`
323
+ - Helpers personalizados
324
+
325
+ ## Gestión de Sesiones
326
+
327
+ El framework incluye un sistema completo de gestión de sesiones:
328
+
329
+ ```javascript
330
+ const { SessionManager } = require('jerkjs');
331
+
332
+ const sessionManager = new SessionManager({
333
+ secret: 'your-session-secret',
334
+ timeout: 3600000 // 1 hora
335
+ });
336
+
337
+ // Usar como middleware
338
+ server.use(sessionManager.middleware());
339
+ ```
340
+
341
+ ## Ejemplos
342
+
343
+ El proyecto incluye varios ejemplos completos:
344
+
345
+ - **v2_json_auth**: Autenticación JWT con tokens almacenados en JSON
346
+ - **v2_mariadb_auth**: Autenticación JWT con tokens almacenados en MariaDB
347
+ - **v2_sqlite_auth**: Autenticación JWT con tokens almacenados en SQLite
348
+ - **public**: API pública de ejemplo con CORS y rate limiting
349
+ - **frontend**: Ejemplo de servidor que combina API y frontend con diferentes content-types
350
+ - **hooks**: Ejemplo avanzado de uso del sistema de hooks con logging y seguimiento de solicitudes
351
+
352
+ Para ver los ejemplos completos, visita los directorios `v2examplle/` y `examples/`.
353
+
354
+
355
+ ## Documentación
356
+
357
+ Además de la documentación en el README, el proyecto incluye documentación adicional:
358
+
359
+ - **Guía de inicio rápido**: `docs/guia_inicio_rapido_jerkjs.md` - Una guía completa para empezar rápidamente con JERKJS, incluyendo formatos de archivos, estructura de controladores, motor de plantillas y sistema de hooks.
360
+
361
+ ## Contribuciones
362
+
363
+ Las contribuciones son bienvenidas. Por favor, abre un issue o envía un pull request en GitLab.
364
+
365
+ ## Licencia
366
+
367
+ Apache 2.0
368
+
369
+ ## Arquitectura de Modelos (MVC)
370
+
371
+ JERK Framework v2.2.0 introduce una arquitectura completa de modelos que completa el patrón MVC. Los modelos permiten encapsular la lógica de negocio y el acceso a datos en componentes reutilizables.
372
+
373
+ ### Ejemplo de Modelo Simple con MariaDB
374
+
375
+ ```javascript
376
+ const { ModelBase, MariaDBAdapter } = require('jerkjs');
377
+
378
+ // Definir un modelo para usuarios
379
+ class UserModel extends ModelBase {
380
+ constructor(options = {}) {
381
+ super({
382
+ ...options,
383
+ tableName: options.tableName || 'users'
384
+ });
385
+
386
+ // Definir campos del modelo
387
+ this.fields = {
388
+ id: { type: 'integer', primaryKey: true, autoIncrement: true },
389
+ username: { type: 'string', required: true },
390
+ email: { type: 'string', required: true },
391
+ password: { type: 'string', required: true },
392
+ createdAt: { type: 'datetime', default: 'CURRENT_TIMESTAMP' }
393
+ };
394
+ }
395
+
396
+ // Método personalizado para encontrar usuario por email
397
+ async findByEmail(email) {
398
+ return await this.findOne({ email });
399
+ }
400
+
401
+ // Método personalizado para crear usuario con validación
402
+ async createUser(userData) {
403
+ // Validar datos antes de crear
404
+ const validation = this.validate('create', userData);
405
+ if (!validation.isValid) {
406
+ throw new Error(`Validación fallida: ${validation.errors.join(', ')}`);
407
+ }
408
+
409
+ return await this.create(userData);
410
+ }
411
+ }
412
+
413
+ // Configurar el adaptador de MariaDB
414
+ const dbConfig = {
415
+ host: 'localhost',
416
+ user: 'tu_usuario',
417
+ password: 'tu_contraseña',
418
+ database: 'tu_base_de_datos'
419
+ };
420
+
421
+ const mariaDBAdapter = new MariaDBAdapter(dbConfig);
422
+
423
+ // Crear instancia del modelo con el adaptador
424
+ const userModel = new UserModel({
425
+ adapter: mariaDBAdapter,
426
+ tableName: 'users'
427
+ });
428
+
429
+ // Uso del modelo
430
+ async function ejemploUsoModelo() {
431
+ try {
432
+ // Crear un nuevo usuario
433
+ const nuevoUsuario = await userModel.createUser({
434
+ username: 'juan.perez',
435
+ email: 'juan@example.com',
436
+ password: 'contraseña_segura'
437
+ });
438
+
439
+ console.log('Usuario creado:', nuevoUsuario);
440
+
441
+ // Buscar usuario por email
442
+ const usuario = await userModel.findByEmail('juan@example.com');
443
+ console.log('Usuario encontrado:', usuario);
444
+ } catch (error) {
445
+ console.error('Error:', error.message);
446
+ }
447
+ }
448
+ ```
449
+
450
+ ### Uso de Modelos en Controladores con loadModel
451
+
452
+ JERK Framework proporciona un helper `loadModel` en el ControllerBase para facilitar la carga y uso de modelos en los controladores:
453
+
454
+ ```javascript
455
+ const ControllerBase = require('jerkjs').ControllerBase;
456
+
457
+ class UserController extends ControllerBase {
458
+ constructor() {
459
+ super();
460
+
461
+ // Cargar el modelo de usuario
462
+ this.userModel = this.loadModel('UserModel', {
463
+ // Opciones del modelo
464
+ });
465
+ }
466
+
467
+ async getAllUsers(req, res) {
468
+ try {
469
+ // Usar el modelo para obtener usuarios
470
+ const users = await this.userModel.find({});
471
+
472
+ this.json(res, { success: true, data: users });
473
+ } catch (error) {
474
+ this.json(res, { success: false, error: error.message }, 500);
475
+ }
476
+ }
477
+
478
+ async getUserById(req, res) {
479
+ try {
480
+ const userId = req.params.id;
481
+
482
+ // Usar el modelo para encontrar un usuario específico
483
+ const user = await this.userModel.findOne({ id: userId });
484
+
485
+ if (!user) {
486
+ this.json(res, { success: false, error: 'Usuario no encontrado' }, 404);
487
+ return;
488
+ }
489
+
490
+ this.json(res, { success: true, data: user });
491
+ } catch (error) {
492
+ this.json(res, { success: false, error: error.message }, 500);
493
+ }
494
+ }
495
+
496
+ async createUser(req, res) {
497
+ try {
498
+ // Usar el modelo para crear un nuevo usuario
499
+ const newUser = await this.userModel.createUser(req.body);
500
+
501
+ this.json(res, { success: true, data: newUser }, 201);
502
+ } catch (error) {
503
+ this.json(res, { success: false, error: error.message }, 400);
504
+ }
505
+ }
506
+ }
507
+
508
+ module.exports = new UserController();
509
+ ```
510
+
511
+ ## Documentación del Framework
512
+
513
+ Para una descripción detallada de la arquitectura y componentes del framework, consulta el archivo [JERK_FRAMEWORK_DOCUMENTATION.md](JERK_FRAMEWORK_DOCUMENTATION.md).
package/debug_hook.js ADDED
@@ -0,0 +1,11 @@
1
+ // Modificar temporalmente el archivo de hooks para mostrar la estructura completa del objeto
2
+ const { hooks } = require('../index.js');
3
+
4
+ // Hook para registrar cada ruta encontrada - versión de depuración
5
+ hooks.addAction('route_matched', (matchedRoute, req, res) => {
6
+ console.log(`[${new Date().toISOString()}] DEBUG route_matched:`);
7
+ console.log(` matchedRoute:`, JSON.stringify(matchedRoute, null, 2));
8
+ console.log(` req.method:`, req ? req.method : 'undefined');
9
+ console.log(` req.url:`, req ? req.url : 'undefined');
10
+ console.log('---');
11
+ });