jerkjs 2.1.6 → 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.
Files changed (54) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +202 -5
  3. package/index.js +29 -4
  4. package/lib/core/server.js +328 -27
  5. package/lib/loader/routeLoader.js +148 -117
  6. package/lib/middleware/compressor.js +87 -18
  7. package/lib/mvc/GenericAdapter.js +136 -0
  8. package/lib/mvc/MariaDBAdapter.js +315 -0
  9. package/lib/mvc/MemoryAdapter.js +269 -0
  10. package/lib/mvc/ModelControllerExample.js +285 -0
  11. package/lib/mvc/controllerBase.js +60 -0
  12. package/lib/mvc/modelBase.js +383 -0
  13. package/lib/mvc/modelManager.js +284 -0
  14. package/lib/mvc/userModel.js +265 -0
  15. package/lib/mvc/viewEngine.js +32 -1
  16. package/lib/utils/mimeType.js +62 -0
  17. package/package.json +5 -3
  18. package/JERK_FRAMEWORK_DIAGRAM.txt +0 -492
  19. package/JERK_FRAMEWORK_DIAGRAM_MERMAID.mmd +0 -124
  20. package/JERK_FRAMEWORK_DOCUMENTATION.md +0 -527
  21. package/LICENSE +0 -201
  22. package/README_EN.md +0 -230
  23. package/README_PT.md +0 -230
  24. package/docs/ARQUITECTURA_ROUTES.md +0 -140
  25. package/docs/EXTENSION_MANUAL.md +0 -955
  26. package/docs/FIREWALL_MANUAL.md +0 -416
  27. package/docs/HOOK-2.0.md +0 -512
  28. package/docs/HOOKS_REFERENCE_IMPROVED.md +0 -596
  29. package/docs/MANUAL_API_SDK.md +0 -536
  30. package/docs/MARIADB_TOKENS_IMPLEMENTATION.md +0 -110
  31. package/docs/MIDDLEWARE_MANUAL.md +0 -518
  32. package/docs/OAUTH2_GOOGLE_MANUAL.md +0 -405
  33. package/docs/ROUTING_WITHOUT_JSON_GUIDE.md +0 -454
  34. package/docs/frontend-and-sessions.md +0 -353
  35. package/docs/guia_inicio_rapido_jerkjs.md +0 -113
  36. package/examples/examples.arj +0 -0
  37. package/standard/CompressionTestController.js +0 -56
  38. package/standard/HealthController.js +0 -16
  39. package/standard/HomeController.js +0 -12
  40. package/standard/ProductController.js +0 -18
  41. package/standard/README.md +0 -47
  42. package/standard/UserController.js +0 -23
  43. package/standard/package.json +0 -22
  44. package/standard/routes.json +0 -65
  45. package/standard/server.js +0 -140
  46. package/standardA/controllers/AuthController.js +0 -82
  47. package/standardA/controllers/HomeController.js +0 -19
  48. package/standardA/controllers/UserController.js +0 -41
  49. package/standardA/server.js +0 -311
  50. package/standardA/views/auth/dashboard.html +0 -51
  51. package/standardA/views/auth/login.html +0 -47
  52. package/standardA/views/index.html +0 -32
  53. package/standardA/views/users/detail.html +0 -28
  54. package/standardA/views/users/list.html +0 -36
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Controlador de ejemplo que demuestra la interacción con modelos en el framework JERK
3
+ * Implementación del componente MVC ModelControllerExample.js
4
+ * Muestra cómo los controladores pueden interactuar con modelos
5
+ */
6
+
7
+ const ControllerBase = require('./controllerBase');
8
+
9
+ // Importar componentes dinámicamente para evitar dependencias circulares
10
+ let _ModelManager, _UserModel, _MemoryAdapter;
11
+
12
+ const loadComponents = () => {
13
+ if (!_ModelManager || !_UserModel || !_MemoryAdapter) {
14
+ const components = require('../../index.js');
15
+ _ModelManager = components.ModelManager;
16
+ _UserModel = components.UserModel;
17
+ _MemoryAdapter = components.MemoryAdapter;
18
+ }
19
+ return { _ModelManager, _UserModel, _MemoryAdapter };
20
+ };
21
+
22
+ class ModelControllerExample extends ControllerBase {
23
+ constructor() {
24
+ super();
25
+
26
+ // Cargar componentes dinámicamente
27
+ const { _ModelManager, _MemoryAdapter } = loadComponents();
28
+
29
+ // Crear instancia del gestor de modelos
30
+ this.modelManager = new _ModelManager();
31
+
32
+ // Crear e registrar un adaptador de memoria
33
+ const memoryAdapter = new _MemoryAdapter();
34
+ this.modelManager.registerAdapter('memory', memoryAdapter);
35
+
36
+ // Crear e registrar el modelo de usuario
37
+ this.userModel = this.modelManager.createModel('User', {
38
+ adapterName: 'memory',
39
+ modelOptions: { tableName: 'users' }
40
+ });
41
+
42
+ // Asociar el modelo con este controlador para comunicación bidireccional
43
+ this.modelManager.associateModelWithController('User', this);
44
+ }
45
+
46
+ /**
47
+ * Método para obtener todos los usuarios
48
+ * @param {Object} req - Objeto de solicitud
49
+ * @param {Object} res - Objeto de respuesta
50
+ */
51
+ async getAllUsers(req, res) {
52
+ try {
53
+ const users = await this.userModel.find({});
54
+
55
+ res.writeHead(200, { 'Content-Type': 'application/json' });
56
+ res.end(JSON.stringify({
57
+ success: true,
58
+ data: users,
59
+ count: users.length
60
+ }));
61
+ } catch (error) {
62
+ console.error('Error obteniendo usuarios:', error);
63
+ res.writeHead(500, { 'Content-Type': 'application/json' });
64
+ res.end(JSON.stringify({
65
+ success: false,
66
+ error: error.message
67
+ }));
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Método para obtener un usuario por ID
73
+ * @param {Object} req - Objeto de solicitud
74
+ * @param {Object} res - Objeto de respuesta
75
+ */
76
+ async getUserById(req, res) {
77
+ try {
78
+ const userId = req.params.id;
79
+
80
+ if (!userId) {
81
+ res.writeHead(400, { 'Content-Type': 'application/json' });
82
+ res.end(JSON.stringify({
83
+ success: false,
84
+ error: 'ID de usuario es requerido'
85
+ }));
86
+ return;
87
+ }
88
+
89
+ const user = await this.userModel.findOne({ id: parseInt(userId) });
90
+
91
+ if (!user) {
92
+ res.writeHead(404, { 'Content-Type': 'application/json' });
93
+ res.end(JSON.stringify({
94
+ success: false,
95
+ error: 'Usuario no encontrado'
96
+ }));
97
+ return;
98
+ }
99
+
100
+ res.writeHead(200, { 'Content-Type': 'application/json' });
101
+ res.end(JSON.stringify({
102
+ success: true,
103
+ data: user
104
+ }));
105
+ } catch (error) {
106
+ console.error('Error obteniendo usuario por ID:', error);
107
+ res.writeHead(500, { 'Content-Type': 'application/json' });
108
+ res.end(JSON.stringify({
109
+ success: false,
110
+ error: error.message
111
+ }));
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Método para crear un nuevo usuario
117
+ * @param {Object} req - Objeto de solicitud
118
+ * @param {Object} res - Objeto de respuesta
119
+ */
120
+ async createUser(req, res) {
121
+ try {
122
+ const userData = req.body;
123
+
124
+ // Validar que se proporcionen los datos necesarios
125
+ if (!userData.username || !userData.email || !userData.password) {
126
+ res.writeHead(400, { 'Content-Type': 'application/json' });
127
+ res.end(JSON.stringify({
128
+ success: false,
129
+ error: 'Username, email y password son requeridos'
130
+ }));
131
+ return;
132
+ }
133
+
134
+ // Crear el usuario usando el modelo
135
+ const newUser = await this.userModel.createUser(userData);
136
+
137
+ res.writeHead(201, { 'Content-Type': 'application/json' });
138
+ res.end(JSON.stringify({
139
+ success: true,
140
+ data: newUser
141
+ }));
142
+ } catch (error) {
143
+ console.error('Error creando usuario:', error);
144
+ res.writeHead(500, { 'Content-Type': 'application/json' });
145
+ res.end(JSON.stringify({
146
+ success: false,
147
+ error: error.message
148
+ }));
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Método para actualizar un usuario
154
+ * @param {Object} req - Objeto de solicitud
155
+ * @param {Object} res - Objeto de respuesta
156
+ */
157
+ async updateUser(req, res) {
158
+ try {
159
+ const userId = req.params.id;
160
+ const userData = req.body;
161
+
162
+ if (!userId) {
163
+ res.writeHead(400, { 'Content-Type': 'application/json' });
164
+ res.end(JSON.stringify({
165
+ success: false,
166
+ error: 'ID de usuario es requerido'
167
+ }));
168
+ return;
169
+ }
170
+
171
+ // Actualizar el usuario usando el modelo
172
+ const affectedRows = await this.userModel.updateUser({ id: parseInt(userId) }, userData);
173
+
174
+ if (affectedRows === 0) {
175
+ res.writeHead(404, { 'Content-Type': 'application/json' });
176
+ res.end(JSON.stringify({
177
+ success: false,
178
+ error: 'Usuario no encontrado'
179
+ }));
180
+ return;
181
+ }
182
+
183
+ res.writeHead(200, { 'Content-Type': 'application/json' });
184
+ res.end(JSON.stringify({
185
+ success: true,
186
+ message: 'Usuario actualizado exitosamente',
187
+ affectedRows
188
+ }));
189
+ } catch (error) {
190
+ console.error('Error actualizando usuario:', error);
191
+ res.writeHead(500, { 'Content-Type': 'application/json' });
192
+ res.end(JSON.stringify({
193
+ success: false,
194
+ error: error.message
195
+ }));
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Método para eliminar un usuario
201
+ * @param {Object} req - Objeto de solicitud
202
+ * @param {Object} res - Objeto de respuesta
203
+ */
204
+ async deleteUser(req, res) {
205
+ try {
206
+ const userId = req.params.id;
207
+
208
+ if (!userId) {
209
+ res.writeHead(400, { 'Content-Type': 'application/json' });
210
+ res.end(JSON.stringify({
211
+ success: false,
212
+ error: 'ID de usuario es requerido'
213
+ }));
214
+ return;
215
+ }
216
+
217
+ // Eliminar el usuario usando el modelo
218
+ const deletedRows = await this.userModel.delete({ id: parseInt(userId) });
219
+
220
+ if (deletedRows === 0) {
221
+ res.writeHead(404, { 'Content-Type': 'application/json' });
222
+ res.end(JSON.stringify({
223
+ success: false,
224
+ error: 'Usuario no encontrado'
225
+ }));
226
+ return;
227
+ }
228
+
229
+ res.writeHead(200, { 'Content-Type': 'application/json' });
230
+ res.end(JSON.stringify({
231
+ success: true,
232
+ message: 'Usuario eliminado exitosamente',
233
+ deletedRows
234
+ }));
235
+ } catch (error) {
236
+ console.error('Error eliminando usuario:', error);
237
+ res.writeHead(500, { 'Content-Type': 'application/json' });
238
+ res.end(JSON.stringify({
239
+ success: false,
240
+ error: error.message
241
+ }));
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Método para obtener usuarios con paginación
247
+ * @param {Object} req - Objeto de solicitud
248
+ * @param {Object} res - Objeto de respuesta
249
+ */
250
+ async getUsersPaginated(req, res) {
251
+ try {
252
+ // Obtener parámetros de paginación de la consulta
253
+ const page = parseInt(req.query.page) || 1;
254
+ const limit = parseInt(req.query.limit) || 10;
255
+
256
+ // Validar parámetros
257
+ if (page < 1 || limit < 1 || limit > 100) {
258
+ res.writeHead(400, { 'Content-Type': 'application/json' });
259
+ res.end(JSON.stringify({
260
+ success: false,
261
+ error: 'Parámetros de paginación inválidos'
262
+ }));
263
+ return;
264
+ }
265
+
266
+ // Obtener usuarios con paginación usando el modelo
267
+ const result = await this.userModel.getUsersPaginated({ page, limit });
268
+
269
+ res.writeHead(200, { 'Content-Type': 'application/json' });
270
+ res.end(JSON.stringify({
271
+ success: true,
272
+ ...result
273
+ }));
274
+ } catch (error) {
275
+ console.error('Error obteniendo usuarios paginados:', error);
276
+ res.writeHead(500, { 'Content-Type': 'application/json' });
277
+ res.end(JSON.stringify({
278
+ success: false,
279
+ error: error.message
280
+ }));
281
+ }
282
+ }
283
+ }
284
+
285
+ module.exports = ModelControllerExample;
@@ -202,6 +202,66 @@ class ControllerBase {
202
202
  clearViewData() {
203
203
  this.viewData = {};
204
204
  }
205
+
206
+ /**
207
+ * Carga un modelo para su uso en el controlador
208
+ * @param {string} modelName - Nombre del modelo a cargar
209
+ * @param {Object} options - Opciones para la creación del modelo
210
+ * @returns {ModelBase} - Instancia del modelo cargado
211
+ */
212
+ loadModel(modelName, options = {}) {
213
+ try {
214
+ // Construir la ruta del modelo
215
+ // Buscar en diferentes ubicaciones posibles
216
+ let ModelClass;
217
+
218
+ // Primero intentar cargar desde la carpeta models del proyecto
219
+ try {
220
+ ModelClass = require(`../../../models/${modelName}`);
221
+ } catch (e1) {
222
+ try {
223
+ // Intentar cargar desde la carpeta models relativa al controlador
224
+ ModelClass = require(`../models/${modelName}`);
225
+ } catch (e2) {
226
+ try {
227
+ // Intentar cargar desde la carpeta models en la raíz del proyecto
228
+ ModelClass = require(`../../models/${modelName}`);
229
+ } catch (e3) {
230
+ // Si no se encuentra en ninguno de los lugares comunes, lanzar error
231
+ throw new Error(`Modelo '${modelName}' no encontrado en ubicaciones estándar`);
232
+ }
233
+ }
234
+ }
235
+
236
+ // Crear instancia del modelo con las opciones proporcionadas
237
+ const modelInstance = new ModelClass(options);
238
+
239
+ // Guardar referencia del modelo en el controlador
240
+ if (!this.models) {
241
+ this.models = {};
242
+ }
243
+
244
+ this.models[modelName] = modelInstance;
245
+
246
+ return modelInstance;
247
+ } catch (error) {
248
+ console.error(`Error cargando modelo '${modelName}':`, error.message);
249
+ throw error;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Obtiene un modelo previamente cargado
255
+ * @param {string} modelName - Nombre del modelo a obtener
256
+ * @returns {ModelBase|null} - Instancia del modelo o null si no está cargado
257
+ */
258
+ getModel(modelName) {
259
+ if (!this.models) {
260
+ this.models = {};
261
+ }
262
+
263
+ return this.models[modelName] || null;
264
+ }
205
265
  }
206
266
 
207
267
  module.exports = ControllerBase;