jerkjs 2.1.7 → 2.2.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/CHANGELOG.md +30 -0
- package/README.md +201 -4
- package/index.js +29 -4
- package/lib/core/server.js +328 -27
- package/lib/loader/routeLoader.js +148 -117
- package/lib/mvc/GenericAdapter.js +136 -0
- package/lib/mvc/MariaDBAdapter.js +315 -0
- package/lib/mvc/MemoryAdapter.js +269 -0
- package/lib/mvc/ModelControllerExample.js +285 -0
- package/lib/mvc/controllerBase.js +60 -0
- package/lib/mvc/modelBase.js +383 -0
- package/lib/mvc/modelManager.js +284 -0
- package/lib/mvc/userModel.js +265 -0
- package/lib/mvc/viewEngine.js +32 -1
- package/lib/utils/mimeType.js +62 -0
- package/package.json +5 -3
- package/BUG_REPORTE_COMPRESION.txt +0 -72
- package/JERK_FRAMEWORK_DIAGRAM.txt +0 -492
- package/JERK_FRAMEWORK_DIAGRAM_MERMAID.mmd +0 -124
- package/JERK_FRAMEWORK_DOCUMENTATION.md +0 -527
- package/LICENSE +0 -201
- package/README_EN.md +0 -230
- package/README_PT.md +0 -230
- package/docs/ARQUITECTURA_ROUTES.md +0 -140
- package/docs/EXTENSION_MANUAL.md +0 -955
- package/docs/FIREWALL_MANUAL.md +0 -416
- package/docs/HOOK-2.0.md +0 -512
- package/docs/HOOKS_REFERENCE_IMPROVED.md +0 -596
- package/docs/MANUAL_API_SDK.md +0 -536
- package/docs/MARIADB_TOKENS_IMPLEMENTATION.md +0 -110
- package/docs/MIDDLEWARE_MANUAL.md +0 -518
- package/docs/OAUTH2_GOOGLE_MANUAL.md +0 -405
- package/docs/ROUTING_WITHOUT_JSON_GUIDE.md +0 -454
- package/docs/frontend-and-sessions.md +0 -353
- package/docs/guia_inicio_rapido_jerkjs.md +0 -113
- package/examples/examples.arj +0 -0
- package/standard/CompressionTestController.js +0 -56
- package/standard/HealthController.js +0 -16
- package/standard/HomeController.js +0 -12
- package/standard/ProductController.js +0 -18
- package/standard/README.md +0 -47
- package/standard/UserController.js +0 -23
- package/standard/package.json +0 -22
- package/standard/routes.json +0 -65
- package/standard/server.js +0 -140
- package/standardA/controllers/AuthController.js +0 -82
- package/standardA/controllers/HomeController.js +0 -19
- package/standardA/controllers/UserController.js +0 -41
- package/standardA/server.js +0 -311
- package/standardA/views/auth/dashboard.html +0 -51
- package/standardA/views/auth/login.html +0 -47
- package/standardA/views/index.html +0 -32
- package/standardA/views/users/detail.html +0 -28
- package/standardA/views/users/list.html +0 -36
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
# Frontend y Sesiones con API SDK JS
|
|
2
|
-
|
|
3
|
-
## Introducción
|
|
4
|
-
|
|
5
|
-
API SDK JS no solo es un framework para crear APIs, sino que ahora también soporta la creación de aplicaciones web completas con frontend y sistema de sesiones. Esta funcionalidad permite a los desarrolladores crear aplicaciones web completas con autenticación basada en sesiones, almacenamiento de datos y mucho más.
|
|
6
|
-
|
|
7
|
-
## Características del Frontend
|
|
8
|
-
|
|
9
|
-
### Especificación de Content-Type en routes.json
|
|
10
|
-
|
|
11
|
-
Una de las nuevas características es la capacidad de especificar el content-type directamente en el archivo routes.json:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
[
|
|
15
|
-
{
|
|
16
|
-
"path": "/",
|
|
17
|
-
"method": "GET",
|
|
18
|
-
"controller": "./controllers/pageController.js",
|
|
19
|
-
"handler": "homePage",
|
|
20
|
-
"auth": "none",
|
|
21
|
-
"contentType": "text/html"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"path": "/api/data",
|
|
25
|
-
"method": "GET",
|
|
26
|
-
"controller": "./controllers/apiController.js",
|
|
27
|
-
"handler": "getData",
|
|
28
|
-
"auth": "none",
|
|
29
|
-
"contentType": "application/json"
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### Soporte para diferentes tipos de contenido
|
|
35
|
-
|
|
36
|
-
El framework ahora puede servir diferentes tipos de contenido:
|
|
37
|
-
- HTML para páginas web
|
|
38
|
-
- CSS para estilos
|
|
39
|
-
- JavaScript para scripts
|
|
40
|
-
- JSON para APIs
|
|
41
|
-
- Y cualquier otro tipo de contenido
|
|
42
|
-
|
|
43
|
-
## Sistema de Sesiones
|
|
44
|
-
|
|
45
|
-
### Configuración
|
|
46
|
-
|
|
47
|
-
Para usar el sistema de sesiones, primero debes configurar el middleware en tu aplicación:
|
|
48
|
-
|
|
49
|
-
```javascript
|
|
50
|
-
const { APIServer, SessionManager, Cors } = require('@apisdkjs/apisdkjs');
|
|
51
|
-
|
|
52
|
-
async function startServer() {
|
|
53
|
-
const server = new APIServer({
|
|
54
|
-
port: 3000,
|
|
55
|
-
host: 'localhost'
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Crear instancia del administrador de sesiones
|
|
59
|
-
const sessionManager = new SessionManager({
|
|
60
|
-
cookieName: 'myapp_session',
|
|
61
|
-
secret: 'my-super-secret-session-key',
|
|
62
|
-
timeout: 3600000 // 1 hora
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Aplicar middleware de sesión
|
|
66
|
-
server.use(sessionManager.middleware());
|
|
67
|
-
|
|
68
|
-
// Hacer que sessionManager esté disponible para el RouteLoader
|
|
69
|
-
server.sessionManager = sessionManager;
|
|
70
|
-
|
|
71
|
-
// Cargar rutas
|
|
72
|
-
const routeLoader = new RouteLoader();
|
|
73
|
-
await routeLoader.loadRoutes(server, './routes.json');
|
|
74
|
-
|
|
75
|
-
server.start();
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Protección de rutas
|
|
80
|
-
|
|
81
|
-
Puedes proteger rutas específicas usando `"auth": "session"` en tu archivo routes.json:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
[
|
|
85
|
-
{
|
|
86
|
-
"path": "/dashboard",
|
|
87
|
-
"method": "GET",
|
|
88
|
-
"controller": "./controllers/dashboardController.js",
|
|
89
|
-
"handler": "showDashboard",
|
|
90
|
-
"auth": "session",
|
|
91
|
-
"contentType": "text/html"
|
|
92
|
-
}
|
|
93
|
-
]
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Uso en controladores
|
|
97
|
-
|
|
98
|
-
En tus controladores, puedes acceder a la sesión a través de `req.session`:
|
|
99
|
-
|
|
100
|
-
```javascript
|
|
101
|
-
const authController = {
|
|
102
|
-
// Controlador para iniciar sesión
|
|
103
|
-
processLogin: async (req, res) => {
|
|
104
|
-
const { username, password } = req.body;
|
|
105
|
-
|
|
106
|
-
// Validar credenciales (tu lógica aquí)
|
|
107
|
-
const user = await validateUser(username, password);
|
|
108
|
-
|
|
109
|
-
if (user) {
|
|
110
|
-
// Crear sesión de usuario autenticado
|
|
111
|
-
req.session.create({
|
|
112
|
-
authenticated: true,
|
|
113
|
-
userId: user.id,
|
|
114
|
-
username: user.username
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
118
|
-
res.end(JSON.stringify({
|
|
119
|
-
success: true,
|
|
120
|
-
message: 'Inicio de sesión exitoso'
|
|
121
|
-
}));
|
|
122
|
-
} else {
|
|
123
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
124
|
-
res.end(JSON.stringify({
|
|
125
|
-
success: false,
|
|
126
|
-
message: 'Credenciales inválidas'
|
|
127
|
-
}));
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
// Controlador para cerrar sesión
|
|
132
|
-
processLogout: (req, res) => {
|
|
133
|
-
if (req.session) {
|
|
134
|
-
req.session.destroy();
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
138
|
-
res.end(JSON.stringify({
|
|
139
|
-
success: true,
|
|
140
|
-
message: 'Sesión cerrada exitosamente'
|
|
141
|
-
}));
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Sistema de Hooks, Filters y Actions
|
|
147
|
-
|
|
148
|
-
El sistema de sesiones está completamente integrado con el sistema de hooks, filters y actions del framework, lo que permite extender y personalizar su comportamiento.
|
|
149
|
-
|
|
150
|
-
### Hooks Disponibles
|
|
151
|
-
|
|
152
|
-
#### Sesion Creation Hooks
|
|
153
|
-
- `session_create_data`: Filtra los datos antes de crear una sesión
|
|
154
|
-
- `session_created`: Acción disparada después de crear una sesión
|
|
155
|
-
- `session_create_user_data`: Filtra los datos de usuario antes de crear la sesión
|
|
156
|
-
|
|
157
|
-
#### Sesion Retrieval Hooks
|
|
158
|
-
- `session_get_id`: Filtra el ID de sesión antes de buscarla
|
|
159
|
-
- `session_retrieved`: Acción disparada después de obtener una sesión
|
|
160
|
-
- `session_not_found`: Acción disparada cuando no se encuentra una sesión
|
|
161
|
-
- `session_expired`: Acción disparada cuando una sesión ha expirado
|
|
162
|
-
|
|
163
|
-
#### Sesion Update Hooks
|
|
164
|
-
- `session_update_data`: Filtra los nuevos datos antes de actualizar la sesión
|
|
165
|
-
- `session_updated`: Acción disparada después de actualizar una sesión
|
|
166
|
-
- `session_update_user_data`: Filtra los datos de usuario antes de actualizar
|
|
167
|
-
|
|
168
|
-
#### Sesion Destruction Hooks
|
|
169
|
-
- `session_destroy_before`: Acción disparada antes de destruir una sesión
|
|
170
|
-
- `session_destroyed`: Acción disparada después de destruir una sesión
|
|
171
|
-
- `session_destroy_failed`: Acción disparada cuando falla la destrucción
|
|
172
|
-
|
|
173
|
-
#### Middleware Hooks
|
|
174
|
-
- `session_middleware_before`: Acción disparada antes del middleware de sesión
|
|
175
|
-
- `session_middleware_after`: Acción disparada después del middleware de sesión
|
|
176
|
-
|
|
177
|
-
#### Authentication Hooks
|
|
178
|
-
- `session_auth_check_before`: Acción disparada antes de verificar autenticación
|
|
179
|
-
- `session_auth_success`: Acción disparada cuando la autenticación es exitosa
|
|
180
|
-
- `session_auth_failed`: Acción disparada cuando la autenticación falla
|
|
181
|
-
- `session_created_response`: Acción disparada después de crear sesión en respuesta
|
|
182
|
-
- `session_updated_response`: Acción disparada después de actualizar sesión en respuesta
|
|
183
|
-
- `session_destroyed_response`: Acción disparada después de destruir sesión en respuesta
|
|
184
|
-
|
|
185
|
-
### Ejemplos de Uso de Hooks
|
|
186
|
-
|
|
187
|
-
#### Registrar actividad de sesión
|
|
188
|
-
|
|
189
|
-
```javascript
|
|
190
|
-
const { hooks } = require('@apisdkjs/apisdkjs');
|
|
191
|
-
|
|
192
|
-
// Registrar cuando se crea una sesión
|
|
193
|
-
hooks.addAction('session_created', (sessionId, sessionData) => {
|
|
194
|
-
console.log(`Sesión creada: ${sessionId} para el usuario: ${sessionData.username}`);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
// Registrar cuando se destruye una sesión
|
|
198
|
-
hooks.addAction('session_destroyed', (sessionId, sessionData) => {
|
|
199
|
-
console.log(`Sesión destruida: ${sessionId} para el usuario: ${sessionData.username}`);
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
#### Modificar datos de sesión antes de crearla
|
|
204
|
-
|
|
205
|
-
```javascript
|
|
206
|
-
const { hooks } = require('@apisdkjs/apisdkjs');
|
|
207
|
-
|
|
208
|
-
// Añadir información de IP y fecha a los datos de sesión
|
|
209
|
-
hooks.addFilter('session_create_data', (userData, req) => {
|
|
210
|
-
return {
|
|
211
|
-
...userData,
|
|
212
|
-
ipAddress: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
|
|
213
|
-
createdAt: new Date().toISOString()
|
|
214
|
-
};
|
|
215
|
-
});
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
#### Personalizar el manejo de autenticación fallida
|
|
219
|
-
|
|
220
|
-
```javascript
|
|
221
|
-
const { hooks } = require('@apisdkjs/apisdkjs');
|
|
222
|
-
|
|
223
|
-
// Registrar intentos de acceso no autorizado
|
|
224
|
-
hooks.addAction('session_auth_failed', (req, res, redirectTo) => {
|
|
225
|
-
console.log(`Intento de acceso no autorizado a: ${req.url} desde IP: ${req.connection.remoteAddress}`);
|
|
226
|
-
|
|
227
|
-
// Puedes personalizar la respuesta aquí
|
|
228
|
-
if (req.headers.accept && req.headers.accept.includes('application/json')) {
|
|
229
|
-
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
230
|
-
res.end(JSON.stringify({ error: 'No autorizado', code: 'AUTH_REQUIRED' }));
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
#### Extender datos de sesión durante la actualización
|
|
236
|
-
|
|
237
|
-
```javascript
|
|
238
|
-
const { hooks } = require('@apisdkjs/apisdkjs');
|
|
239
|
-
|
|
240
|
-
// Añadir marca de tiempo a cada actualización de sesión
|
|
241
|
-
hooks.addFilter('session_update_data', (newData, req, sessionId) => {
|
|
242
|
-
return {
|
|
243
|
-
...newData,
|
|
244
|
-
lastUpdated: new Date().toISOString(),
|
|
245
|
-
lastActivity: new Date().toISOString()
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Ejemplo Completo
|
|
251
|
-
|
|
252
|
-
Aquí tienes un ejemplo completo de una aplicación que combina frontend y sesiones:
|
|
253
|
-
|
|
254
|
-
### app.js
|
|
255
|
-
```javascript
|
|
256
|
-
const {
|
|
257
|
-
APIServer,
|
|
258
|
-
RouteLoader,
|
|
259
|
-
Logger,
|
|
260
|
-
Cors,
|
|
261
|
-
SessionManager
|
|
262
|
-
} = require('@apisdkjs/apisdkjs');
|
|
263
|
-
|
|
264
|
-
async function startServer() {
|
|
265
|
-
const server = new APIServer({
|
|
266
|
-
port: 3000,
|
|
267
|
-
host: 'localhost'
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
const logger = new Logger({ level: 'info' });
|
|
271
|
-
|
|
272
|
-
try {
|
|
273
|
-
// Configurar sesiones
|
|
274
|
-
const sessionManager = new SessionManager({
|
|
275
|
-
cookieName: 'myapp_session',
|
|
276
|
-
secret: 'my-super-secret-session-key',
|
|
277
|
-
timeout: 3600000
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
server.use(sessionManager.middleware());
|
|
281
|
-
server.sessionManager = sessionManager;
|
|
282
|
-
|
|
283
|
-
// Configurar CORS
|
|
284
|
-
const cors = new Cors({
|
|
285
|
-
origin: '*',
|
|
286
|
-
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
287
|
-
allowedHeaders: ['Content-Type', 'Authorization']
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
server.use(cors.middleware());
|
|
291
|
-
|
|
292
|
-
// Cargar rutas
|
|
293
|
-
const routeLoader = new RouteLoader();
|
|
294
|
-
await routeLoader.loadRoutes(server, './routes.json');
|
|
295
|
-
|
|
296
|
-
server.start();
|
|
297
|
-
logger.info('Servidor iniciado en http://localhost:3000');
|
|
298
|
-
} catch (error) {
|
|
299
|
-
logger.error('Error iniciando el servidor:', error.message);
|
|
300
|
-
process.exit(1);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
startServer();
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### routes.json
|
|
308
|
-
```json
|
|
309
|
-
[
|
|
310
|
-
{
|
|
311
|
-
"path": "/",
|
|
312
|
-
"method": "GET",
|
|
313
|
-
"controller": "./controllers/pageController.js",
|
|
314
|
-
"handler": "homePage",
|
|
315
|
-
"auth": "none",
|
|
316
|
-
"contentType": "text/html"
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
"path": "/login",
|
|
320
|
-
"method": "GET",
|
|
321
|
-
"controller": "./controllers/authController.js",
|
|
322
|
-
"handler": "showLoginPage",
|
|
323
|
-
"auth": "none",
|
|
324
|
-
"contentType": "text/html"
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
"path": "/dashboard",
|
|
328
|
-
"method": "GET",
|
|
329
|
-
"controller": "./controllers/dashboardController.js",
|
|
330
|
-
"handler": "showDashboard",
|
|
331
|
-
"auth": "session",
|
|
332
|
-
"contentType": "text/html"
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
"path": "/api/login",
|
|
336
|
-
"method": "POST",
|
|
337
|
-
"controller": "./controllers/authController.js",
|
|
338
|
-
"handler": "processLogin",
|
|
339
|
-
"auth": "none",
|
|
340
|
-
"contentType": "application/json"
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
"path": "/api/logout",
|
|
344
|
-
"method": "POST",
|
|
345
|
-
"controller": "./controllers/authController.js",
|
|
346
|
-
"handler": "processLogout",
|
|
347
|
-
"auth": "session",
|
|
348
|
-
"contentType": "application/json"
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
Este ejemplo demuestra cómo crear una aplicación web completa con autenticación basada en sesiones, protección de rutas y soporte para frontend HTML.
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Documentación de Aprendizajes con JERKJS
|
|
2
|
-
|
|
3
|
-
## 1. Formato del archivo routes.json
|
|
4
|
-
|
|
5
|
-
**Formato correcto:**
|
|
6
|
-
```json
|
|
7
|
-
[
|
|
8
|
-
{
|
|
9
|
-
"method": "GET",
|
|
10
|
-
"path": "/",
|
|
11
|
-
"controller": "./controllers/mainController.js",
|
|
12
|
-
"handler": "home",
|
|
13
|
-
"auth": "none"
|
|
14
|
-
}
|
|
15
|
-
]
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
**Características importantes:**
|
|
19
|
-
- Debe ser un array directo de rutas, **NO** un objeto con propiedad "routes"
|
|
20
|
-
- Campos requeridos: `method`, `path`, `controller`, `handler`, `auth`
|
|
21
|
-
- El campo `controller` debe especificar la ruta completa al archivo del controlador
|
|
22
|
-
- El campo `handler` debe especificar el nombre exacto del método en el controlador
|
|
23
|
-
- El campo `auth` puede ser "none", "required", etc.
|
|
24
|
-
|
|
25
|
-
## 2. Estructura de controladores para usar con routes.json
|
|
26
|
-
|
|
27
|
-
**Formato correcto:**
|
|
28
|
-
```javascript
|
|
29
|
-
const { ControllerBase } = require('jerkjs');
|
|
30
|
-
|
|
31
|
-
class MainController extends ControllerBase {
|
|
32
|
-
constructor(options = {}) {
|
|
33
|
-
super(options);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
home(req, res) {
|
|
37
|
-
// Lógica del controlador
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Exportar métodos directamente para que el RouteLoader pueda acceder a ellos
|
|
42
|
-
const controllerInstance = new MainController({ viewsPath: './views' });
|
|
43
|
-
|
|
44
|
-
module.exports = {
|
|
45
|
-
home: (req, res) => {
|
|
46
|
-
controllerInstance.setRequestResponse(req, res);
|
|
47
|
-
controllerInstance.home(req, res);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**Características importantes:**
|
|
53
|
-
- No se puede exportar directamente la instancia del controlador
|
|
54
|
-
- Debe exportar un objeto con funciones que encapsulan la llamada al método del controlador
|
|
55
|
-
- Se debe llamar a `setRequestResponse()` antes de ejecutar el método del controlador
|
|
56
|
-
|
|
57
|
-
## 3. Uso del motor de plantillas de JERK
|
|
58
|
-
|
|
59
|
-
**Características del motor de plantillas:**
|
|
60
|
-
- Usa sintaxis `{{variable}}` para mostrar variables
|
|
61
|
-
- Soporta condicionales: `{{if variable}}contenido{{endif}}`
|
|
62
|
-
- Soporta bucles: `{{foreach:array}}contenido{{endforeach}}`
|
|
63
|
-
- Se accede a los elementos del bucle con `{{item.property}}`
|
|
64
|
-
|
|
65
|
-
## 4. Sistema de hooks
|
|
66
|
-
|
|
67
|
-
**Tipos de hooks:**
|
|
68
|
-
- `addAction(nombre_hook, callback)` - Para acciones que se ejecutan en puntos específicos
|
|
69
|
-
- `addFilter(nombre_hook, callback)` - Para filtrar/modificar datos
|
|
70
|
-
|
|
71
|
-
**Hooks útiles:**
|
|
72
|
-
- `post_controller_load` - Se ejecuta después de cargar un controlador
|
|
73
|
-
- `pre_route_load` - Se ejecuta antes de cargar rutas
|
|
74
|
-
- `post_route_load` - Se ejecuta después de cargar rutas
|
|
75
|
-
- `request_received` - Se ejecuta cuando se recibe una solicitud
|
|
76
|
-
- `request_completed` - Se ejecuta cuando se completa una solicitud
|
|
77
|
-
|
|
78
|
-
## 5. Puerto y configuración del servidor
|
|
79
|
-
|
|
80
|
-
**Configuración del servidor:**
|
|
81
|
-
```javascript
|
|
82
|
-
const server = new APIServer({
|
|
83
|
-
port: 11000, // Puerto específico
|
|
84
|
-
host: 'localhost'
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## 6. Controladores que extienden ControllerBase
|
|
89
|
-
|
|
90
|
-
**Características:**
|
|
91
|
-
- Deben extender `ControllerBase` del framework
|
|
92
|
-
- Usan `this.set()` para establecer variables de vista
|
|
93
|
-
- Usan `this.render()` para renderizar vistas
|
|
94
|
-
- Requieren que se llame a `setRequestResponse()` antes de usar métodos del controlador
|
|
95
|
-
|
|
96
|
-
## 7. Errores comunes y soluciones
|
|
97
|
-
|
|
98
|
-
**Error común:** "this.set is not a function"
|
|
99
|
-
**Solución:** Asegurarse de que se llama a `controllerInstance.setRequestResponse(req, res)` antes de ejecutar métodos del controlador
|
|
100
|
-
|
|
101
|
-
**Error común:** "Error cargando rutas desde ./routes.json: El archivo de rutas debe contener un array de rutas"
|
|
102
|
-
**Solución:** Asegurarse de que routes.json sea un array directo, no un objeto con propiedad "routes"
|
|
103
|
-
|
|
104
|
-
**Error común:** "controllerLoader.loadControllers is not a function"
|
|
105
|
-
**Solución:** El RouteLoader se encarga de cargar tanto rutas como controladores, no usar ControllerLoader por separado
|
|
106
|
-
|
|
107
|
-
## 8. Recursos útiles
|
|
108
|
-
|
|
109
|
-
- Directorio de ejemplos en `/node_modules/jerkjs/examples/`
|
|
110
|
-
- Archivos routes.json de ejemplo en los directorios de ejemplos
|
|
111
|
-
- Documentación en el README del paquete
|
|
112
|
-
|
|
113
|
-
Esta documentación servirá para futuros desarrollos con JERKJS y evitará caer en los mismos errores o confusiones.
|
package/examples/examples.arj
DELETED
|
Binary file
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador para probar compresión
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
class CompressionTestController {
|
|
6
|
-
// Endpoint que devuelve datos grandes para probar compresión
|
|
7
|
-
getLargeData(req, res) {
|
|
8
|
-
// Crear un objeto grande con datos repetidos
|
|
9
|
-
const largeData = {
|
|
10
|
-
message: 'Datos grandes para probar compresión',
|
|
11
|
-
timestamp: new Date().toISOString(),
|
|
12
|
-
data: []
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// Agregar muchos elementos para aumentar el tamaño
|
|
16
|
-
for (let i = 0; i < 1000; i++) {
|
|
17
|
-
largeData.data.push({
|
|
18
|
-
id: i,
|
|
19
|
-
title: `Elemento ${i}`,
|
|
20
|
-
description: `Esta es una descripción larga para el elemento ${i} que ayuda a aumentar el tamaño de la respuesta`,
|
|
21
|
-
metadata: {
|
|
22
|
-
created: new Date().toISOString(),
|
|
23
|
-
tags: [`tag-${i % 10}`, `category-${i % 5}`],
|
|
24
|
-
properties: {
|
|
25
|
-
prop1: `value-${i}`,
|
|
26
|
-
prop2: `another-value-${i}`,
|
|
27
|
-
prop3: `third-value-${i}`
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
34
|
-
res.end(JSON.stringify(largeData));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Nuevo endpoint para probar hooks de compresión
|
|
38
|
-
testCompressionHooks(req, res) {
|
|
39
|
-
// Datos para probar los hooks
|
|
40
|
-
const testData = {
|
|
41
|
-
message: 'Prueba de hooks de compresión',
|
|
42
|
-
hooksTest: true,
|
|
43
|
-
timestamp: new Date().toISOString(),
|
|
44
|
-
data: Array.from({ length: 500 }, (_, i) => ({
|
|
45
|
-
id: i,
|
|
46
|
-
testValue: `Valor de prueba ${i}`,
|
|
47
|
-
description: `Este es un elemento de prueba para verificar que los hooks de compresión funcionan correctamente`
|
|
48
|
-
}))
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
52
|
-
res.end(JSON.stringify(testData));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
module.exports = new CompressionTestController();
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador de salud del sistema
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
class HealthController {
|
|
6
|
-
checkHealth(req, res) {
|
|
7
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
8
|
-
res.end(JSON.stringify({
|
|
9
|
-
status: 'healthy',
|
|
10
|
-
timestamp: new Date().toISOString(),
|
|
11
|
-
uptime: process.uptime()
|
|
12
|
-
}));
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
module.exports = new HealthController();
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador de ejemplo para la ruta raíz
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
class HomeController {
|
|
6
|
-
index(req, res) {
|
|
7
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
8
|
-
res.end('<h1>Bienvenido al servidor estándar de JERK</h1>');
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
module.exports = new HomeController();
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador de productos
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
class ProductController {
|
|
6
|
-
getAllProducts(req, res) {
|
|
7
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
8
|
-
res.end(JSON.stringify({ products: [] }));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
getProductById(req, res) {
|
|
12
|
-
const productId = req.params.id;
|
|
13
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
14
|
-
res.end(JSON.stringify({ id: productId, name: `Producto ${productId}` }));
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = new ProductController();
|
package/standard/README.md
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Servidor Estándar JERK
|
|
2
|
-
|
|
3
|
-
Este es el servidor estándar para JERK Framework v2.1. Implementa todas las características del framework y carga rutas desde un archivo `routes.json`.
|
|
4
|
-
|
|
5
|
-
## Características
|
|
6
|
-
|
|
7
|
-
- Carga de rutas desde `routes.json`
|
|
8
|
-
- Puerto configurable mediante variable de entorno `PORT`
|
|
9
|
-
- Todas las características del framework habilitadas:
|
|
10
|
-
- Autenticación (JWT, API Key, Basic, OAuth2, OIDC)
|
|
11
|
-
- CORS
|
|
12
|
-
- Rate Limiting
|
|
13
|
-
- Compresión
|
|
14
|
-
- Firewall
|
|
15
|
-
- Sesiones
|
|
16
|
-
- Sistema de Hooks/Filters
|
|
17
|
-
- MVC (Modelo-Vista-Controlador)
|
|
18
|
-
- Motor de plantillas
|
|
19
|
-
- Manejo de errores
|
|
20
|
-
|
|
21
|
-
## Variables de Entorno
|
|
22
|
-
|
|
23
|
-
- `PORT`: Puerto en el que escuchará el servidor (por defecto: 3000)
|
|
24
|
-
- `HOST`: Host en el que escuchará el servidor (por defecto: localhost)
|
|
25
|
-
- `USE_HTTPS`: Habilitar HTTPS (por defecto: false)
|
|
26
|
-
- `HTTPS_KEY_PATH`: Ruta al archivo de clave privada para HTTPS
|
|
27
|
-
- `HTTPS_CERT_PATH`: Ruta al archivo de certificado para HTTPS
|
|
28
|
-
- `REQUEST_TIMEOUT`: Timeout para solicitudes en milisegundos (por defecto: 120000)
|
|
29
|
-
- `CONNECTION_TIMEOUT`: Timeout para conexiones en milisegundos (por defecto: 120000)
|
|
30
|
-
- `MAX_BODY_SIZE`: Tamaño máximo del cuerpo de la solicitud en bytes (por defecto: 10MB)
|
|
31
|
-
|
|
32
|
-
## Uso
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# Instalar dependencias
|
|
36
|
-
npm install
|
|
37
|
-
|
|
38
|
-
# Iniciar el servidor
|
|
39
|
-
npm start
|
|
40
|
-
|
|
41
|
-
# Iniciar el servidor en modo desarrollo con puerto diferente
|
|
42
|
-
npm run dev
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Rutas
|
|
46
|
-
|
|
47
|
-
Las rutas se definen en el archivo `routes.json` y se cargan automáticamente al iniciar el servidor. El servidor mostrará las rutas y características cargadas al iniciar mediante el sistema de hooks.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Controlador de usuarios
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
class UserController {
|
|
6
|
-
getAllUsers(req, res) {
|
|
7
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
8
|
-
res.end(JSON.stringify({ users: [] }));
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
getUserById(req, res) {
|
|
12
|
-
const userId = req.params.id;
|
|
13
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
14
|
-
res.end(JSON.stringify({ id: userId, name: `Usuario ${userId}` }));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
createUser(req, res) {
|
|
18
|
-
res.writeHead(201, { 'Content-Type': 'application/json' });
|
|
19
|
-
res.end(JSON.stringify({ message: 'Usuario creado', data: req.body }));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
module.exports = new UserController();
|
package/standard/package.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "jerk-standard-server",
|
|
3
|
-
"version": "2.1.0",
|
|
4
|
-
"description": "Servidor estándar para JERK Framework v2.1",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"start": "node server.js",
|
|
8
|
-
"dev": "PORT=3001 node server.js"
|
|
9
|
-
},
|
|
10
|
-
"keywords": [
|
|
11
|
-
"jerk",
|
|
12
|
-
"framework",
|
|
13
|
-
"api",
|
|
14
|
-
"server",
|
|
15
|
-
"standard"
|
|
16
|
-
],
|
|
17
|
-
"author": "JERK Framework Team",
|
|
18
|
-
"license": "Apache-2.0",
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"jerkjs": "file:.."
|
|
21
|
-
}
|
|
22
|
-
}
|