nicola-framework 1.0.1 → 1.0.2

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/README.md CHANGED
@@ -3,23 +3,25 @@
3
3
  [![npm version](https://img.shields.io/npm/v/nicola-framework.svg)](https://www.npmjs.com/package/nicola-framework)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D16.0.0-brightgreen.svg)](https://nodejs.org)
6
- [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-success.svg)](https://www.npmjs.com/package/nicola-framework)
7
6
 
8
- > **Performance de bajo nivel con DX de alto nivel.**
7
+ > Framework HTTP minimalista para Node.js (ESM): servidor, router, middlewares, JWT y una capa ORM sencilla.
9
8
 
10
- Nicola es un framework web moderno para Node.js con arquitectura **Zero-Dependency**. Diseñado para ser ligero, seguro por defecto y con todas las herramientas que necesitas integradas.
9
+ Nicola expone un **servidor HTTP nativo** con un **router tipo Express** y utilidades integradas. El proyecto está escrito como **ES Modules** (`"type": "module"`), por lo que los ejemplos usan `import`.
11
10
 
12
11
  ---
13
12
 
14
- ## 🚀 ¿Por qué Nicola?
13
+ ## Estado actual del proyecto (lo que realmente hay)
15
14
 
16
- - **🎯 Zero Dependencies** - Sin librerías externas, 100% código nativo
17
- - **⚡ Alto Rendimiento** - Servidor HTTP nativo sin overhead
18
- - **🔐 Seguro por Defecto** - JWT nativo, validación de schemas, headers de seguridad
19
- - **🗃️ ORM Incluido** - Dynamo ORM con soporte MySQL y PostgreSQL
20
- - **🔥 Hot Reload Nativo** - Recarga automática sin nodemon
21
- - **🎨 Error Handler Visual** - Interfaz elegante para debugging
22
- - **📦 Todo Incluido** - Router, middlewares, ORM, seguridad, logging
15
+ - **Core/Router**: `Nicola` (default) extiende `Remote`.
16
+ - **Body parsing**: JSON si `Content-Type` incluye `application/json` (límite ~2MB). Si no, `req.body = {}`.
17
+ - **Helpers de response**: `res.json(data)` y `res.send(text)`. (No existe `res.status()`.)
18
+ - **CORS**: `EasyCors` permite `*` y responde `OPTIONS` con `204`.
19
+ - **Security headers**: `Teleforce` aplica headers básicos (no-sniff, frame deny, etc.).
20
+ - **Logger**: `Shadowgraph` loggea al terminar la respuesta.
21
+ - **Errores**: si un handler lanza error o llama `next(err)`, se responde HTML via `BlackBox`.
22
+ - **JWT**: `Coherer` (HS256) funciona vía métodos **estáticos** y requiere `NICOLA_SECRET` en env.
23
+ - **ORM**: `Dynamo` soporta **Postgres** hoy (driver `postgres`). La lib `pg` es **dependencia opcional** (se instala aparte).
24
+ - **Hot reload**: `LiveCurrent` reinicia el proceso Node al detectar cambios en el directorio.
23
25
 
24
26
  ---
25
27
 
@@ -29,601 +31,244 @@ Nicola es un framework web moderno para Node.js con arquitectura **Zero-Dependen
29
31
  npm install nicola-framework
30
32
  ```
31
33
 
34
+ ### (Opcional) Postgres
35
+
36
+ El dialecto Postgres usa `pg` por import dinámico.
37
+
38
+ ```bash
39
+ npm install pg
40
+ ```
41
+
32
42
  ---
33
43
 
34
44
  ## ⚡ Quickstart
35
45
 
36
- ### Servidor HTTP Básico
46
+ ### Servidor HTTP básico
37
47
 
38
- ```javascript
48
+ ```js
39
49
  import Nicola from 'nicola-framework';
40
50
 
41
51
  const app = new Nicola();
42
52
 
43
53
  app.get('/', (req, res) => {
44
- res.json({ message: 'Hello from Nicola!' });
54
+ res.json({ ok: true, message: 'Hello from Nicola!' });
45
55
  });
46
56
 
47
57
  app.listen(3000, () => {
48
- console.log('🚀 Server running on http://localhost:3000');
58
+ console.log('Server running on http://localhost:3000');
49
59
  });
50
60
  ```
51
61
 
52
- ### Con Router y Middlewares
62
+ ### Router anidado y params
53
63
 
54
- ```javascript
55
- import { Nicola, Remote, Shadowgraph, Teleforce } from 'nicola-framework';
64
+ ```js
65
+ import { Nicola, Remote } from 'nicola-framework';
56
66
 
57
67
  const app = new Nicola();
58
- const router = new Remote();
59
-
60
- // Middlewares globales
61
- app.use(Shadowgraph); // Logger HTTP
62
- app.use(Teleforce); // Security headers
68
+ const api = new Remote();
63
69
 
64
- // Router con rutas anidadas
65
- router.get('/users', (req, res) => {
70
+ api.get('/users', (req, res) => {
66
71
  res.json({ users: ['Alice', 'Bob'] });
67
72
  });
68
73
 
69
- router.get('/users/:id', (req, res) => {
74
+ api.get('/users/:id', (req, res) => {
70
75
  res.json({ userId: req.params.id });
71
76
  });
72
77
 
73
- app.use('/api', router);
74
-
75
- app.listen(3000);
76
- ```
77
-
78
- ### Con ORM (Dynamo)
79
-
80
- ```javascript
81
- import { Nicola, Dynamo } from 'nicola-framework';
82
- import User from './models/User.js';
83
-
84
- // Configurar base de datos
85
- await Dynamo.connect({
86
- dialect: 'mysql',
87
- host: 'localhost',
88
- user: 'root',
89
- password: '',
90
- database: 'mydb'
91
- });
92
-
93
- const app = new Nicola();
94
-
95
- // Crear usuario
96
- app.post('/users', async (req, res) => {
97
- const user = await User.create(req.body);
98
- res.json(user);
99
- });
100
-
101
- // Buscar usuarios
102
- app.get('/users', async (req, res) => {
103
- const users = await User.where('active', true).get();
104
- res.json(users);
105
- });
106
-
78
+ app.use('/api', api);
107
79
  app.listen(3000);
108
80
  ```
109
81
 
110
82
  ---
111
83
 
112
- ## 🏗️ Arquitectura Modular
113
-
114
- Nicola está compuesto por módulos independientes que trabajan en armonía:
84
+ ## 🧠 API (resumen fiel al código)
115
85
 
116
- | Módulo | Función | Descripción |
117
- |--------|---------|-------------|
118
- | **Core** | El Motor | Servidor HTTP nativo con body parsing y middleware system |
119
- | **Remote** | El Cerebro | Router avanzado con soporte MVC, regex y rutas dinámicas |
120
- | **Dynamo** | La Base | ORM completo con QueryBuilder y Active Record |
121
- | **Coherer** | El Notario | Sistema JWT nativo (HMAC SHA256) |
122
- | **Shadowgraph** | El Observador | Logger HTTP de alto rendimiento |
123
- | **Teleforce** | El Escudo | Suite de seguridad (XSS, NoSniff, CORS) |
124
- | **BlackBox** | El Forense | Error handler visual estilo terminal |
125
- | **Insulator** | El Portero | Validador de schemas |
126
- | **Regulator** | El Gestor | Parser de variables .env |
127
- | **LiveCurrent** | El Fénix | Hot reload automático |
86
+ ### `Nicola` (Core)
128
87
 
129
- ---
130
-
131
- ## 📚 Documentación Completa
132
-
133
- ### 1. Core (Servidor HTTP)
88
+ - `new Nicola()`
89
+ - `app.get/post/put/patch/delete(path, ...handlers)`
90
+ - `app.use([path], ...handlers | router)`
91
+ - `app.listen(port, [callback])`
134
92
 
135
- El servidor HTTP principal con soporte de middlewares.
93
+ Notas:
94
+ - `Nicola.listen()` ejecuta internamente `Shadowgraph`, `EasyCors` y `Teleforce` en cada request.
95
+ - `req.query` se construye desde querystring.
136
96
 
137
- ```javascript
138
- import Nicola from 'nicola-framework';
97
+ ### `Remote` (Router)
139
98
 
140
- const app = new Nicola();
99
+ `Remote` es el router base. Soporta middlewares y rutas con params (`/users/:id`).
141
100
 
142
- // Métodos HTTP
143
- app.get('/users', handler);
144
- app.post('/users', handler);
145
- app.put('/users/:id', handler);
146
- app.delete('/users/:id', handler);
147
- app.patch('/users/:id', handler);
101
+ Ejemplo de middleware simple:
148
102
 
149
- // Middleware global
103
+ ```js
150
104
  app.use((req, res, next) => {
151
- console.log(`${req.method} ${req.url}`);
105
+ // No existe res.status(); usa statusCode
106
+ if (req.url === '/blocked') {
107
+ res.statusCode = 403;
108
+ res.end('Forbidden');
109
+ return;
110
+ }
152
111
  next();
153
112
  });
154
-
155
- // Prefijo de ruta
156
- app.use('/api', router);
157
-
158
- app.listen(3000);
159
113
  ```
160
114
 
161
- ### 2. Remote (Router)
162
-
163
- Sistema de routing recursivo con soporte de rutas dinámicas.
164
-
165
- ```javascript
166
- import { Remote } from 'nicola-framework';
167
-
168
- const router = new Remote();
169
-
170
- // Rutas básicas
171
- router.get('/users', getUsers);
172
- router.post('/users', createUser);
173
-
174
- // Parámetros dinámicos
175
- router.get('/users/:id', getUser); // req.params.id
176
- router.get('/posts/:slug/comments/:id', getComment);
177
-
178
- // Routers anidados
179
- const adminRouter = new Remote();
180
- adminRouter.get('/dashboard', adminDashboard);
181
- router.use('/admin', adminRouter); // /admin/dashboard
182
- ```
183
-
184
- ### 3. Dynamo ORM
185
-
186
- ORM completo con Active Record pattern.
187
-
188
- #### Configuración
189
-
190
- ```javascript
191
- import { Dynamo } from 'nicola-framework';
115
+ Errores:
192
116
 
193
- await Dynamo.connect({
194
- dialect: 'mysql', // o 'postgres'
195
- host: 'localhost',
196
- port: 3306,
197
- user: 'root',
198
- password: 'secret',
199
- database: 'mydb'
117
+ ```js
118
+ app.get('/boom', (req, res) => {
119
+ throw new Error('Boom');
200
120
  });
201
121
  ```
202
122
 
203
- #### Definir Modelos
204
-
205
- ```javascript
206
- import { Dynamo } from 'nicola-framework';
207
-
208
- class User extends Dynamo.Model {
209
- static table = 'users';
210
-
211
- static schema = {
212
- name: { type: 'string', required: true },
213
- email: { type: 'string', required: true },
214
- age: { type: 'number' }
215
- };
216
- }
217
-
218
- export default User;
219
- ```
220
-
221
- #### Query Builder
222
-
223
- ```javascript
224
- // Seleccionar todos
225
- const users = await User.all();
226
-
227
- // Buscar por ID
228
- const user = await User.find(1);
229
-
230
- // Condiciones
231
- const activeUsers = await User.where('active', true).get();
232
- const adults = await User.where('age', '>', 18).get();
233
-
234
- // Múltiples condiciones
235
- const results = await User
236
- .where('country', 'US')
237
- .where('age', '>=', 21)
238
- .get();
123
+ ---
239
124
 
240
- // Crear
241
- const newUser = await User.create({
242
- name: 'Alice',
243
- email: 'alice@example.com'
244
- });
125
+ ## 🔐 Seguridad
245
126
 
246
- // Actualizar
247
- await User.where('id', 5).update({ name: 'Bob' });
127
+ ### `Regulator` (.env)
248
128
 
249
- // Eliminar
250
- await User.where('id', 5).delete();
129
+ Lee `.env` desde el directorio actual (`process.cwd()`) y lo copia a `process.env`.
251
130
 
252
- // Select específico
253
- const names = await User.select('name', 'email').get();
131
+ ```js
132
+ import { Regulator } from 'nicola-framework';
254
133
 
255
- // Límite
256
- const first10 = await User.limit(10).get();
134
+ Regulator.load();
257
135
  ```
258
136
 
259
- ### 4. Coherer (JWT Nativo)
260
-
261
- Sistema de autenticación JWT sin dependencias externas.
137
+ ### `Coherer` (JWT HS256)
262
138
 
263
- ```javascript
264
- import { Coherer } from 'nicola-framework';
139
+ `Coherer` es una clase con métodos **estáticos**.
265
140
 
266
- const jwt = new Coherer('mi-secreto-super-seguro');
141
+ ```js
142
+ import { Regulator, Coherer } from 'nicola-framework';
267
143
 
268
- // Generar token
269
- const token = jwt.sign({
270
- userId: 123,
271
- role: 'admin'
272
- }, '24h'); // Expira en 24 horas
273
-
274
- // Verificar token
275
- const payload = jwt.verify(token);
276
- if (payload) {
277
- console.log('Token válido:', payload);
278
- } else {
279
- console.log('Token inválido o expirado');
280
- }
144
+ Regulator.load();
281
145
 
282
- // Middleware de autenticación
283
- function authMiddleware(req, res, next) {
284
- const token = req.headers.authorization?.split(' ')[1];
285
-
286
- const payload = jwt.verify(token);
287
- if (!payload) {
288
- return res.status(401).json({ error: 'No autorizado' });
289
- }
290
-
291
- req.user = payload;
292
- next();
293
- }
146
+ const token = Coherer.sign(
147
+ { userId: 123, role: 'admin' },
148
+ { expiresIn: '24h' }
149
+ );
294
150
 
295
- app.use('/protected', authMiddleware);
151
+ const payload = Coherer.verify(token);
152
+ console.log(payload.userId);
296
153
  ```
297
154
 
298
- ### 5. Regulator (Variables de Entorno)
299
-
300
- Parser seguro de archivos .env
301
-
302
- ```javascript
303
- import { Regulator } from 'nicola-framework';
304
-
305
- // Cargar .env
306
- Regulator.load();
155
+ `.env` mínimo:
307
156
 
308
- // Acceder a variables
309
- const port = process.env.PORT || 3000;
310
- const dbUrl = process.env.DATABASE_URL;
311
- const secret = process.env.JWT_SECRET;
312
- ```
313
-
314
- **.env example:**
315
157
  ```env
316
- PORT=3000
317
- DATABASE_URL=mysql://root:password@localhost:3306/mydb
318
- JWT_SECRET=mi-super-secreto-jwt
319
- NODE_ENV=development
158
+ NICOLA_SECRET=mi-secreto-super-seguro
320
159
  ```
321
160
 
322
- ### 6. Middlewares Incluidos
323
-
324
- #### Shadowgraph (Logger HTTP)
161
+ ---
325
162
 
326
- ```javascript
327
- import { Shadowgraph } from 'nicola-framework';
163
+ ## 🗃️ Dynamo (ORM)
328
164
 
329
- app.use(Shadowgraph);
330
- // Output: GET /users → 200 (15ms)
331
- ```
165
+ ### Configuración
332
166
 
333
- #### Teleforce (Security Headers)
167
+ `Dynamo.connect()` **no recibe config**: toma la configuración desde variables de entorno.
334
168
 
335
- ```javascript
336
- import { Teleforce } from 'nicola-framework';
169
+ ```js
170
+ import { Regulator, Dynamo } from 'nicola-framework';
337
171
 
338
- app.use(Teleforce);
339
- // Añade: X-XSS-Protection, X-Content-Type-Options, etc.
172
+ Regulator.load();
173
+ await Dynamo.connect();
340
174
  ```
341
175
 
342
- #### EasyCors (CORS Management)
343
-
344
- ```javascript
345
- import { EasyCors } from 'nicola-framework';
176
+ `.env` para Postgres:
346
177
 
347
- app.use(EasyCors({
348
- origin: 'https://mi-frontend.com',
349
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
350
- credentials: true
351
- }));
178
+ ```env
179
+ DB_DRIVER=postgres
180
+ DB_HOST=localhost
181
+ DB_PORT=5432
182
+ DB_USER=postgres
183
+ DB_PASS=postgres
184
+ DB_NAME=mydb
352
185
  ```
353
186
 
354
- #### BlackBox (Error Handler)
187
+ ### Modelos
355
188
 
356
- ```javascript
357
- import { BlackBox } from 'nicola-framework';
358
-
359
- app.use(BlackBox); // Debe ser el último middleware
360
- // Captura errores y muestra interfaz visual
361
- ```
189
+ ```js
190
+ import { Dynamo } from 'nicola-framework';
362
191
 
363
- #### Insulator (Schema Validation)
192
+ export default class User extends Dynamo.Model {
193
+ static tableName = 'users';
364
194
 
365
- ```javascript
366
- import { Insulator } from 'nicola-framework';
195
+ static schema = {
196
+ name: { type: 'string', required: true },
197
+ email: { type: 'string', required: true },
198
+ age: { type: 'number', required: false }
199
+ };
200
+ }
201
+ ```
367
202
 
368
- const userSchema = {
369
- name: { type: 'string', required: true, min: 3 },
370
- email: { type: 'string', required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },
371
- age: { type: 'number', min: 18 }
372
- };
203
+ ### Queries
373
204
 
374
- app.post('/users', Insulator(userSchema), (req, res) => {
375
- // req.body ya está validado
376
- res.json({ message: 'Usuario válido' });
377
- });
378
- ```
205
+ ```js
206
+ // All
207
+ const users = await User.all();
379
208
 
380
- ### 7. LiveCurrent (Hot Reload)
209
+ // Where
210
+ const active = await User.where('active', true).get();
381
211
 
382
- Para desarrollo con recarga automática:
212
+ // Insert (valida contra schema)
213
+ const created = await User.create({ name: 'Alice', email: 'a@a.com', age: 20 });
383
214
 
384
- ```javascript
385
- import { DevRunner } from 'nicola-framework';
215
+ // Update / Delete
216
+ await User.where('id', 1).update({ name: 'Alice 2' });
217
+ await User.where('id', 1).delete();
386
218
 
387
- // dev.js
388
- DevRunner.start('./app.js', {
389
- watch: ['src/', 'config/'],
390
- ignore: ['node_modules/', 'logs/']
391
- });
392
- ```
219
+ // Select específico (usa string con coma)
220
+ const names = await User.select('name,email').get();
393
221
 
394
- ```bash
395
- node dev.js
396
- # El servidor se recarga automáticamente al editar archivos
222
+ // Order/limit/offset vía QueryBuilder
223
+ const latest = await User.query().orderBy('id', 'DESC').limit(10).offset(0).get();
397
224
  ```
398
225
 
399
226
  ---
400
227
 
401
- ## 🎯 Ejemplos Completos
228
+ ## 🧩 Middlewares
402
229
 
403
- ### API REST con Autenticación
230
+ ### `Insulator(schema)`
404
231
 
405
- ```javascript
406
- import { Nicola, Remote, Coherer, Regulator } from 'nicola-framework';
407
- import User from './models/User.js';
232
+ Valida `req.body` con un esquema **simple** de tipos (`typeof`).
408
233
 
409
- Regulator.load();
234
+ ```js
235
+ import { Insulator } from 'nicola-framework';
410
236
 
411
- const app = new Nicola();
412
- const router = new Remote();
413
- const jwt = new Coherer(process.env.JWT_SECRET);
414
-
415
- // Middleware de autenticación
416
- const authenticate = (req, res, next) => {
417
- const token = req.headers.authorization?.split(' ')[1];
418
- const payload = jwt.verify(token);
419
-
420
- if (!payload) {
421
- return res.status(401).json({ error: 'No autorizado' });
422
- }
423
-
424
- req.user = payload;
425
- next();
237
+ const schema = {
238
+ name: 'string',
239
+ age: 'number'
426
240
  };
427
241
 
428
- // Rutas públicas
429
- router.post('/register', async (req, res) => {
430
- const user = await User.create(req.body);
431
- const token = jwt.sign({ userId: user.id }, '7d');
432
-
433
- res.json({ user, token });
434
- });
435
-
436
- router.post('/login', async (req, res) => {
437
- const user = await User.where('email', req.body.email).first();
438
-
439
- if (!user || user.password !== req.body.password) {
440
- return res.status(401).json({ error: 'Credenciales inválidas' });
441
- }
442
-
443
- const token = jwt.sign({ userId: user.id }, '7d');
444
- res.json({ user, token });
445
- });
446
-
447
- // Rutas protegidas
448
- router.get('/profile', authenticate, async (req, res) => {
449
- const user = await User.find(req.user.userId);
450
- res.json(user);
451
- });
452
-
453
- router.put('/profile', authenticate, async (req, res) => {
454
- await User.where('id', req.user.userId).update(req.body);
455
- res.json({ message: 'Perfil actualizado' });
242
+ app.post('/users', Insulator(schema), (req, res) => {
243
+ res.json({ ok: true });
456
244
  });
457
-
458
- app.use('/api', router);
459
- app.listen(3000);
460
245
  ```
461
246
 
462
- ### CRUD Completo
463
-
464
- ```javascript
465
- import { Nicola, Remote, Dynamo, Insulator, Shadowgraph, BlackBox } from 'nicola-framework';
466
- import Post from './models/Post.js';
467
-
468
- await Dynamo.connect({
469
- dialect: 'mysql',
470
- host: 'localhost',
471
- database: 'blog'
472
- });
473
-
474
- const app = new Nicola();
475
- const router = new Remote();
476
-
477
- app.use(Shadowgraph); // Logger
478
-
479
- const postSchema = {
480
- title: { type: 'string', required: true, min: 5 },
481
- content: { type: 'string', required: true },
482
- published: { type: 'boolean' }
483
- };
484
-
485
- // List posts
486
- router.get('/', async (req, res) => {
487
- const posts = await Post.where('published', true).get();
488
- res.json(posts);
489
- });
490
-
491
- // Get single post
492
- router.get('/:id', async (req, res) => {
493
- const post = await Post.find(req.params.id);
494
-
495
- if (!post) {
496
- return res.status(404).json({ error: 'Post no encontrado' });
497
- }
498
-
499
- res.json(post);
500
- });
501
-
502
- // Create post
503
- router.post('/', Insulator(postSchema), async (req, res) => {
504
- const post = await Post.create(req.body);
505
- res.status(201).json(post);
506
- });
507
-
508
- // Update post
509
- router.put('/:id', Insulator(postSchema), async (req, res) => {
510
- await Post.where('id', req.params.id).update(req.body);
511
- res.json({ message: 'Post actualizado' });
512
- });
513
-
514
- // Delete post
515
- router.delete('/:id', async (req, res) => {
516
- await Post.where('id', req.params.id).delete();
517
- res.status(204).send();
518
- });
247
+ ### `Shadowgraph`, `Teleforce`, `EasyCors`
519
248
 
520
- app.use('/api/posts', router);
521
- app.use(BlackBox); // Error handler (último)
522
-
523
- app.listen(3000);
524
- ```
249
+ Se ejecutan automáticamente dentro de `Nicola.listen()`. También puedes llamarlos manualmente si estás usando `Remote` por separado.
525
250
 
526
251
  ---
527
252
 
528
- ## 🔧 Estructura de Proyecto Recomendada
253
+ ## 🔥 LiveCurrent (hot reload)
529
254
 
530
- ```
531
- /mi-proyecto
532
- ├── /src
533
- │ ├── /controllers # Lógica de negocio
534
- │ ├── /models # Modelos Dynamo
535
- │ ├── /routes # Definición de rutas
536
- │ ├── /middlewares # Middlewares custom
537
- │ └── /config # Configuraciones
538
- ├── app.js # Entry point
539
- ├── dev.js # Script desarrollo
540
- ├── .env # Variables de entorno
541
- ├── .env.example # Template de .env
542
- └── package.json
543
- ```
255
+ ```js
256
+ import { LiveCurrent } from 'nicola-framework';
544
257
 
545
- ---
546
-
547
- ## 🚀 Scripts NPM Recomendados
548
-
549
- ```json
550
- {
551
- "scripts": {
552
- "start": "node app.js",
553
- "dev": "node dev.js",
554
- "test": "node --test"
555
- }
556
- }
258
+ const dev = new LiveCurrent('app.js');
259
+ dev.boot();
557
260
  ```
558
261
 
559
262
  ---
560
263
 
561
- ## 🌟 Características Destacadas
562
-
563
- ### Zero Dependencies
564
- A diferencia de Express o Fastify, Nicola no tiene dependencias externas (excepto chalk para logs en desarrollo). Todo está construido con módulos nativos de Node.js.
565
-
566
- ### JWT Nativo
567
- Implementación propia de JWT usando el módulo `crypto` nativo, sin necesidad de jsonwebtoken.
568
-
569
- ### ORM Incluido
570
- No necesitas instalar Sequelize, TypeORM o Prisma. Dynamo viene integrado con soporte para MySQL y PostgreSQL.
571
-
572
- ### Hot Reload Nativo
573
- LiveCurrent detecta cambios en archivos y reinicia el servidor sin necesidad de nodemon o pm2.
574
-
575
- ### Error Handler Visual
576
- BlackBox captura errores y los muestra en una interfaz web elegante con stack trace completo.
577
-
578
- ---
579
-
580
- ## 📊 Comparación con Otros Frameworks
581
-
582
- | Feature | Nicola | Express | Fastify |
583
- |---------|--------|---------|---------|
584
- | Dependencies | 0 | ~50 | ~20 |
585
- | Router | ✅ Incluido | ✅ | ✅ |
586
- | ORM | ✅ Incluido | ❌ | ❌ |
587
- | JWT | ✅ Nativo | ❌ | ❌ |
588
- | Hot Reload | ✅ Nativo | ❌ | ❌ |
589
- | Error UI | ✅ Visual | ❌ | ❌ |
590
- | Validation | ✅ Incluido | ❌ | ✅ |
591
-
592
- ---
593
-
594
264
  ## 🤝 Contribuir
595
265
 
596
- Las contribuciones son bienvenidas. Por favor:
597
-
598
- 1. Fork el proyecto
599
- 2. Crea una rama (`git checkout -b feature/amazing-feature`)
600
- 3. Commit tus cambios (`git commit -m 'Add amazing feature'`)
601
- 4. Push a la rama (`git push origin feature/amazing-feature`)
602
- 5. Abre un Pull Request
266
+ 1. Fork
267
+ 2. Rama feature
268
+ 3. PR
603
269
 
604
270
  ---
605
271
 
606
272
  ## 📝 Licencia
607
273
 
608
- MIT © [Erick Mauricio Tiznado Rodriguez](https://github.com/yourusername)
609
-
610
- ---
611
-
612
- ## 🙏 Agradecimientos
613
-
614
- Inspirado en la filosofía de Nikola Nicola: *"Si quieres encontrar los secretos del universo, piensa en términos de energía, frecuencia y vibración."*
615
-
616
- ---
617
-
618
- ## 📬 Contacto
619
-
620
- - **NPM**: [nicola-framework](https://www.npmjs.com/package/nicola-framework)
621
- - **Issues**: [GitHub Issues](https://github.com/yourusername/nicola-framework/issues)
622
-
623
- ---
624
-
625
- <div align="center">
626
-
627
- ⚡ **Built with electricity and zero dependencies** ⚡
628
-
629
- </div>
274
+ MIT © Erick Mauricio Tiznado Rodriguez