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,356 @@
1
+ # Frontend y Sesiones con API SDK JS
2
+
3
+ Visita nuestra página web: https://jerk.page.gd/
4
+ Repositorio oficial: https://gitlab.com/bytedogssyndicate1/jerk/
5
+
6
+ ## Introducción
7
+
8
+ 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.
9
+
10
+ ## Características del Frontend
11
+
12
+ ### Especificación de Content-Type en routes.json
13
+
14
+ Una de las nuevas características es la capacidad de especificar el content-type directamente en el archivo routes.json:
15
+
16
+ ```json
17
+ [
18
+ {
19
+ "path": "/",
20
+ "method": "GET",
21
+ "controller": "./controllers/pageController.js",
22
+ "handler": "homePage",
23
+ "auth": "none",
24
+ "contentType": "text/html"
25
+ },
26
+ {
27
+ "path": "/api/data",
28
+ "method": "GET",
29
+ "controller": "./controllers/apiController.js",
30
+ "handler": "getData",
31
+ "auth": "none",
32
+ "contentType": "application/json"
33
+ }
34
+ ]
35
+ ```
36
+
37
+ ### Soporte para diferentes tipos de contenido
38
+
39
+ El framework ahora puede servir diferentes tipos de contenido:
40
+ - HTML para páginas web
41
+ - CSS para estilos
42
+ - JavaScript para scripts
43
+ - JSON para APIs
44
+ - Y cualquier otro tipo de contenido
45
+
46
+ ## Sistema de Sesiones
47
+
48
+ ### Configuración
49
+
50
+ Para usar el sistema de sesiones, primero debes configurar el middleware en tu aplicación:
51
+
52
+ ```javascript
53
+ const { APIServer, SessionManager, Cors } = require('@jerkjs/jerk');
54
+
55
+ async function startServer() {
56
+ const server = new APIServer({
57
+ port: 3000,
58
+ host: 'localhost'
59
+ });
60
+
61
+ // Crear instancia del administrador de sesiones
62
+ const sessionManager = new SessionManager({
63
+ cookieName: 'myapp_session',
64
+ secret: 'my-super-secret-session-key',
65
+ timeout: 3600000 // 1 hora
66
+ });
67
+
68
+ // Aplicar middleware de sesión
69
+ server.use(sessionManager.middleware());
70
+
71
+ // Hacer que sessionManager esté disponible para el RouteLoader
72
+ server.sessionManager = sessionManager;
73
+
74
+ // Cargar rutas
75
+ const routeLoader = new RouteLoader();
76
+ await routeLoader.loadRoutes(server, './routes.json');
77
+
78
+ server.start();
79
+ }
80
+ ```
81
+
82
+ ### Protección de rutas
83
+
84
+ Puedes proteger rutas específicas usando `"auth": "session"` en tu archivo routes.json:
85
+
86
+ ```json
87
+ [
88
+ {
89
+ "path": "/dashboard",
90
+ "method": "GET",
91
+ "controller": "./controllers/dashboardController.js",
92
+ "handler": "showDashboard",
93
+ "auth": "session",
94
+ "contentType": "text/html"
95
+ }
96
+ ]
97
+ ```
98
+
99
+ ### Uso en controladores
100
+
101
+ En tus controladores, puedes acceder a la sesión a través de `req.session`:
102
+
103
+ ```javascript
104
+ const authController = {
105
+ // Controlador para iniciar sesión
106
+ processLogin: async (req, res) => {
107
+ const { username, password } = req.body;
108
+
109
+ // Validar credenciales (tu lógica aquí)
110
+ const user = await validateUser(username, password);
111
+
112
+ if (user) {
113
+ // Crear sesión de usuario autenticado
114
+ req.session.create({
115
+ authenticated: true,
116
+ userId: user.id,
117
+ username: user.username
118
+ });
119
+
120
+ res.writeHead(200, { 'Content-Type': 'application/json' });
121
+ res.end(JSON.stringify({
122
+ success: true,
123
+ message: 'Inicio de sesión exitoso'
124
+ }));
125
+ } else {
126
+ res.writeHead(401, { 'Content-Type': 'application/json' });
127
+ res.end(JSON.stringify({
128
+ success: false,
129
+ message: 'Credenciales inválidas'
130
+ }));
131
+ }
132
+ },
133
+
134
+ // Controlador para cerrar sesión
135
+ processLogout: (req, res) => {
136
+ if (req.session) {
137
+ req.session.destroy();
138
+ }
139
+
140
+ res.writeHead(200, { 'Content-Type': 'application/json' });
141
+ res.end(JSON.stringify({
142
+ success: true,
143
+ message: 'Sesión cerrada exitosamente'
144
+ }));
145
+ }
146
+ };
147
+ ```
148
+
149
+ ## Sistema de Hooks, Filters y Actions
150
+
151
+ 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.
152
+
153
+ ### Hooks Disponibles
154
+
155
+ #### Sesion Creation Hooks
156
+ - `session_create_data`: Filtra los datos antes de crear una sesión
157
+ - `session_created`: Acción disparada después de crear una sesión
158
+ - `session_create_user_data`: Filtra los datos de usuario antes de crear la sesión
159
+
160
+ #### Sesion Retrieval Hooks
161
+ - `session_get_id`: Filtra el ID de sesión antes de buscarla
162
+ - `session_retrieved`: Acción disparada después de obtener una sesión
163
+ - `session_not_found`: Acción disparada cuando no se encuentra una sesión
164
+ - `session_expired`: Acción disparada cuando una sesión ha expirado
165
+
166
+ #### Sesion Update Hooks
167
+ - `session_update_data`: Filtra los nuevos datos antes de actualizar la sesión
168
+ - `session_updated`: Acción disparada después de actualizar una sesión
169
+ - `session_update_user_data`: Filtra los datos de usuario antes de actualizar
170
+
171
+ #### Sesion Destruction Hooks
172
+ - `session_destroy_before`: Acción disparada antes de destruir una sesión
173
+ - `session_destroyed`: Acción disparada después de destruir una sesión
174
+ - `session_destroy_failed`: Acción disparada cuando falla la destrucción
175
+
176
+ #### Middleware Hooks
177
+ - `session_middleware_before`: Acción disparada antes del middleware de sesión
178
+ - `session_middleware_after`: Acción disparada después del middleware de sesión
179
+
180
+ #### Authentication Hooks
181
+ - `session_auth_check_before`: Acción disparada antes de verificar autenticación
182
+ - `session_auth_success`: Acción disparada cuando la autenticación es exitosa
183
+ - `session_auth_failed`: Acción disparada cuando la autenticación falla
184
+ - `session_created_response`: Acción disparada después de crear sesión en respuesta
185
+ - `session_updated_response`: Acción disparada después de actualizar sesión en respuesta
186
+ - `session_destroyed_response`: Acción disparada después de destruir sesión en respuesta
187
+
188
+ ### Ejemplos de Uso de Hooks
189
+
190
+ #### Registrar actividad de sesión
191
+
192
+ ```javascript
193
+ const { hooks } = require('@jerkjs/jerk');
194
+
195
+ // Registrar cuando se crea una sesión
196
+ hooks.addAction('session_created', (sessionId, sessionData) => {
197
+ console.log(`Sesión creada: ${sessionId} para el usuario: ${sessionData.username}`);
198
+ });
199
+
200
+ // Registrar cuando se destruye una sesión
201
+ hooks.addAction('session_destroyed', (sessionId, sessionData) => {
202
+ console.log(`Sesión destruida: ${sessionId} para el usuario: ${sessionData.username}`);
203
+ });
204
+ ```
205
+
206
+ #### Modificar datos de sesión antes de crearla
207
+
208
+ ```javascript
209
+ const { hooks } = require('@jerkjs/jerk');
210
+
211
+ // Añadir información de IP y fecha a los datos de sesión
212
+ hooks.addFilter('session_create_data', (userData, req) => {
213
+ return {
214
+ ...userData,
215
+ ipAddress: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
216
+ createdAt: new Date().toISOString()
217
+ };
218
+ });
219
+ ```
220
+
221
+ #### Personalizar el manejo de autenticación fallida
222
+
223
+ ```javascript
224
+ const { hooks } = require('@jerkjs/jerk');
225
+
226
+ // Registrar intentos de acceso no autorizado
227
+ hooks.addAction('session_auth_failed', (req, res, redirectTo) => {
228
+ console.log(`Intento de acceso no autorizado a: ${req.url} desde IP: ${req.connection.remoteAddress}`);
229
+
230
+ // Puedes personalizar la respuesta aquí
231
+ if (req.headers.accept && req.headers.accept.includes('application/json')) {
232
+ res.writeHead(401, { 'Content-Type': 'application/json' });
233
+ res.end(JSON.stringify({ error: 'No autorizado', code: 'AUTH_REQUIRED' }));
234
+ }
235
+ });
236
+ ```
237
+
238
+ #### Extender datos de sesión durante la actualización
239
+
240
+ ```javascript
241
+ const { hooks } = require('@jerkjs/jerk');
242
+
243
+ // Añadir marca de tiempo a cada actualización de sesión
244
+ hooks.addFilter('session_update_data', (newData, req, sessionId) => {
245
+ return {
246
+ ...newData,
247
+ lastUpdated: new Date().toISOString(),
248
+ lastActivity: new Date().toISOString()
249
+ };
250
+ });
251
+ ```
252
+
253
+ ## Ejemplo Completo
254
+
255
+ Aquí tienes un ejemplo completo de una aplicación que combina frontend y sesiones:
256
+
257
+ ### app.js
258
+ ```javascript
259
+ const {
260
+ APIServer,
261
+ RouteLoader,
262
+ Logger,
263
+ Cors,
264
+ SessionManager
265
+ } = require('@jerkjs/jerk');
266
+
267
+ async function startServer() {
268
+ const server = new APIServer({
269
+ port: 3000,
270
+ host: 'localhost'
271
+ });
272
+
273
+ const logger = new Logger({ level: 'info' });
274
+
275
+ try {
276
+ // Configurar sesiones
277
+ const sessionManager = new SessionManager({
278
+ cookieName: 'myapp_session',
279
+ secret: 'my-super-secret-session-key',
280
+ timeout: 3600000
281
+ });
282
+
283
+ server.use(sessionManager.middleware());
284
+ server.sessionManager = sessionManager;
285
+
286
+ // Configurar CORS
287
+ const cors = new Cors({
288
+ origin: '*',
289
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
290
+ allowedHeaders: ['Content-Type', 'Authorization']
291
+ });
292
+
293
+ server.use(cors.middleware());
294
+
295
+ // Cargar rutas
296
+ const routeLoader = new RouteLoader();
297
+ await routeLoader.loadRoutes(server, './routes.json');
298
+
299
+ server.start();
300
+ logger.info('Servidor iniciado en http://localhost:3000');
301
+ } catch (error) {
302
+ logger.error('Error iniciando el servidor:', error.message);
303
+ process.exit(1);
304
+ }
305
+ }
306
+
307
+ startServer();
308
+ ```
309
+
310
+ ### routes.json
311
+ ```json
312
+ [
313
+ {
314
+ "path": "/",
315
+ "method": "GET",
316
+ "controller": "./controllers/pageController.js",
317
+ "handler": "homePage",
318
+ "auth": "none",
319
+ "contentType": "text/html"
320
+ },
321
+ {
322
+ "path": "/login",
323
+ "method": "GET",
324
+ "controller": "./controllers/authController.js",
325
+ "handler": "showLoginPage",
326
+ "auth": "none",
327
+ "contentType": "text/html"
328
+ },
329
+ {
330
+ "path": "/dashboard",
331
+ "method": "GET",
332
+ "controller": "./controllers/dashboardController.js",
333
+ "handler": "showDashboard",
334
+ "auth": "session",
335
+ "contentType": "text/html"
336
+ },
337
+ {
338
+ "path": "/api/login",
339
+ "method": "POST",
340
+ "controller": "./controllers/authController.js",
341
+ "handler": "processLogin",
342
+ "auth": "none",
343
+ "contentType": "application/json"
344
+ },
345
+ {
346
+ "path": "/api/logout",
347
+ "method": "POST",
348
+ "controller": "./controllers/authController.js",
349
+ "handler": "processLogout",
350
+ "auth": "session",
351
+ "contentType": "application/json"
352
+ }
353
+ ]
354
+ ```
355
+
356
+ 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.
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Controlador de ejemplo para productos
3
+ * Archivo: examples/advanced/controllers/productController.js
4
+ */
5
+
6
+ // Simulación de base de datos de productos
7
+ let products = [
8
+ { id: 1, name: 'Laptop', price: 1000, category: 'Electronics' },
9
+ { id: 2, name: 'Mouse', price: 25, category: 'Accessories' }
10
+ ];
11
+
12
+ // Obtener todos los productos
13
+ function getProducts(req, res) {
14
+ res.writeHead(200, { 'Content-Type': 'application/json' });
15
+ res.end(JSON.stringify({
16
+ success: true,
17
+ data: products
18
+ }));
19
+ }
20
+
21
+ // Actualizar un producto por ID
22
+ function updateProduct(req, res) {
23
+ try {
24
+ const productId = parseInt(req.params.id);
25
+ const { name, price, category } = req.body;
26
+
27
+ const productIndex = products.findIndex(p => p.id === productId);
28
+
29
+ if (productIndex === -1) {
30
+ res.writeHead(404, { 'Content-Type': 'application/json' });
31
+ res.end(JSON.stringify({
32
+ success: false,
33
+ message: 'Producto no encontrado'
34
+ }));
35
+ return;
36
+ }
37
+
38
+ // Actualizar producto
39
+ products[productIndex] = {
40
+ ...products[productIndex],
41
+ ...(name && { name }),
42
+ ...(price && { price }),
43
+ ...(category && { category })
44
+ };
45
+
46
+ res.writeHead(200, { 'Content-Type': 'application/json' });
47
+ res.end(JSON.stringify({
48
+ success: true,
49
+ data: products[productIndex]
50
+ }));
51
+ } catch (error) {
52
+ res.writeHead(500, { 'Content-Type': 'application/json' });
53
+ res.end(JSON.stringify({
54
+ success: false,
55
+ message: 'Error al actualizar producto'
56
+ }));
57
+ }
58
+ }
59
+
60
+ // Exportar handlers
61
+ module.exports = {
62
+ getProducts,
63
+ updateProduct
64
+ };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Controlador de ejemplo para usuarios
3
+ * Archivo: examples/basic/controllers/userController.js
4
+ */
5
+
6
+ // Simulación de base de datos
7
+ let users = [
8
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
9
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
10
+ ];
11
+
12
+ // Obtener todos los usuarios
13
+ function getUsers(req, res) {
14
+ res.writeHead(200, { 'Content-Type': 'application/json' });
15
+ res.end(JSON.stringify({
16
+ success: true,
17
+ data: users
18
+ }));
19
+ }
20
+
21
+ // Obtener un usuario por ID
22
+ function getUserById(req, res) {
23
+ const userId = parseInt(req.params.id);
24
+ const user = users.find(u => u.id === userId);
25
+
26
+ if (!user) {
27
+ res.writeHead(404, { 'Content-Type': 'application/json' });
28
+ res.end(JSON.stringify({
29
+ success: false,
30
+ message: 'Usuario no encontrado'
31
+ }));
32
+ return;
33
+ }
34
+
35
+ res.writeHead(200, { 'Content-Type': 'application/json' });
36
+ res.end(JSON.stringify({
37
+ success: true,
38
+ data: user
39
+ }));
40
+ }
41
+
42
+ // Crear un nuevo usuario
43
+ function createUser(req, res) {
44
+ try {
45
+ const { name, email } = req.body;
46
+
47
+ // Validar datos
48
+ if (!name || !email) {
49
+ res.writeHead(400, { 'Content-Type': 'application/json' });
50
+ res.end(JSON.stringify({
51
+ success: false,
52
+ message: 'Nombre y correo electrónico son requeridos'
53
+ }));
54
+ return;
55
+ }
56
+
57
+ // Crear nuevo usuario
58
+ const newUser = {
59
+ id: users.length + 1,
60
+ name,
61
+ email
62
+ };
63
+
64
+ users.push(newUser);
65
+
66
+ res.writeHead(201, { 'Content-Type': 'application/json' });
67
+ res.end(JSON.stringify({
68
+ success: true,
69
+ data: newUser
70
+ }));
71
+ } catch (error) {
72
+ res.writeHead(500, { 'Content-Type': 'application/json' });
73
+ res.end(JSON.stringify({
74
+ success: false,
75
+ message: 'Error al crear usuario'
76
+ }));
77
+ }
78
+ }
79
+
80
+ // Exportar handlers
81
+ module.exports = {
82
+ getUsers,
83
+ getUserById,
84
+ createUser
85
+ };
@@ -0,0 +1,51 @@
1
+ [
2
+ {
3
+ "path": "/api/users",
4
+ "method": "GET",
5
+ "auth": "jwt",
6
+ "authOptions": {
7
+ "jwtSecret": "secret-jwt-key"
8
+ },
9
+ "controller": "./basic/controllers/userController.js",
10
+ "handler": "getUsers"
11
+ },
12
+ {
13
+ "path": "/api/users/:id",
14
+ "method": "GET",
15
+ "auth": "jwt",
16
+ "authOptions": {
17
+ "jwtSecret": "secret-jwt-key"
18
+ },
19
+ "controller": "./basic/controllers/userController.js",
20
+ "handler": "getUserById"
21
+ },
22
+ {
23
+ "path": "/api/users",
24
+ "method": "POST",
25
+ "auth": "apiKey",
26
+ "authOptions": {
27
+ "apiKeyHeader": "X-API-Key",
28
+ "apiKeyValues": ["secret-key-123"]
29
+ },
30
+ "controller": "./basic/controllers/userController.js",
31
+ "handler": "createUser"
32
+ },
33
+ {
34
+ "path": "/api/products",
35
+ "method": "GET",
36
+ "auth": "none",
37
+ "controller": "./advanced/controllers/productController.js",
38
+ "handler": "getProducts"
39
+ },
40
+ {
41
+ "path": "/api/products/:id",
42
+ "method": "PUT",
43
+ "auth": "apiKey",
44
+ "authOptions": {
45
+ "apiKeyHeader": "X-API-Key",
46
+ "apiKeyValues": ["secret-key-123"]
47
+ },
48
+ "controller": "./advanced/controllers/productController.js",
49
+ "handler": "updateProduct"
50
+ }
51
+ ]
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Ejemplo real de uso del framework API SDK
3
+ * Este script demuestra cómo cargar rutas desde un archivo JSON
4
+ * y usar los controladores definidos en el archivo de rutas
5
+ */
6
+
7
+ const path = require('path');
8
+ const { APISDK, RouteLoader, Authenticator, Logger } = require('../index');
9
+
10
+ // Crear instancia del logger
11
+ const logger = new Logger({ level: 'info', timestamp: true });
12
+
13
+ logger.info('Iniciando ejemplo real de carga de rutas desde JSON');
14
+
15
+ // Crear instancia del servidor
16
+ const server = new APISDK({
17
+ port: 9900,
18
+ host: 'localhost'
19
+ });
20
+
21
+ // Crear instancia del autenticador
22
+ const authenticator = new Authenticator();
23
+
24
+ // Registrar estrategias de autenticación que se usan en routes.json
25
+ authenticator.use('apiKey', authenticator.apiKeyStrategy('X-API-Key', ['secret-key-123']));
26
+ authenticator.use('jwt', authenticator.jwtStrategy('secret-jwt-key'));
27
+
28
+ // Cargar rutas desde el archivo JSON
29
+ const routeLoader = new RouteLoader();
30
+
31
+ // Middleware de logging
32
+ server.use((req, res, next) => {
33
+ logger.info(`${req.method} ${req.url} - IP: ${req.connection.remoteAddress}`);
34
+ next();
35
+ });
36
+
37
+ logger.info('Cargando rutas desde advanced/routes.json...');
38
+
39
+ // Cargar las rutas desde el archivo JSON
40
+ // Cambiamos temporalmente el directorio de trabajo para que las rutas relativas funcionen correctamente
41
+ const originalCwd = process.cwd();
42
+ process.chdir(__dirname); // Cambiar al directorio actual (examples)
43
+
44
+ routeLoader.loadRoutes(server, './advanced/routes.json')
45
+ .then(routes => {
46
+ process.chdir(originalCwd); // Restaurar directorio original
47
+
48
+ logger.info(`Cargadas ${routes.length} rutas desde el archivo JSON:`);
49
+ routes.forEach((route, index) => {
50
+ logger.info(` ${index + 1}. ${route.method} ${route.path} -> ${route.controller}#${route.handler}`);
51
+ });
52
+
53
+ logger.info('\nIniciando servidor en http://localhost:9900');
54
+
55
+ // Iniciar el servidor
56
+ const httpServer = server.start();
57
+
58
+ logger.info('\nENDPOINTS DISPONIBLES (cargados desde routes.json):');
59
+ logger.info('GET /api/users - Obtener todos los usuarios (JWT req)');
60
+ logger.info('GET /api/users/:id - Obtener usuario por ID (JWT req)');
61
+ logger.info('POST /api/users - Crear usuario (API Key req)');
62
+ logger.info('GET /api/products - Obtener productos (sin auth)');
63
+ logger.info('PUT /api/products/:id - Actualizar producto (API Key req)');
64
+
65
+ logger.info('\nEJEMPLOS DE USO:');
66
+ logger.info('# Obtener productos (sin autenticación):');
67
+ logger.info('curl -X GET http://localhost:9900/api/products');
68
+
69
+ logger.info('\nEl servidor se detendrá automáticamente en 120 segundos...');
70
+
71
+ // Programar apagado automático para la demostración
72
+ setTimeout(() => {
73
+ logger.info('Finalizando ejemplo...');
74
+ httpServer.close(() => {
75
+ logger.info('Servidor detenido. Ejemplo completado.');
76
+ console.log('\nEjemplo real completado exitosamente!');
77
+ console.log('El framework ha demostrado su capacidad para:');
78
+ console.log(' - Cargar rutas dinámicamente desde archivos JSON');
79
+ console.log(' - Usar controladores definidos externamente');
80
+ console.log(' - Aplicar diferentes tipos de autenticación');
81
+ process.exit(0);
82
+ });
83
+ }, 120000);
84
+
85
+ })
86
+ .catch(error => {
87
+ process.chdir(originalCwd); // Asegurarse de restaurar el directorio en caso de error
88
+ logger.error('Error cargando rutas:', error.message);
89
+ process.exit(1);
90
+ });
91
+
92
+ // Mantener el proceso activo
93
+ process.stdin.resume();