jerkjs 2.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.
Files changed (177) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +171 -0
  3. package/doc/EXTENSION_MANUAL.md +958 -0
  4. package/doc/FIREWALL_MANUAL.md +419 -0
  5. package/doc/HOOKS_REFERENCE_IMPROVED.md +599 -0
  6. package/doc/MANUAL_API_SDK.md +539 -0
  7. package/doc/MANUAL_MVC.md +397 -0
  8. package/doc/MARIADB_TOKENS_IMPLEMENTATION.md +113 -0
  9. package/doc/MIDDLEWARE_MANUAL.md +521 -0
  10. package/doc/OAUTH2_GOOGLE_MANUAL.md +408 -0
  11. package/doc/frontend-and-sessions.md +356 -0
  12. package/examples/advanced/controllers/productController.js +64 -0
  13. package/examples/advanced/controllers/userController.js +85 -0
  14. package/examples/advanced/routes.json +51 -0
  15. package/examples/advanced_example.js +93 -0
  16. package/examples/basic/controllers/userController.js +85 -0
  17. package/examples/basic_example.js +72 -0
  18. package/examples/frontend/README.md +71 -0
  19. package/examples/frontend/app.js +71 -0
  20. package/examples/frontend/controllers/apiController.js +39 -0
  21. package/examples/frontend/controllers/authController.js +220 -0
  22. package/examples/frontend/controllers/formController.js +47 -0
  23. package/examples/frontend/controllers/messageController.js +96 -0
  24. package/examples/frontend/controllers/pageController.js +178 -0
  25. package/examples/frontend/controllers/staticController.js +167 -0
  26. package/examples/frontend/routes.json +90 -0
  27. package/examples/mvc_example/app.js +138 -0
  28. package/examples/mvc_example/views/home/index.html +26 -0
  29. package/examples/mvc_example/views/home/simple.html +3 -0
  30. package/examples/mvc_example/views/layout.html +23 -0
  31. package/examples/mvc_example/views/test.html +3 -0
  32. package/examples/mvc_example/views/user/invalid.html +6 -0
  33. package/examples/mvc_example/views/user/list.html +36 -0
  34. package/examples/mvc_example/views/user/notfound.html +6 -0
  35. package/examples/mvc_example/views/user/profile.html +11 -0
  36. package/examples/mvc_routes_example/app.js +34 -0
  37. package/examples/mvc_routes_example/controllers/mainController.js +27 -0
  38. package/examples/mvc_routes_example/controllers/productController.js +47 -0
  39. package/examples/mvc_routes_example/controllers/userController.js +76 -0
  40. package/examples/mvc_routes_example/routes.json +30 -0
  41. package/examples/mvc_routes_example/views/layout.html +31 -0
  42. package/examples/mvc_routes_example/views/main/index.html +11 -0
  43. package/examples/mvc_routes_example/views/product/catalog.html +24 -0
  44. package/examples/mvc_routes_example/views/user/invalid.html +6 -0
  45. package/examples/mvc_routes_example/views/user/list.html +40 -0
  46. package/examples/mvc_routes_example/views/user/notfound.html +6 -0
  47. package/examples/mvc_routes_example/views/user/profile.html +18 -0
  48. package/examples/public/README.md +92 -0
  49. package/examples/public/app.js +72 -0
  50. package/examples/public/controllers/healthController.js +20 -0
  51. package/examples/public/controllers/mainController.js +22 -0
  52. package/examples/public/controllers/userController.js +139 -0
  53. package/examples/public/routes.json +51 -0
  54. package/examples/v2/README.md +72 -0
  55. package/examples/v2/app.js +74 -0
  56. package/examples/v2/app_fixed.js +74 -0
  57. package/examples/v2/controllers/authController.js +64 -0
  58. package/examples/v2/controllers/mainController.js +24 -0
  59. package/examples/v2/controllers/protectedController.js +12 -0
  60. package/examples/v2/controllers/userController.js +16 -0
  61. package/examples/v2/package.json +27 -0
  62. package/examples/v2/routes.json +30 -0
  63. package/examples/v2/test_api.sh +47 -0
  64. package/examples/v2/tokens_example.sqlite +0 -0
  65. package/examples/v2.1_firewall_demo/README.md +113 -0
  66. package/examples/v2.1_firewall_demo/app.js +182 -0
  67. package/examples/v2.1_firewall_demo/package.json +27 -0
  68. package/examples/v2.1_hooks_demo/README.md +85 -0
  69. package/examples/v2.1_hooks_demo/app.js +101 -0
  70. package/examples/v2.1_hooks_demo/controllers/hooksController.js +29 -0
  71. package/examples/v2.1_hooks_demo/controllers/mainController.js +18 -0
  72. package/examples/v2.1_hooks_demo/package.json +27 -0
  73. package/examples/v2.1_hooks_demo/routes.json +16 -0
  74. package/examples/v2.1_openapi_demo/README.md +82 -0
  75. package/examples/v2.1_openapi_demo/app.js +296 -0
  76. package/examples/v2.1_openapi_demo/package.json +26 -0
  77. package/examples/v2_cors/README.md +82 -0
  78. package/examples/v2_cors/app.js +108 -0
  79. package/examples/v2_cors/package.json +23 -0
  80. package/examples/v2_json_auth/README.md +83 -0
  81. package/examples/v2_json_auth/app.js +72 -0
  82. package/examples/v2_json_auth/controllers/authController.js +67 -0
  83. package/examples/v2_json_auth/controllers/mainController.js +16 -0
  84. package/examples/v2_json_auth/controllers/protectedController.js +12 -0
  85. package/examples/v2_json_auth/controllers/tokenController.js +28 -0
  86. package/examples/v2_json_auth/controllers/userController.js +15 -0
  87. package/examples/v2_json_auth/package.json +26 -0
  88. package/examples/v2_json_auth/routes.json +37 -0
  89. package/examples/v2_json_auth/tokens.json +20 -0
  90. package/examples/v2_mariadb_auth/README.md +94 -0
  91. package/examples/v2_mariadb_auth/app.js +81 -0
  92. package/examples/v2_mariadb_auth/controllers/authController.js +95 -0
  93. package/examples/v2_mariadb_auth/controllers/mainController.js +31 -0
  94. package/examples/v2_mariadb_auth/controllers/protectedController.js +12 -0
  95. package/examples/v2_mariadb_auth/controllers/userController.js +17 -0
  96. package/examples/v2_mariadb_auth/package.json +27 -0
  97. package/examples/v2_mariadb_auth/routes.json +37 -0
  98. package/examples/v2_no_auth/README.md +75 -0
  99. package/examples/v2_no_auth/app.js +72 -0
  100. package/examples/v2_no_auth/controllers/healthController.js +14 -0
  101. package/examples/v2_no_auth/controllers/mainController.js +19 -0
  102. package/examples/v2_no_auth/controllers/productController.js +31 -0
  103. package/examples/v2_no_auth/controllers/publicController.js +16 -0
  104. package/examples/v2_no_auth/package.json +22 -0
  105. package/examples/v2_no_auth/routes.json +37 -0
  106. package/examples/v2_oauth/README.md +70 -0
  107. package/examples/v2_oauth/app.js +90 -0
  108. package/examples/v2_oauth/controllers/mainController.js +45 -0
  109. package/examples/v2_oauth/controllers/oauthController.js +247 -0
  110. package/examples/v2_oauth/controllers/protectedController.js +13 -0
  111. package/examples/v2_oauth/controllers/userController.js +17 -0
  112. package/examples/v2_oauth/package.json +26 -0
  113. package/examples/v2_oauth/routes.json +44 -0
  114. package/examples/v2_openapi/README.md +77 -0
  115. package/examples/v2_openapi/app.js +222 -0
  116. package/examples/v2_openapi/controllers/authController.js +52 -0
  117. package/examples/v2_openapi/controllers/mainController.js +26 -0
  118. package/examples/v2_openapi/controllers/productController.js +17 -0
  119. package/examples/v2_openapi/controllers/userController.js +27 -0
  120. package/examples/v2_openapi/package.json +26 -0
  121. package/examples/v2_openapi/routes.json +37 -0
  122. package/generate_token.js +10 -0
  123. package/index.js +85 -0
  124. package/jerk.jpg +0 -0
  125. package/lib/core/handler.js +86 -0
  126. package/lib/core/hooks.js +224 -0
  127. package/lib/core/router.js +204 -0
  128. package/lib/core/securityEnhancedServer.js +752 -0
  129. package/lib/core/server.js +369 -0
  130. package/lib/loader/controllerLoader.js +175 -0
  131. package/lib/loader/routeLoader.js +341 -0
  132. package/lib/middleware/auditLogger.js +208 -0
  133. package/lib/middleware/authenticator.js +565 -0
  134. package/lib/middleware/compressor.js +218 -0
  135. package/lib/middleware/cors.js +135 -0
  136. package/lib/middleware/firewall.js +443 -0
  137. package/lib/middleware/rateLimiter.js +210 -0
  138. package/lib/middleware/session.js +301 -0
  139. package/lib/middleware/validator.js +193 -0
  140. package/lib/mvc/controllerBase.js +207 -0
  141. package/lib/mvc/viewEngine.js +752 -0
  142. package/lib/utils/configParser.js +223 -0
  143. package/lib/utils/logger.js +145 -0
  144. package/lib/utils/mariadbTokenAdapter.js +226 -0
  145. package/lib/utils/openapiGenerator.js +140 -0
  146. package/lib/utils/sqliteTokenAdapter.js +224 -0
  147. package/lib/utils/tokenManager.js +254 -0
  148. package/package.json +47 -0
  149. package/v2examplle/v2_json_auth/README.md +83 -0
  150. package/v2examplle/v2_json_auth/app.js +72 -0
  151. package/v2examplle/v2_json_auth/controllers/authController.js +67 -0
  152. package/v2examplle/v2_json_auth/controllers/mainController.js +16 -0
  153. package/v2examplle/v2_json_auth/controllers/protectedController.js +12 -0
  154. package/v2examplle/v2_json_auth/controllers/tokenController.js +28 -0
  155. package/v2examplle/v2_json_auth/controllers/userController.js +15 -0
  156. package/v2examplle/v2_json_auth/package.json +26 -0
  157. package/v2examplle/v2_json_auth/routes.json +37 -0
  158. package/v2examplle/v2_json_auth/tokens.json +20 -0
  159. package/v2examplle/v2_mariadb_auth/README.md +94 -0
  160. package/v2examplle/v2_mariadb_auth/app.js +81 -0
  161. package/v2examplle/v2_mariadb_auth/controllers/authController.js +95 -0
  162. package/v2examplle/v2_mariadb_auth/controllers/mainController.js +31 -0
  163. package/v2examplle/v2_mariadb_auth/controllers/protectedController.js +12 -0
  164. package/v2examplle/v2_mariadb_auth/controllers/userController.js +17 -0
  165. package/v2examplle/v2_mariadb_auth/package.json +27 -0
  166. package/v2examplle/v2_mariadb_auth/routes.json +37 -0
  167. package/v2examplle/v2_sqlite_auth/README.md +72 -0
  168. package/v2examplle/v2_sqlite_auth/app.js +74 -0
  169. package/v2examplle/v2_sqlite_auth/app_fixed.js +74 -0
  170. package/v2examplle/v2_sqlite_auth/controllers/authController.js +64 -0
  171. package/v2examplle/v2_sqlite_auth/controllers/mainController.js +24 -0
  172. package/v2examplle/v2_sqlite_auth/controllers/protectedController.js +12 -0
  173. package/v2examplle/v2_sqlite_auth/controllers/userController.js +16 -0
  174. package/v2examplle/v2_sqlite_auth/package.json +27 -0
  175. package/v2examplle/v2_sqlite_auth/routes.json +30 -0
  176. package/v2examplle/v2_sqlite_auth/test_api.sh +47 -0
  177. package/v2examplle/v2_sqlite_auth/tokens_example.sqlite +0 -0
@@ -0,0 +1,52 @@
1
+ const jwt = require('jsonwebtoken');
2
+ const { TokenManager } = require('../../../index.js');
3
+
4
+ // TokenManager para este controlador
5
+ const tokenManager = new TokenManager({
6
+ storage: 'memory'
7
+ });
8
+
9
+ const authController = {
10
+ login: async (req, res) => {
11
+ try {
12
+ const { username, password } = req.body;
13
+
14
+ // Validación simple de credenciales (esto debería ser más robusto en producción)
15
+ if (!username || !password) {
16
+ res.writeHead(400, { 'Content-Type': 'application/json' });
17
+ res.end(JSON.stringify({ error: 'Nombre de usuario y contraseña requeridos' }));
18
+ return;
19
+ }
20
+
21
+ // Simulación de autenticación (en una aplicación real, esto verificaría contra una base de datos)
22
+ if (username === 'admin' && password === 'password') {
23
+ // Generar un token JWT
24
+ const payload = {
25
+ userId: 1,
26
+ username: username,
27
+ role: 'admin'
28
+ };
29
+
30
+ // Secret para firmar el token (en producción, debería estar en variables de entorno)
31
+ const secret = 'super-secret-key-for-openapi-example';
32
+ const token = jwt.sign(payload, secret, { expiresIn: '1h' });
33
+
34
+ res.writeHead(200, { 'Content-Type': 'application/json' });
35
+ res.end(JSON.stringify({
36
+ message: 'Inicio de sesión exitoso',
37
+ token: token,
38
+ user: payload
39
+ }));
40
+ } else {
41
+ res.writeHead(401, { 'Content-Type': 'application/json' });
42
+ res.end(JSON.stringify({ error: 'Credenciales inválidas' }));
43
+ }
44
+ } catch (error) {
45
+ console.error('Error en login:', error);
46
+ res.writeHead(500, { 'Content-Type': 'application/json' });
47
+ res.end(JSON.stringify({ error: 'Error interno del servidor' }));
48
+ }
49
+ }
50
+ };
51
+
52
+ module.exports = authController;
@@ -0,0 +1,26 @@
1
+ const jwt = require('jsonwebtoken');
2
+ const { TokenManager } = require('../../../index.js');
3
+
4
+ // TokenManager para este controlador
5
+ const tokenManager = new TokenManager({
6
+ storage: 'memory'
7
+ });
8
+
9
+ const mainController = {
10
+ home: (req, res) => {
11
+ res.writeHead(200, { 'Content-Type': 'application/json' });
12
+ res.end(JSON.stringify({
13
+ message: 'Bienvenido a la API de ejemplo con funcionalidad OpenAPI',
14
+ endpoints: {
15
+ 'POST /login': 'Iniciar sesión y obtener token',
16
+ 'GET /users': 'Obtener lista de usuarios (requiere token)',
17
+ 'GET /products': 'Obtener lista de productos (requiere token)',
18
+ 'GET /profile': 'Obtener perfil de usuario (requiere token)',
19
+ 'GET /docs': 'Documentación interactiva OpenAPI/Swagger',
20
+ 'GET /openapi.json': 'Especificación OpenAPI'
21
+ }
22
+ }));
23
+ }
24
+ };
25
+
26
+ module.exports = mainController;
@@ -0,0 +1,17 @@
1
+ // Datos de ejemplo de productos
2
+ const products = [
3
+ { id: 1, name: 'Laptop', price: 999.99, category: 'Electronics' },
4
+ { id: 2, name: 'Mouse', price: 29.99, category: 'Electronics' },
5
+ { id: 3, name: 'Keyboard', price: 79.99, category: 'Electronics' },
6
+ { id: 4, name: 'Monitor', price: 299.99, category: 'Electronics' },
7
+ { id: 5, name: 'Webcam', price: 89.99, category: 'Electronics' }
8
+ ];
9
+
10
+ const productController = {
11
+ getProducts: (req, res) => {
12
+ res.writeHead(200, { 'Content-Type': 'application/json' });
13
+ res.end(JSON.stringify(products));
14
+ }
15
+ };
16
+
17
+ module.exports = productController;
@@ -0,0 +1,27 @@
1
+ // Datos de ejemplo de usuarios
2
+ const users = [
3
+ { id: 1, name: 'John Doe', email: 'john@example.com', role: 'admin' },
4
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'user' },
5
+ { id: 3, name: 'Robert Johnson', email: 'robert@example.com', role: 'user' }
6
+ ];
7
+
8
+ const userController = {
9
+ getUsers: (req, res) => {
10
+ res.writeHead(200, { 'Content-Type': 'application/json' });
11
+ res.end(JSON.stringify(users));
12
+ },
13
+
14
+ getProfile: (req, res) => {
15
+ res.writeHead(200, { 'Content-Type': 'application/json' });
16
+ res.end(JSON.stringify({
17
+ profile: {
18
+ id: req.user.userId,
19
+ username: req.user.username || 'Usuario',
20
+ role: req.user.role || 'guest'
21
+ },
22
+ message: 'Perfil de usuario obtenido exitosamente'
23
+ }));
24
+ }
25
+ };
26
+
27
+ module.exports = userController;
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "api-sdk-openapi-example",
3
+ "version": "1.0.0",
4
+ "description": "Ejemplo de API con funcionalidad OpenAPI usando el Framework API SDK",
5
+ "main": "app.js",
6
+ "scripts": {
7
+ "start": "node app.js",
8
+ "dev": "nodemon app.js"
9
+ },
10
+ "keywords": [
11
+ "api",
12
+ "sdk",
13
+ "openapi",
14
+ "swagger",
15
+ "documentation",
16
+ "framework"
17
+ ],
18
+ "author": "API SDK Framework",
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "jsonwebtoken": "^9.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "nodemon": "^3.0.0"
25
+ }
26
+ }
@@ -0,0 +1,37 @@
1
+ [
2
+ {
3
+ "path": "/",
4
+ "method": "GET",
5
+ "controller": "./controllers/mainController.js",
6
+ "handler": "home",
7
+ "auth": "none"
8
+ },
9
+ {
10
+ "path": "/login",
11
+ "method": "POST",
12
+ "controller": "./controllers/authController.js",
13
+ "handler": "login",
14
+ "auth": "none"
15
+ },
16
+ {
17
+ "path": "/users",
18
+ "method": "GET",
19
+ "controller": "./controllers/userController.js",
20
+ "handler": "getUsers",
21
+ "auth": "jwt-openapi"
22
+ },
23
+ {
24
+ "path": "/products",
25
+ "method": "GET",
26
+ "controller": "./controllers/productController.js",
27
+ "handler": "getProducts",
28
+ "auth": "jwt-openapi"
29
+ },
30
+ {
31
+ "path": "/profile",
32
+ "method": "GET",
33
+ "controller": "./controllers/userController.js",
34
+ "handler": "getProfile",
35
+ "auth": "jwt-openapi"
36
+ }
37
+ ]
@@ -0,0 +1,10 @@
1
+ const jwt = require('jsonwebtoken');
2
+
3
+ // Generar un token JWT de prueba
4
+ const payload = { userId: 1, username: 'testuser', role: 'user' };
5
+ const secret = 'secret-jwt-key';
6
+
7
+ const token = jwt.sign(payload, secret, { expiresIn: '1h' });
8
+
9
+ console.log('Token JWT generado:');
10
+ console.log(token);
package/index.js ADDED
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Punto de entrada del framework API SDK
3
+ * API SDK Framework v2.0
4
+ */
5
+
6
+ const APIServer = require('./lib/core/server');
7
+ const Router = require('./lib/core/router');
8
+ const HandlerManager = require('./lib/core/handler');
9
+ const Authenticator = require('./lib/middleware/authenticator');
10
+ const Validator = require('./lib/middleware/validator');
11
+ const RouteLoader = require('./lib/loader/routeLoader');
12
+ const ControllerLoader = require('./lib/loader/controllerLoader');
13
+ const ConfigParser = require('./lib/utils/configParser');
14
+ const { Logger } = require('./lib/utils/logger');
15
+
16
+ // Componentes adicionales de la versión 2.0
17
+ const Cors = require('./lib/middleware/cors');
18
+ const RateLimiter = require('./lib/middleware/rateLimiter');
19
+ const Compressor = require('./lib/middleware/compressor');
20
+ const TokenManager = require('./lib/utils/tokenManager');
21
+ const MariaDBTokenAdapter = require('./lib/utils/mariadbTokenAdapter');
22
+ const SQLiteTokenAdapter = require('./lib/utils/sqliteTokenAdapter');
23
+ const AuditLogger = require('./lib/middleware/auditLogger');
24
+ const OpenApiGenerator = require('./lib/utils/openapiGenerator');
25
+
26
+ const HookSystem = require('./lib/core/hooks');
27
+
28
+ // Importar componentes adicionales
29
+ const SecurityEnhancedServer = require('./lib/core/securityEnhancedServer');
30
+ const Firewall = require('./lib/middleware/firewall');
31
+ const { SessionManager, sessionAuth } = require('./lib/middleware/session');
32
+
33
+ // Componentes MVC
34
+ const ViewEngine = require('./lib/mvc/viewEngine');
35
+ const ControllerBase = require('./lib/mvc/controllerBase');
36
+
37
+ // Exportar todos los componentes del framework
38
+ module.exports = {
39
+ // Componentes fundamentales (v1.0)
40
+ APIServer,
41
+ Router,
42
+ HandlerManager,
43
+ Authenticator,
44
+ Validator,
45
+ RouteLoader,
46
+ ControllerLoader,
47
+ ConfigParser,
48
+ Logger,
49
+
50
+ // Componentes de seguridad y rendimiento (v2.0)
51
+ Cors,
52
+ RateLimiter,
53
+ Compressor,
54
+
55
+ // Componentes de utilidad (v2.0)
56
+ TokenManager,
57
+ MariaDBTokenAdapter,
58
+ SQLiteTokenAdapter,
59
+ AuditLogger,
60
+ OpenApiGenerator,
61
+
62
+ // Sistema de hooks para extensibilidad
63
+ HookSystem,
64
+
65
+ // Componentes de seguridad avanzada (v2.1.0)
66
+ SecurityEnhancedServer,
67
+ Firewall,
68
+
69
+ // Componentes de sesión (v2.2.0)
70
+ SessionManager,
71
+ sessionAuth,
72
+
73
+ // Componentes MVC (v2.3.0)
74
+ ViewEngine,
75
+ ControllerBase
76
+ };
77
+
78
+ // También exportar clases individuales por conveniencia
79
+ module.exports.APISDK = APIServer;
80
+
81
+ // Crear instancia global del sistema de hooks
82
+ module.exports.hooks = new HookSystem();
83
+
84
+ // Disparar hooks de inicio del framework
85
+ module.exports.hooks.doAction('framework_init');
package/jerk.jpg ADDED
Binary file
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Gestión de handlers para el framework API SDK
3
+ * Implementación del componente core/handler.js
4
+ */
5
+
6
+ class HandlerManager {
7
+ /**
8
+ * Constructor del gestor de handlers
9
+ */
10
+ constructor() {
11
+ this.handlers = new Map();
12
+ }
13
+
14
+ /**
15
+ * Método para registrar un handler
16
+ * @param {string} name - Nombre del handler
17
+ * @param {Function} handler - Función handler
18
+ */
19
+ register(name, handler) {
20
+ this.handlers.set(name, handler);
21
+ }
22
+
23
+ /**
24
+ * Método para obtener un handler registrado
25
+ * @param {string} name - Nombre del handler
26
+ * @returns {Function|null} - Función handler o null si no existe
27
+ */
28
+ get(name) {
29
+ return this.handlers.get(name) || null;
30
+ }
31
+
32
+ /**
33
+ * Método para ejecutar un handler
34
+ * @param {string} name - Nombre del handler
35
+ * @param {Object} req - Objeto de solicitud HTTP
36
+ * @param {Object} res - Objeto de respuesta HTTP
37
+ * @returns {*} - Resultado de la ejecución del handler
38
+ */
39
+ async execute(name, req, res) {
40
+ const handler = this.get(name);
41
+ if (!handler) {
42
+ throw new Error(`Handler '${name}' no encontrado`);
43
+ }
44
+
45
+ // Verificar si el handler es una función asíncrona o no
46
+ if (handler.constructor.name === 'AsyncFunction') {
47
+ return await handler(req, res);
48
+ } else {
49
+ return handler(req, res);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Método para eliminar un handler
55
+ * @param {string} name - Nombre del handler
56
+ */
57
+ remove(name) {
58
+ this.handlers.delete(name);
59
+ }
60
+
61
+ /**
62
+ * Método para limpiar todos los handlers
63
+ */
64
+ clear() {
65
+ this.handlers.clear();
66
+ }
67
+
68
+ /**
69
+ * Método para verificar si un handler existe
70
+ * @param {string} name - Nombre del handler
71
+ * @returns {boolean} - True si existe, false en caso contrario
72
+ */
73
+ has(name) {
74
+ return this.handlers.has(name);
75
+ }
76
+
77
+ /**
78
+ * Método para obtener todos los nombres de handlers
79
+ * @returns {Array} - Array con los nombres de todos los handlers
80
+ */
81
+ getAllNames() {
82
+ return Array.from(this.handlers.keys());
83
+ }
84
+ }
85
+
86
+ module.exports = HandlerManager;
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Sistema de Hooks y Filters como el core de WordPress
3
+ * Implementación para el Framework API SDK
4
+ */
5
+
6
+ class HookSystem {
7
+ constructor() {
8
+ // Almacenar acciones registradas
9
+ this.actions = new Map();
10
+ // Almacenar filtros registrados
11
+ this.filters = new Map();
12
+ }
13
+
14
+ /**
15
+ * Registra una acción
16
+ * @param {string} hookName - Nombre del hook
17
+ * @param {Function} callback - Función a ejecutar
18
+ * @param {number} priority - Prioridad (más bajo se ejecuta primero)
19
+ * @param {number} acceptedArgs - Número de argumentos aceptados
20
+ */
21
+ addAction(hookName, callback, priority = 10, acceptedArgs = 1) {
22
+ if (!this.actions.has(hookName)) {
23
+ this.actions.set(hookName, []);
24
+ }
25
+
26
+ const hookList = this.actions.get(hookName);
27
+ hookList.push({
28
+ callback,
29
+ priority,
30
+ acceptedArgs,
31
+ id: Date.now() + Math.random() // ID único para identificar el hook
32
+ });
33
+
34
+ // Ordenar por prioridad
35
+ hookList.sort((a, b) => a.priority - b.priority);
36
+ }
37
+
38
+ /**
39
+ * Registra un filtro
40
+ * @param {string} hookName - Nombre del hook
41
+ * @param {Function} callback - Función a ejecutar
42
+ * @param {number} priority - Prioridad (más bajo se ejecuta primero)
43
+ * @param {number} acceptedArgs - Número de argumentos aceptados
44
+ */
45
+ addFilter(hookName, callback, priority = 10, acceptedArgs = 1) {
46
+ if (!this.filters.has(hookName)) {
47
+ this.filters.set(hookName, []);
48
+ }
49
+
50
+ const hookList = this.filters.get(hookName);
51
+ hookList.push({
52
+ callback,
53
+ priority,
54
+ acceptedArgs,
55
+ id: Date.now() + Math.random() // ID único para identificar el hook
56
+ });
57
+
58
+ // Ordenar por prioridad
59
+ hookList.sort((a, b) => a.priority - b.priority);
60
+ }
61
+
62
+ /**
63
+ * Ejecuta una acción
64
+ * @param {string} hookName - Nombre del hook
65
+ * @param {...any} args - Argumentos a pasar a los callbacks
66
+ */
67
+ doAction(hookName, ...args) {
68
+ const hooks = this.actions.get(hookName);
69
+ if (!hooks || hooks.length === 0) {
70
+ return;
71
+ }
72
+
73
+ for (const hook of hooks) {
74
+ // Limitar argumentos según acceptedArgs
75
+ const callArgs = args.slice(0, hook.acceptedArgs);
76
+ hook.callback(...callArgs);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Aplica un filtro
82
+ * @param {string} hookName - Nombre del hook
83
+ * @param {any} value - Valor a filtrar
84
+ * @param {...any} additionalArgs - Argumentos adicionales
85
+ * @returns {any} - Valor filtrado
86
+ */
87
+ applyFilters(hookName, value, ...additionalArgs) {
88
+ const hooks = this.filters.get(hookName);
89
+ if (!hooks || hooks.length === 0) {
90
+ return value;
91
+ }
92
+
93
+ let filteredValue = value;
94
+ for (const hook of hooks) {
95
+ // El primer argumento es el valor a filtrar, luego los adicionales
96
+ const callArgs = [filteredValue, ...additionalArgs.slice(0, hook.acceptedArgs - 1)];
97
+ filteredValue = hook.callback(...callArgs);
98
+ }
99
+
100
+ return filteredValue;
101
+ }
102
+
103
+ /**
104
+ * Verifica si una acción tiene callbacks registrados
105
+ * @param {string} hookName - Nombre del hook
106
+ * @returns {boolean} - True si tiene callbacks registrados
107
+ */
108
+ hasAction(hookName) {
109
+ const hooks = this.actions.get(hookName);
110
+ return !!hooks && hooks.length > 0;
111
+ }
112
+
113
+ /**
114
+ * Verifica si un filtro tiene callbacks registrados
115
+ * @param {string} hookName - Nombre del hook
116
+ * @returns {boolean} - True si tiene callbacks registrados
117
+ */
118
+ hasFilter(hookName) {
119
+ const hooks = this.filters.get(hookName);
120
+ return !!hooks && hooks.length > 0;
121
+ }
122
+
123
+ /**
124
+ * Elimina una acción específica
125
+ * @param {string} hookName - Nombre del hook
126
+ * @param {Function} callback - Callback a eliminar
127
+ * @param {number} priority - Prioridad del callback
128
+ * @returns {boolean} - True si se eliminó correctamente
129
+ */
130
+ removeAction(hookName, callback, priority = 10) {
131
+ const hooks = this.actions.get(hookName);
132
+ if (!hooks) {
133
+ return false;
134
+ }
135
+
136
+ const initialLength = hooks.length;
137
+ const filteredHooks = hooks.filter(hook =>
138
+ !(hook.callback === callback && hook.priority === priority)
139
+ );
140
+
141
+ if (filteredHooks.length !== initialLength) {
142
+ this.actions.set(hookName, filteredHooks);
143
+ return true;
144
+ }
145
+
146
+ return false;
147
+ }
148
+
149
+ /**
150
+ * Elimina un filtro específico
151
+ * @param {string} hookName - Nombre del hook
152
+ * @param {Function} callback - Callback a eliminar
153
+ * @param {number} priority - Prioridad del callback
154
+ * @returns {boolean} - True si se eliminó correctamente
155
+ */
156
+ removeFilter(hookName, callback, priority = 10) {
157
+ const hooks = this.filters.get(hookName);
158
+ if (!hooks) {
159
+ return false;
160
+ }
161
+
162
+ const initialLength = hooks.length;
163
+ const filteredHooks = hooks.filter(hook =>
164
+ !(hook.callback === callback && hook.priority === priority)
165
+ );
166
+
167
+ if (filteredHooks.length !== initialLength) {
168
+ this.filters.set(hookName, filteredHooks);
169
+ return true;
170
+ }
171
+
172
+ return false;
173
+ }
174
+
175
+ /**
176
+ * Elimina todas las acciones de un hook
177
+ * @param {string} hookName - Nombre del hook
178
+ * @returns {boolean} - True si se eliminaron correctamente
179
+ */
180
+ removeAllActions(hookName) {
181
+ if (!hookName) {
182
+ this.actions.clear();
183
+ return true;
184
+ }
185
+
186
+ return this.actions.delete(hookName);
187
+ }
188
+
189
+ /**
190
+ * Elimina todos los filtros de un hook
191
+ * @param {string} hookName - Nombre del hook
192
+ * @returns {boolean} - True si se eliminaron correctamente
193
+ */
194
+ removeAllFilters(hookName) {
195
+ if (!hookName) {
196
+ this.filters.clear();
197
+ return true;
198
+ }
199
+
200
+ return this.filters.delete(hookName);
201
+ }
202
+
203
+ /**
204
+ * Obtiene el número de callbacks registrados para una acción
205
+ * @param {string} hookName - Nombre del hook
206
+ * @returns {number} - Número de callbacks
207
+ */
208
+ actionsCount(hookName) {
209
+ const hooks = this.actions.get(hookName);
210
+ return hooks ? hooks.length : 0;
211
+ }
212
+
213
+ /**
214
+ * Obtiene el número de callbacks registrados para un filtro
215
+ * @param {string} hookName - Nombre del hook
216
+ * @returns {number} - Número de callbacks
217
+ */
218
+ filtersCount(hookName) {
219
+ const hooks = this.filters.get(hookName);
220
+ return hooks ? hooks.length : 0;
221
+ }
222
+ }
223
+
224
+ module.exports = HookSystem;