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.
- package/LICENSE +200 -0
- package/README.md +171 -0
- package/doc/EXTENSION_MANUAL.md +958 -0
- package/doc/FIREWALL_MANUAL.md +419 -0
- package/doc/HOOKS_REFERENCE_IMPROVED.md +599 -0
- package/doc/MANUAL_API_SDK.md +539 -0
- package/doc/MANUAL_MVC.md +397 -0
- package/doc/MARIADB_TOKENS_IMPLEMENTATION.md +113 -0
- package/doc/MIDDLEWARE_MANUAL.md +521 -0
- package/doc/OAUTH2_GOOGLE_MANUAL.md +408 -0
- package/doc/frontend-and-sessions.md +356 -0
- package/examples/advanced/controllers/productController.js +64 -0
- package/examples/advanced/controllers/userController.js +85 -0
- package/examples/advanced/routes.json +51 -0
- package/examples/advanced_example.js +93 -0
- package/examples/basic/controllers/userController.js +85 -0
- package/examples/basic_example.js +72 -0
- package/examples/frontend/README.md +71 -0
- package/examples/frontend/app.js +71 -0
- package/examples/frontend/controllers/apiController.js +39 -0
- package/examples/frontend/controllers/authController.js +220 -0
- package/examples/frontend/controllers/formController.js +47 -0
- package/examples/frontend/controllers/messageController.js +96 -0
- package/examples/frontend/controllers/pageController.js +178 -0
- package/examples/frontend/controllers/staticController.js +167 -0
- package/examples/frontend/routes.json +90 -0
- package/examples/mvc_example/app.js +138 -0
- package/examples/mvc_example/views/home/index.html +26 -0
- package/examples/mvc_example/views/home/simple.html +3 -0
- package/examples/mvc_example/views/layout.html +23 -0
- package/examples/mvc_example/views/test.html +3 -0
- package/examples/mvc_example/views/user/invalid.html +6 -0
- package/examples/mvc_example/views/user/list.html +36 -0
- package/examples/mvc_example/views/user/notfound.html +6 -0
- package/examples/mvc_example/views/user/profile.html +11 -0
- package/examples/mvc_routes_example/app.js +34 -0
- package/examples/mvc_routes_example/controllers/mainController.js +27 -0
- package/examples/mvc_routes_example/controllers/productController.js +47 -0
- package/examples/mvc_routes_example/controllers/userController.js +76 -0
- package/examples/mvc_routes_example/routes.json +30 -0
- package/examples/mvc_routes_example/views/layout.html +31 -0
- package/examples/mvc_routes_example/views/main/index.html +11 -0
- package/examples/mvc_routes_example/views/product/catalog.html +24 -0
- package/examples/mvc_routes_example/views/user/invalid.html +6 -0
- package/examples/mvc_routes_example/views/user/list.html +40 -0
- package/examples/mvc_routes_example/views/user/notfound.html +6 -0
- package/examples/mvc_routes_example/views/user/profile.html +18 -0
- package/examples/public/README.md +92 -0
- package/examples/public/app.js +72 -0
- package/examples/public/controllers/healthController.js +20 -0
- package/examples/public/controllers/mainController.js +22 -0
- package/examples/public/controllers/userController.js +139 -0
- package/examples/public/routes.json +51 -0
- package/examples/v2/README.md +72 -0
- package/examples/v2/app.js +74 -0
- package/examples/v2/app_fixed.js +74 -0
- package/examples/v2/controllers/authController.js +64 -0
- package/examples/v2/controllers/mainController.js +24 -0
- package/examples/v2/controllers/protectedController.js +12 -0
- package/examples/v2/controllers/userController.js +16 -0
- package/examples/v2/package.json +27 -0
- package/examples/v2/routes.json +30 -0
- package/examples/v2/test_api.sh +47 -0
- package/examples/v2/tokens_example.sqlite +0 -0
- package/examples/v2.1_firewall_demo/README.md +113 -0
- package/examples/v2.1_firewall_demo/app.js +182 -0
- package/examples/v2.1_firewall_demo/package.json +27 -0
- package/examples/v2.1_hooks_demo/README.md +85 -0
- package/examples/v2.1_hooks_demo/app.js +101 -0
- package/examples/v2.1_hooks_demo/controllers/hooksController.js +29 -0
- package/examples/v2.1_hooks_demo/controllers/mainController.js +18 -0
- package/examples/v2.1_hooks_demo/package.json +27 -0
- package/examples/v2.1_hooks_demo/routes.json +16 -0
- package/examples/v2.1_openapi_demo/README.md +82 -0
- package/examples/v2.1_openapi_demo/app.js +296 -0
- package/examples/v2.1_openapi_demo/package.json +26 -0
- package/examples/v2_cors/README.md +82 -0
- package/examples/v2_cors/app.js +108 -0
- package/examples/v2_cors/package.json +23 -0
- package/examples/v2_json_auth/README.md +83 -0
- package/examples/v2_json_auth/app.js +72 -0
- package/examples/v2_json_auth/controllers/authController.js +67 -0
- package/examples/v2_json_auth/controllers/mainController.js +16 -0
- package/examples/v2_json_auth/controllers/protectedController.js +12 -0
- package/examples/v2_json_auth/controllers/tokenController.js +28 -0
- package/examples/v2_json_auth/controllers/userController.js +15 -0
- package/examples/v2_json_auth/package.json +26 -0
- package/examples/v2_json_auth/routes.json +37 -0
- package/examples/v2_json_auth/tokens.json +20 -0
- package/examples/v2_mariadb_auth/README.md +94 -0
- package/examples/v2_mariadb_auth/app.js +81 -0
- package/examples/v2_mariadb_auth/controllers/authController.js +95 -0
- package/examples/v2_mariadb_auth/controllers/mainController.js +31 -0
- package/examples/v2_mariadb_auth/controllers/protectedController.js +12 -0
- package/examples/v2_mariadb_auth/controllers/userController.js +17 -0
- package/examples/v2_mariadb_auth/package.json +27 -0
- package/examples/v2_mariadb_auth/routes.json +37 -0
- package/examples/v2_no_auth/README.md +75 -0
- package/examples/v2_no_auth/app.js +72 -0
- package/examples/v2_no_auth/controllers/healthController.js +14 -0
- package/examples/v2_no_auth/controllers/mainController.js +19 -0
- package/examples/v2_no_auth/controllers/productController.js +31 -0
- package/examples/v2_no_auth/controllers/publicController.js +16 -0
- package/examples/v2_no_auth/package.json +22 -0
- package/examples/v2_no_auth/routes.json +37 -0
- package/examples/v2_oauth/README.md +70 -0
- package/examples/v2_oauth/app.js +90 -0
- package/examples/v2_oauth/controllers/mainController.js +45 -0
- package/examples/v2_oauth/controllers/oauthController.js +247 -0
- package/examples/v2_oauth/controllers/protectedController.js +13 -0
- package/examples/v2_oauth/controllers/userController.js +17 -0
- package/examples/v2_oauth/package.json +26 -0
- package/examples/v2_oauth/routes.json +44 -0
- package/examples/v2_openapi/README.md +77 -0
- package/examples/v2_openapi/app.js +222 -0
- package/examples/v2_openapi/controllers/authController.js +52 -0
- package/examples/v2_openapi/controllers/mainController.js +26 -0
- package/examples/v2_openapi/controllers/productController.js +17 -0
- package/examples/v2_openapi/controllers/userController.js +27 -0
- package/examples/v2_openapi/package.json +26 -0
- package/examples/v2_openapi/routes.json +37 -0
- package/generate_token.js +10 -0
- package/index.js +85 -0
- package/jerk.jpg +0 -0
- package/lib/core/handler.js +86 -0
- package/lib/core/hooks.js +224 -0
- package/lib/core/router.js +204 -0
- package/lib/core/securityEnhancedServer.js +752 -0
- package/lib/core/server.js +369 -0
- package/lib/loader/controllerLoader.js +175 -0
- package/lib/loader/routeLoader.js +341 -0
- package/lib/middleware/auditLogger.js +208 -0
- package/lib/middleware/authenticator.js +565 -0
- package/lib/middleware/compressor.js +218 -0
- package/lib/middleware/cors.js +135 -0
- package/lib/middleware/firewall.js +443 -0
- package/lib/middleware/rateLimiter.js +210 -0
- package/lib/middleware/session.js +301 -0
- package/lib/middleware/validator.js +193 -0
- package/lib/mvc/controllerBase.js +207 -0
- package/lib/mvc/viewEngine.js +752 -0
- package/lib/utils/configParser.js +223 -0
- package/lib/utils/logger.js +145 -0
- package/lib/utils/mariadbTokenAdapter.js +226 -0
- package/lib/utils/openapiGenerator.js +140 -0
- package/lib/utils/sqliteTokenAdapter.js +224 -0
- package/lib/utils/tokenManager.js +254 -0
- package/package.json +47 -0
- package/v2examplle/v2_json_auth/README.md +83 -0
- package/v2examplle/v2_json_auth/app.js +72 -0
- package/v2examplle/v2_json_auth/controllers/authController.js +67 -0
- package/v2examplle/v2_json_auth/controllers/mainController.js +16 -0
- package/v2examplle/v2_json_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_json_auth/controllers/tokenController.js +28 -0
- package/v2examplle/v2_json_auth/controllers/userController.js +15 -0
- package/v2examplle/v2_json_auth/package.json +26 -0
- package/v2examplle/v2_json_auth/routes.json +37 -0
- package/v2examplle/v2_json_auth/tokens.json +20 -0
- package/v2examplle/v2_mariadb_auth/README.md +94 -0
- package/v2examplle/v2_mariadb_auth/app.js +81 -0
- package/v2examplle/v2_mariadb_auth/controllers/authController.js +95 -0
- package/v2examplle/v2_mariadb_auth/controllers/mainController.js +31 -0
- package/v2examplle/v2_mariadb_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_mariadb_auth/controllers/userController.js +17 -0
- package/v2examplle/v2_mariadb_auth/package.json +27 -0
- package/v2examplle/v2_mariadb_auth/routes.json +37 -0
- package/v2examplle/v2_sqlite_auth/README.md +72 -0
- package/v2examplle/v2_sqlite_auth/app.js +74 -0
- package/v2examplle/v2_sqlite_auth/app_fixed.js +74 -0
- package/v2examplle/v2_sqlite_auth/controllers/authController.js +64 -0
- package/v2examplle/v2_sqlite_auth/controllers/mainController.js +24 -0
- package/v2examplle/v2_sqlite_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_sqlite_auth/controllers/userController.js +16 -0
- package/v2examplle/v2_sqlite_auth/package.json +27 -0
- package/v2examplle/v2_sqlite_auth/routes.json +30 -0
- package/v2examplle/v2_sqlite_auth/test_api.sh +47 -0
- 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;
|