@mkgabri18/mini-serve 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/lib/index.js +3 -0
- package/lib/middlewareRunner.js +41 -0
- package/lib/middlewares/bodyParser.js +52 -0
- package/lib/middlewares/enhancers.js +28 -0
- package/lib/middlewares/errorHandlers.js +16 -0
- package/lib/middlewares/index.js +4 -0
- package/lib/middlewares/logger.js +8 -0
- package/lib/router.js +56 -0
- package/lib/server.js +88 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# mini-serve
|
|
2
|
+
|
|
3
|
+
`mini-serve` è un micro-framework HTTP ultra-leggero e **zero-dependency** per Node.js. È nato come alternativa minimale e nativa a Express per creare API REST, CRUD e server web veloci, mantenendo il pieno controllo sulle performance e sulla configurazione dei middleware.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Indice
|
|
8
|
+
1. [Caratteristiche principali](#caratteristiche-principali)
|
|
9
|
+
2. [Guida: Come usarlo in un nuovo progetto da zero](#guida-come-usarlo-in-un-nuovo-progetto-da-zero)
|
|
10
|
+
3. [Guida all'API](#guida-allapi)
|
|
11
|
+
4. [Gestione dei Middleware](#gestione-dei-middleware)
|
|
12
|
+
5. [Licenza](#licenza)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Caratteristiche principali
|
|
17
|
+
|
|
18
|
+
* 🚀 **Zero dipendenze esterne**: Utilizza esclusivamente i moduli nativi di Node.js (es. `node:http`, `node:fs`).
|
|
19
|
+
* 🛣️ **Router Express-like**: Supporto nativo per rotte HTTP (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) e parametri dinamici nell'URL (es. `/api/users/:id`).
|
|
20
|
+
* ⚙️ **Modularità Opt-In**: I middleware built-in (body parser, request/response enhancers, logging) sono disattivati o attivabili a piacimento.
|
|
21
|
+
* 🛡️ **Leggero e Sicuro**: Include un body parser con limite integrato di 1MB sui payload per prevenire attacchi di tipo DOS.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Guida: Come usarlo in un nuovo progetto da zero
|
|
26
|
+
|
|
27
|
+
Ecco i passaggi da seguire per creare un nuovo progetto ed utilizzare `mini-serve`.
|
|
28
|
+
|
|
29
|
+
### Step 1: Inizializza il progetto Node.js
|
|
30
|
+
Crea una nuova cartella per il tuo progetto e inizializzala tramite il terminale:
|
|
31
|
+
```bash
|
|
32
|
+
mkdir mio-nuovo-progetto
|
|
33
|
+
cd mio-nuovo-progetto
|
|
34
|
+
npm init -y
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Step 2: Abilita i moduli ES (ESM)
|
|
38
|
+
Apri il file `package.json` appena generato e aggiungi la riga `"type": "module"`. Questo passaggio è fondamentale in quanto `mini-serve` utilizza la sintassi moderna degli import di ES6:
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"name": "mio-nuovo-progetto",
|
|
42
|
+
"version": "1.0.0",
|
|
43
|
+
"type": "module",
|
|
44
|
+
"scripts": {
|
|
45
|
+
"start": "node index.js"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Step 3: Installa `mini-serve`
|
|
51
|
+
Installa il pacchetto tramite npm (puoi installarlo localmente o puntare al percorso se lo stai testando localmente):
|
|
52
|
+
```bash
|
|
53
|
+
npm install mini-serve
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Step 4: Crea il file del Server (`index.js`)
|
|
57
|
+
Crea un file chiamato `index.js` nella root del tuo progetto e scrivi il seguente codice di esempio:
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
import http from 'node:http';
|
|
61
|
+
import { createServer } from 'mini-serve';
|
|
62
|
+
import { notFoundHandler, globalErrorHandler } from 'mini-serve/middlewares';
|
|
63
|
+
|
|
64
|
+
// 1. Inizializza il server con le opzioni desiderate
|
|
65
|
+
const app = createServer({
|
|
66
|
+
useEnhancers: true, // Abilita res.json(), res.status() e req.query
|
|
67
|
+
useBodyParser: true, // Parsa automaticamente il JSON per POST/PUT/PATCH
|
|
68
|
+
useLogger: true // Mostra i log delle richieste in console
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 2. Definisci le tue rotte
|
|
72
|
+
app.get('/', (req, res) => {
|
|
73
|
+
res.status(200).json({ message: 'Benvenuto nel mio nuovo server agnostico!' });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Rotta con parametri dinamici
|
|
77
|
+
app.get('/items/:id', (req, res) => {
|
|
78
|
+
const { id } = req.params;
|
|
79
|
+
res.status(200).json({ itemId: id, queryString: req.query });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Rotta POST con gestione del body parificato
|
|
83
|
+
app.post('/items', (req, res) => {
|
|
84
|
+
const payload = req.body;
|
|
85
|
+
res.status(201).json({ created: payload });
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 3. Registra i middleware di fallback per errori
|
|
89
|
+
app.use(notFoundHandler);
|
|
90
|
+
app.use(globalErrorHandler);
|
|
91
|
+
|
|
92
|
+
// 4. Avvia il server tramite il modulo nativo http di Node.js
|
|
93
|
+
const server = http.createServer(app.handler);
|
|
94
|
+
|
|
95
|
+
server.listen(3000, () => {
|
|
96
|
+
console.log('Server avviato con successo su http://localhost:3000');
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Step 5: Avvia il server
|
|
101
|
+
Esegui il server tramite il terminale:
|
|
102
|
+
```bash
|
|
103
|
+
npm start
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Guida all'API
|
|
109
|
+
|
|
110
|
+
### `createServer(options)`
|
|
111
|
+
Crea un'istanza dell'applicazione. Riceve un oggetto di configurazione per i middleware built-in:
|
|
112
|
+
|
|
113
|
+
| Opzione | Tipo | Default | Descrizione |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| `useEnhancers` | `boolean` | `true` | Aggiunge `req.query`, `req.path`, `res.status(code)` e `res.json(data)`. |
|
|
116
|
+
| `useBodyParser` | `boolean` | `true` | Parsa automaticamente i payload JSON in `req.body` (limite max: 1MB). Ritorna `413 Payload Too Large` se superato o `400 Bad Request` in caso di JSON malformato. |
|
|
117
|
+
| `useLogger` | `boolean` | `false` | Stampa a console le richieste ricevute, lo status code e il tempo di elaborazione in ms (es: `[GET] /api/users - 200 (12ms)`). |
|
|
118
|
+
|
|
119
|
+
L'oggetto `app` restituito espone i seguenti metodi:
|
|
120
|
+
- `app.use(middleware)`: Registra un middleware globale o un gestore errori.
|
|
121
|
+
- `app.get(path, ...handlers)`: Registra una rotta GET.
|
|
122
|
+
- `app.post(path, ...handlers)`: Registra una rotta POST.
|
|
123
|
+
- `app.put(path, ...handlers)`: Registra una rotta PUT.
|
|
124
|
+
- `app.delete(path, ...handlers)`: Registra una rotta DELETE.
|
|
125
|
+
- `app.patch(path, ...handlers)`: Registra una rotta PATCH.
|
|
126
|
+
- `app.handler`: Il delegato nativo `(req, res)` da passare a `http.createServer()`.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Gestione dei Middleware
|
|
131
|
+
|
|
132
|
+
I middleware seguono il classico pattern `(req, res, next)`:
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
app.use((req, res, next) => {
|
|
136
|
+
console.log('Richiesta in transito...');
|
|
137
|
+
next(); // Passa al middleware successivo
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Gestione degli Errori globali
|
|
142
|
+
Se passi un errore a `next(err)`, lo stack salterà tutti i middleware standard fino a raggiungere un middleware di errore, identificato dall'avere 4 parametri `(err, req, res, next)`:
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
app.use((err, req, res, next) => {
|
|
146
|
+
console.error(err.stack);
|
|
147
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
148
|
+
res.end(JSON.stringify({ error: 'Errore generico del server' }));
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Puoi anche usare gli handler predefiniti importandoli da sottomodulo:
|
|
153
|
+
```javascript
|
|
154
|
+
import { notFoundHandler, globalErrorHandler } from 'mini-serve/middlewares';
|
|
155
|
+
|
|
156
|
+
app.use(notFoundHandler); // Gestisce i 404 per rotte non registrate
|
|
157
|
+
app.use(globalErrorHandler); // Cattura ed elabora in sicurezza gli errori generici
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Licenza
|
|
163
|
+
|
|
164
|
+
Questo progetto è rilasciato sotto licenza [MIT](LICENSE).
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export function runMiddlewares(middlewares, req, res) {
|
|
2
|
+
function dispatch(i, err) {
|
|
3
|
+
if (i >= middlewares.length) return;
|
|
4
|
+
|
|
5
|
+
const middleware = middlewares[i];
|
|
6
|
+
let called = false;
|
|
7
|
+
|
|
8
|
+
function next(nextErr) {
|
|
9
|
+
if (called) {
|
|
10
|
+
console.error("next() called multiple times");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
called = true;
|
|
14
|
+
dispatch(i + 1, nextErr);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
if (err) {
|
|
19
|
+
// Stiamo gestendo un errore: invochiamo solo gli errori middleware (4 parametri)
|
|
20
|
+
if (middleware.length === 4) {
|
|
21
|
+
Promise.resolve(middleware(err, req, res, next)).catch(next);
|
|
22
|
+
} else {
|
|
23
|
+
// Salta il middleware normale e vai avanti trascinando l'errore
|
|
24
|
+
dispatch(i + 1, err);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
// Funzionamento normale: invochiamo solo i middleware regolari (< 4 parametri)
|
|
28
|
+
if (middleware.length < 4) {
|
|
29
|
+
Promise.resolve(middleware(req, res, next)).catch(next);
|
|
30
|
+
} else {
|
|
31
|
+
// Salta l'error middleware
|
|
32
|
+
dispatch(i + 1, err);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch (caughtErr) {
|
|
36
|
+
next(caughtErr);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
dispatch(0);
|
|
41
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function jsonBodyParser(req, res, next) {
|
|
2
|
+
// Parsiamo il body solo per le richieste che solitamente lo prevedono
|
|
3
|
+
if (["POST", "PUT", "PATCH"].includes(req.method)) {
|
|
4
|
+
let body = "";
|
|
5
|
+
const MAX_SIZE = 1 * 1024 * 1024; // 1 Megabyte
|
|
6
|
+
let limitExceeded = false;
|
|
7
|
+
|
|
8
|
+
req.on("data", chunk => {
|
|
9
|
+
if (limitExceeded) return;
|
|
10
|
+
|
|
11
|
+
body += chunk;
|
|
12
|
+
if (body.length > MAX_SIZE) {
|
|
13
|
+
limitExceeded = true;
|
|
14
|
+
req.pause();
|
|
15
|
+
|
|
16
|
+
// Send 413 Payload Too Large response gracefully
|
|
17
|
+
res.status(413).json({ error: "Payload Too Large" });
|
|
18
|
+
|
|
19
|
+
// Destroy the socket on the next tick so Node has time to flush the response
|
|
20
|
+
setImmediate(() => {
|
|
21
|
+
req.destroy();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
req.on("end", () => {
|
|
27
|
+
if (limitExceeded || req.destroyed) return;
|
|
28
|
+
|
|
29
|
+
if (!body) {
|
|
30
|
+
req.body = {};
|
|
31
|
+
return next();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
req.body = JSON.parse(body);
|
|
36
|
+
next();
|
|
37
|
+
} catch (err) {
|
|
38
|
+
const error = new Error("Invalid JSON Payload");
|
|
39
|
+
error.status = 400; // Bad Request
|
|
40
|
+
next(error);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
req.on("error", (err) => {
|
|
45
|
+
if (limitExceeded) return;
|
|
46
|
+
next(err);
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
// Per le richieste come GET o DELETE, proseguiamo oltre ignorando il body
|
|
50
|
+
next();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function requestResponseEnhancer(req, res, next) {
|
|
2
|
+
// --- ENHANCE REQUEST ---
|
|
3
|
+
// Analizza l'URL includendo anche le query string (es. ?sort=asc)
|
|
4
|
+
const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`);
|
|
5
|
+
|
|
6
|
+
// Salva il path "pulito" da eventuali query string (es. /notes invece di /notes?sort=asc)
|
|
7
|
+
req.path = parsedUrl.pathname;
|
|
8
|
+
|
|
9
|
+
// Salva i parametri estratti (es. { sort: 'asc' })
|
|
10
|
+
req.query = Object.fromEntries(parsedUrl.searchParams);
|
|
11
|
+
|
|
12
|
+
// --- ENHANCE RESPONSE ---
|
|
13
|
+
// Aggiunge la scorciatoia per impostare lo status code a catena
|
|
14
|
+
res.status = function(code) {
|
|
15
|
+
res.statusCode = code;
|
|
16
|
+
return res;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Aggiunge la scorciatoia per inviare JSON con i corretti Headers
|
|
20
|
+
res.json = function(data) {
|
|
21
|
+
if (!res.hasHeader("Content-Type")) {
|
|
22
|
+
res.setHeader("Content-Type", "application/json");
|
|
23
|
+
}
|
|
24
|
+
res.end(JSON.stringify(data));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
next();
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function notFoundHandler(req, res, next) {
|
|
2
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
3
|
+
res.end(JSON.stringify({ error: "Not Found" }));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function globalErrorHandler(err, req, res, next) {
|
|
7
|
+
console.error("Global Error Caught:", err.message || err);
|
|
8
|
+
|
|
9
|
+
if (res.headersSent) {
|
|
10
|
+
return next(err); // Lascia che sia Node a gestire la chiusura forzata
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const statusCode = err.status || 500;
|
|
14
|
+
res.writeHead(statusCode, { "Content-Type": "application/json" });
|
|
15
|
+
res.end(JSON.stringify({ error: err.message || "Internal Server Error" }));
|
|
16
|
+
}
|
package/lib/router.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function route(method, pathDefinition, ...handlers) {
|
|
2
|
+
// Split the path definition into dynamic parameters and static parts,
|
|
3
|
+
// escaping regex special characters in static parts while extracting parameter names.
|
|
4
|
+
const paramNames = [];
|
|
5
|
+
const parts = pathDefinition.split(/(:[a-zA-Z0-9_]+)/);
|
|
6
|
+
const regexParts = parts.map(part => {
|
|
7
|
+
if (part.startsWith(":")) {
|
|
8
|
+
const paramName = part.slice(1);
|
|
9
|
+
paramNames.push(paramName);
|
|
10
|
+
return "([^/]+)";
|
|
11
|
+
}
|
|
12
|
+
// Escape regex characters in static path parts to avoid weak matches (like '.' matching any character)
|
|
13
|
+
return part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14
|
+
});
|
|
15
|
+
const pathRegex = new RegExp(`^${regexParts.join("")}/?$`);
|
|
16
|
+
|
|
17
|
+
return (req, res, next) => {
|
|
18
|
+
if (req.method === method) {
|
|
19
|
+
// Usiamo req.path (pulito dalle query) se disponibile, altrimenti req.url depurato
|
|
20
|
+
const urlToMatch = req.path || req.url.split('?')[0];
|
|
21
|
+
const match = urlToMatch.match(pathRegex);
|
|
22
|
+
|
|
23
|
+
if (match) {
|
|
24
|
+
// Estraiamo i valori dinamici (es. /notes/15 -> req.params.id = "15")
|
|
25
|
+
req.params = {};
|
|
26
|
+
paramNames.forEach((name, index) => {
|
|
27
|
+
req.params[name] = match[index + 1];
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Run route-specific handlers in sequence
|
|
31
|
+
let i = 0;
|
|
32
|
+
const runNext = (err) => {
|
|
33
|
+
if (err) {
|
|
34
|
+
return next(err); // Forward errors directly to global error handler
|
|
35
|
+
}
|
|
36
|
+
if (i < handlers.length) {
|
|
37
|
+
const handler = handlers[i++];
|
|
38
|
+
try {
|
|
39
|
+
Promise.resolve(handler(req, res, runNext)).catch(runNext);
|
|
40
|
+
} catch (caughtErr) {
|
|
41
|
+
runNext(caughtErr);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
next(); // Handlers completed without sending a response, fallback to next outer middleware
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
runNext();
|
|
49
|
+
return; // Interrompiamo qui, la route è stata gestita
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Se non c'è match, passiamo al prossimo middleware della catena
|
|
54
|
+
next();
|
|
55
|
+
};
|
|
56
|
+
}
|
package/lib/server.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { route } from "./router.js";
|
|
2
|
+
import { runMiddlewares } from "./middlewareRunner.js";
|
|
3
|
+
import { requestResponseEnhancer } from "./middlewares/enhancers.js";
|
|
4
|
+
import { jsonBodyParser } from "./middlewares/bodyParser.js";
|
|
5
|
+
import { logger } from "./middlewares/logger.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Factory che crea l'istanza del server mini-serve.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} [options] - Opzioni di configurazione dei middleware built-in.
|
|
11
|
+
* @param {boolean} [options.useEnhancers=true] - Se registrare il middleware che arricchisce req e res.
|
|
12
|
+
* @param {boolean} [options.useBodyParser=true] - Se registrare il parser JSON del body per POST/PUT/PATCH.
|
|
13
|
+
* @param {boolean} [options.useLogger=false] - Se abilitare il logger delle richieste in console.
|
|
14
|
+
* @returns {Object} Istanza dell'applicazione con i metodi per definire le rotte e registrare middleware.
|
|
15
|
+
*/
|
|
16
|
+
export function createServer(options = {}) {
|
|
17
|
+
const {
|
|
18
|
+
useEnhancers = true,
|
|
19
|
+
useBodyParser = true,
|
|
20
|
+
useLogger = false,
|
|
21
|
+
} = options;
|
|
22
|
+
|
|
23
|
+
const middlewares = [];
|
|
24
|
+
|
|
25
|
+
// Registrazione dei middleware built-in in base alle opzioni
|
|
26
|
+
if (useEnhancers) {
|
|
27
|
+
middlewares.push(requestResponseEnhancer);
|
|
28
|
+
}
|
|
29
|
+
if (useBodyParser) {
|
|
30
|
+
middlewares.push(jsonBodyParser);
|
|
31
|
+
}
|
|
32
|
+
if (useLogger) {
|
|
33
|
+
middlewares.push(logger);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const app = {
|
|
37
|
+
/**
|
|
38
|
+
* Registra un middleware generico nello stack.
|
|
39
|
+
*/
|
|
40
|
+
use(fn) {
|
|
41
|
+
middlewares.push(fn);
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Registra una rotta GET.
|
|
46
|
+
*/
|
|
47
|
+
get(path, ...handler) {
|
|
48
|
+
middlewares.push(route("GET", path, ...handler));
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Registra una rotta POST.
|
|
53
|
+
*/
|
|
54
|
+
post(path, ...handler) {
|
|
55
|
+
middlewares.push(route("POST", path, ...handler));
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Registra una rotta PUT.
|
|
60
|
+
*/
|
|
61
|
+
put(path, ...handler) {
|
|
62
|
+
middlewares.push(route("PUT", path, ...handler));
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Registra una rotta DELETE.
|
|
67
|
+
*/
|
|
68
|
+
delete(path, ...handler) {
|
|
69
|
+
middlewares.push(route("DELETE", path, ...handler));
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Registra una rotta PATCH.
|
|
74
|
+
*/
|
|
75
|
+
patch(path, ...handler) {
|
|
76
|
+
middlewares.push(route("PATCH", path, ...handler));
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Il delegato (req, res) da passare a http.createServer().
|
|
81
|
+
*/
|
|
82
|
+
handler(req, res) {
|
|
83
|
+
runMiddlewares(middlewares, req, res);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return app;
|
|
88
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mkgabri18/mini-serve",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A tiny, zero-dependency HTTP framework for Node.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./lib/index.js",
|
|
9
|
+
"./middlewares": "./lib/middlewares/index.js"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/Mkgabri18/mini-serve.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Mkgabri18/mini-serve/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/Mkgabri18/mini-serve#readme",
|
|
19
|
+
"files": [
|
|
20
|
+
"lib"
|
|
21
|
+
],
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "node src/server.js",
|
|
27
|
+
"test": "node --test notes/notes.test.js"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"http",
|
|
31
|
+
"framework",
|
|
32
|
+
"server",
|
|
33
|
+
"middleware",
|
|
34
|
+
"router",
|
|
35
|
+
"zero-dependency"
|
|
36
|
+
],
|
|
37
|
+
"author": "",
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|