@mkgabri18/mini-serve 0.1.0 → 0.1.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
@@ -1,44 +1,44 @@
1
1
  # mini-serve
2
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.
3
+ `mini-serve` is an ultra-lightweight, **zero-dependency** HTTP framework for Node.js. It is designed as a minimal, native alternative to Express for building REST APIs, CRUD services, and web servers while maintaining full control over performance and middleware configuration.
4
4
 
5
5
  ---
6
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)
7
+ ## Table of Contents
8
+ 1. [Key Features](#key-features)
9
+ 2. [Guide: How to Use It in a New Project from Scratch](#guide-how-to-use-it-in-a-new-project-from-scratch)
10
+ 3. [API Guide](#api-guide)
11
+ 4. [Middleware Management](#middleware-management)
12
+ 5. [License](#license)
13
13
 
14
14
  ---
15
15
 
16
- ## Caratteristiche principali
16
+ ## Key Features
17
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.
18
+ * 🚀 **Zero external dependencies**: Built entirely on top of Node.js native modules (e.g. `node:http`, `node:fs`).
19
+ * 🛣️ **Express-like Router**: Native support for HTTP methods (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) and dynamic path parameters (e.g. `/api/users/:id`).
20
+ * ⚙️ **Opt-In Modularity**: Built-in middlewares (body parser, request/response enhancers, logger) are configurable and can be enabled or disabled at will.
21
+ * 🛡️ **Lightweight & Secure**: Includes a built-in JSON body parser with a default 1MB size limit to prevent potential DOS attacks.
22
22
 
23
23
  ---
24
24
 
25
- ## Guida: Come usarlo in un nuovo progetto da zero
25
+ ## Guide: How to Use It in a New Project from Scratch
26
26
 
27
- Ecco i passaggi da seguire per creare un nuovo progetto ed utilizzare `mini-serve`.
27
+ Follow these steps to create a new project and use `mini-serve`.
28
28
 
29
- ### Step 1: Inizializza il progetto Node.js
30
- Crea una nuova cartella per il tuo progetto e inizializzala tramite il terminale:
29
+ ### Step 1: Initialize the Node.js project
30
+ Create a new directory for your project and initialize it via terminal:
31
31
  ```bash
32
- mkdir mio-nuovo-progetto
33
- cd mio-nuovo-progetto
32
+ mkdir my-new-project
33
+ cd my-new-project
34
34
  npm init -y
35
35
  ```
36
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:
37
+ ### Step 2: Enable ES Modules (ESM)
38
+ Open the newly generated `package.json` file and add the `"type": "module"` property. This step is critical since `mini-serve` uses modern ES6 import syntax:
39
39
  ```json
40
40
  {
41
- "name": "mio-nuovo-progetto",
41
+ "name": "my-new-project",
42
42
  "version": "1.0.0",
43
43
  "type": "module",
44
44
  "scripts": {
@@ -47,118 +47,118 @@ Apri il file `package.json` appena generato e aggiungi la riga `"type": "module"
47
47
  }
48
48
  ```
49
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):
50
+ ### Step 3: Install `@mkgabri18/mini-serve`
51
+ Install the package using npm:
52
52
  ```bash
53
- npm install mini-serve
53
+ npm install @mkgabri18/mini-serve
54
54
  ```
55
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:
56
+ ### Step 4: Create the Server File (`index.js`)
57
+ Create a file named `index.js` in the root of your project and add the following sample code:
58
58
 
59
59
  ```javascript
60
60
  import http from 'node:http';
61
- import { createServer } from 'mini-serve';
62
- import { notFoundHandler, globalErrorHandler } from 'mini-serve/middlewares';
61
+ import { createServer } from '@mkgabri18/mini-serve';
62
+ import { notFoundHandler, globalErrorHandler } from '@mkgabri18/mini-serve/middlewares';
63
63
 
64
- // 1. Inizializza il server con le opzioni desiderate
64
+ // 1. Initialize the server with the desired options
65
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
66
+ useEnhancers: true, // Enables res.json(), res.status(), and req.query
67
+ useBodyParser: true, // Automatically parses JSON body for POST/PUT/PATCH
68
+ useLogger: true // Logs requests to the console
69
69
  });
70
70
 
71
- // 2. Definisci le tue rotte
71
+ // 2. Define your routes
72
72
  app.get('/', (req, res) => {
73
- res.status(200).json({ message: 'Benvenuto nel mio nuovo server agnostico!' });
73
+ res.status(200).json({ message: 'Welcome to my new agnostic server!' });
74
74
  });
75
75
 
76
- // Rotta con parametri dinamici
76
+ // Route with dynamic path parameters
77
77
  app.get('/items/:id', (req, res) => {
78
78
  const { id } = req.params;
79
79
  res.status(200).json({ itemId: id, queryString: req.query });
80
80
  });
81
81
 
82
- // Rotta POST con gestione del body parificato
82
+ // POST route with body parser support
83
83
  app.post('/items', (req, res) => {
84
84
  const payload = req.body;
85
85
  res.status(201).json({ created: payload });
86
86
  });
87
87
 
88
- // 3. Registra i middleware di fallback per errori
88
+ // 3. Register fallback and error handling middlewares
89
89
  app.use(notFoundHandler);
90
90
  app.use(globalErrorHandler);
91
91
 
92
- // 4. Avvia il server tramite il modulo nativo http di Node.js
92
+ // 4. Start the server using Node.js native http module
93
93
  const server = http.createServer(app.handler);
94
94
 
95
95
  server.listen(3000, () => {
96
- console.log('Server avviato con successo su http://localhost:3000');
96
+ console.log('Server successfully started at http://localhost:3000');
97
97
  });
98
98
  ```
99
99
 
100
- ### Step 5: Avvia il server
101
- Esegui il server tramite il terminale:
100
+ ### Step 5: Start the server
101
+ Run the server using your terminal:
102
102
  ```bash
103
103
  npm start
104
104
  ```
105
105
 
106
106
  ---
107
107
 
108
- ## Guida all'API
108
+ ## API Guide
109
109
 
110
110
  ### `createServer(options)`
111
- Crea un'istanza dell'applicazione. Riceve un oggetto di configurazione per i middleware built-in:
111
+ Creates an application instance. Accepts a configuration object for built-in middlewares:
112
112
 
113
- | Opzione | Tipo | Default | Descrizione |
113
+ | Option | Type | Default | Description |
114
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()`.
115
+ | `useEnhancers` | `boolean` | `true` | Injects `req.query`, `req.path`, `res.status(code)`, and `res.json(data)`. |
116
+ | `useBodyParser` | `boolean` | `true` | Automatically parses JSON payloads into `req.body` (max limit: 1MB). Returns `413 Payload Too Large` if exceeded, or `400 Bad Request` if JSON is malformed. |
117
+ | `useLogger` | `boolean` | `false` | Logs incoming requests, status code, and execution time in ms (e.g.: `[GET] /api/users - 200 (12ms)`). |
118
+
119
+ The returned `app` object exposes the following methods:
120
+ - `app.use(middleware)`: Registers a global middleware or an error-handling middleware.
121
+ - `app.get(path, ...handlers)`: Registers a GET route.
122
+ - `app.post(path, ...handlers)`: Registers a POST route.
123
+ - `app.put(path, ...handlers)`: Registers a PUT route.
124
+ - `app.delete(path, ...handlers)`: Registers a DELETE route.
125
+ - `app.patch(path, ...handlers)`: Registers a PATCH route.
126
+ - `app.handler`: The native callback `(req, res)` to pass to `http.createServer()`.
127
127
 
128
128
  ---
129
129
 
130
- ## Gestione dei Middleware
130
+ ## Middleware Management
131
131
 
132
- I middleware seguono il classico pattern `(req, res, next)`:
132
+ Middlewares follow the standard `(req, res, next)` pattern:
133
133
 
134
134
  ```javascript
135
135
  app.use((req, res, next) => {
136
- console.log('Richiesta in transito...');
137
- next(); // Passa al middleware successivo
136
+ console.log('Request received...');
137
+ next(); // Pass control to the next middleware
138
138
  });
139
139
  ```
140
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)`:
141
+ ### Global Error Handling
142
+ If you pass an error to `next(err)`, the middleware runner skips all standard middlewares to execute error-handling middlewares, which are identified by having 4 arguments `(err, req, res, next)`:
143
143
 
144
144
  ```javascript
145
145
  app.use((err, req, res, next) => {
146
146
  console.error(err.stack);
147
147
  res.writeHead(500, { 'Content-Type': 'application/json' });
148
- res.end(JSON.stringify({ error: 'Errore generico del server' }));
148
+ res.end(JSON.stringify({ error: 'Internal Server Error' }));
149
149
  });
150
150
  ```
151
151
 
152
- Puoi anche usare gli handler predefiniti importandoli da sottomodulo:
152
+ You can also import and use the pre-built error handlers from their submodule:
153
153
  ```javascript
154
- import { notFoundHandler, globalErrorHandler } from 'mini-serve/middlewares';
154
+ import { notFoundHandler, globalErrorHandler } from '@mkgabri18/mini-serve/middlewares';
155
155
 
156
- app.use(notFoundHandler); // Gestisce i 404 per rotte non registrate
157
- app.use(globalErrorHandler); // Cattura ed elabora in sicurezza gli errori generici
156
+ app.use(notFoundHandler); // Handles 404 for unregistered routes
157
+ app.use(globalErrorHandler); // Safely catches and processes uncaught errors
158
158
  ```
159
159
 
160
160
  ---
161
161
 
162
- ## Licenza
162
+ ## License
163
163
 
164
- Questo progetto è rilasciato sotto licenza [MIT](LICENSE).
164
+ This project is licensed under the [MIT](LICENSE) License.
@@ -16,19 +16,19 @@ export function runMiddlewares(middlewares, req, res) {
16
16
 
17
17
  try {
18
18
  if (err) {
19
- // Stiamo gestendo un errore: invochiamo solo gli errori middleware (4 parametri)
19
+ // We are handling an error: invoke error-handling middlewares only (4 arguments)
20
20
  if (middleware.length === 4) {
21
21
  Promise.resolve(middleware(err, req, res, next)).catch(next);
22
22
  } else {
23
- // Salta il middleware normale e vai avanti trascinando l'errore
23
+ // Skip normal middleware and continue passing down the error
24
24
  dispatch(i + 1, err);
25
25
  }
26
26
  } else {
27
- // Funzionamento normale: invochiamo solo i middleware regolari (< 4 parametri)
27
+ // Normal flow: invoke regular middlewares only (< 4 arguments)
28
28
  if (middleware.length < 4) {
29
29
  Promise.resolve(middleware(req, res, next)).catch(next);
30
30
  } else {
31
- // Salta l'error middleware
31
+ // Skip error-handling middleware
32
32
  dispatch(i + 1, err);
33
33
  }
34
34
  }
@@ -1,5 +1,5 @@
1
1
  export function jsonBodyParser(req, res, next) {
2
- // Parsiamo il body solo per le richieste che solitamente lo prevedono
2
+ // Parse the body only for requests that are expected to contain it
3
3
  if (["POST", "PUT", "PATCH"].includes(req.method)) {
4
4
  let body = "";
5
5
  const MAX_SIZE = 1 * 1024 * 1024; // 1 Megabyte
@@ -46,7 +46,7 @@ export function jsonBodyParser(req, res, next) {
46
46
  next(err);
47
47
  });
48
48
  } else {
49
- // Per le richieste come GET o DELETE, proseguiamo oltre ignorando il body
49
+ // For requests like GET or DELETE, proceed ignoring the body
50
50
  next();
51
51
  }
52
52
  }
@@ -1,22 +1,22 @@
1
1
  export function requestResponseEnhancer(req, res, next) {
2
2
  // --- ENHANCE REQUEST ---
3
- // Analizza l'URL includendo anche le query string (es. ?sort=asc)
3
+ // Parse URL including query parameters (e.g. ?sort=asc)
4
4
  const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`);
5
5
 
6
- // Salva il path "pulito" da eventuali query string (es. /notes invece di /notes?sort=asc)
6
+ // Save pathname stripped of query strings (e.g. /notes instead of /notes?sort=asc)
7
7
  req.path = parsedUrl.pathname;
8
8
 
9
- // Salva i parametri estratti (es. { sort: 'asc' })
9
+ // Save query parameters as an object (e.g. { sort: 'asc' })
10
10
  req.query = Object.fromEntries(parsedUrl.searchParams);
11
11
 
12
12
  // --- ENHANCE RESPONSE ---
13
- // Aggiunge la scorciatoia per impostare lo status code a catena
13
+ // Adds chainable status code shortcut
14
14
  res.status = function(code) {
15
15
  res.statusCode = code;
16
16
  return res;
17
17
  };
18
18
 
19
- // Aggiunge la scorciatoia per inviare JSON con i corretti Headers
19
+ // Adds json helper method to send responses with appropriate Headers
20
20
  res.json = function(data) {
21
21
  if (!res.hasHeader("Content-Type")) {
22
22
  res.setHeader("Content-Type", "application/json");
@@ -7,7 +7,7 @@ export function globalErrorHandler(err, req, res, next) {
7
7
  console.error("Global Error Caught:", err.message || err);
8
8
 
9
9
  if (res.headersSent) {
10
- return next(err); // Lascia che sia Node a gestire la chiusura forzata
10
+ return next(err); // Let Node handle the connection termination
11
11
  }
12
12
 
13
13
  const statusCode = err.status || 500;
package/lib/router.js CHANGED
@@ -16,12 +16,12 @@ export function route(method, pathDefinition, ...handlers) {
16
16
 
17
17
  return (req, res, next) => {
18
18
  if (req.method === method) {
19
- // Usiamo req.path (pulito dalle query) se disponibile, altrimenti req.url depurato
19
+ // Use req.path (cleaned of query params) if available, otherwise sanitized req.url
20
20
  const urlToMatch = req.path || req.url.split('?')[0];
21
21
  const match = urlToMatch.match(pathRegex);
22
22
 
23
23
  if (match) {
24
- // Estraiamo i valori dinamici (es. /notes/15 -> req.params.id = "15")
24
+ // Extract dynamic parameters (e.g., /notes/15 -> req.params.id = "15")
25
25
  req.params = {};
26
26
  paramNames.forEach((name, index) => {
27
27
  req.params[name] = match[index + 1];
@@ -46,11 +46,11 @@ export function route(method, pathDefinition, ...handlers) {
46
46
  };
47
47
 
48
48
  runNext();
49
- return; // Interrompiamo qui, la route è stata gestita
49
+ return; // Stop here, route has been matched and handled
50
50
  }
51
51
  }
52
52
 
53
- // Se non c'è match, passiamo al prossimo middleware della catena
53
+ // If no match is found, proceed to the next middleware in the chain
54
54
  next();
55
55
  };
56
56
  }
package/lib/server.js CHANGED
@@ -5,13 +5,13 @@ import { jsonBodyParser } from "./middlewares/bodyParser.js";
5
5
  import { logger } from "./middlewares/logger.js";
6
6
 
7
7
  /**
8
- * Factory che crea l'istanza del server mini-serve.
8
+ * Factory that creates the mini-serve server instance.
9
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.
10
+ * @param {Object} [options] - Configuration options for built-in middlewares.
11
+ * @param {boolean} [options.useEnhancers=true] - Whether to register the middleware that enhances req and res.
12
+ * @param {boolean} [options.useBodyParser=true] - Whether to register the JSON body parser for POST/PUT/PATCH.
13
+ * @param {boolean} [options.useLogger=false] - Whether to enable the request logger in console.
14
+ * @returns {Object} Application instance with methods to define routes and register middlewares.
15
15
  */
16
16
  export function createServer(options = {}) {
17
17
  const {
@@ -22,7 +22,7 @@ export function createServer(options = {}) {
22
22
 
23
23
  const middlewares = [];
24
24
 
25
- // Registrazione dei middleware built-in in base alle opzioni
25
+ // Register built-in middlewares based on options
26
26
  if (useEnhancers) {
27
27
  middlewares.push(requestResponseEnhancer);
28
28
  }
@@ -35,49 +35,49 @@ export function createServer(options = {}) {
35
35
 
36
36
  const app = {
37
37
  /**
38
- * Registra un middleware generico nello stack.
38
+ * Registers a generic middleware in the stack.
39
39
  */
40
40
  use(fn) {
41
41
  middlewares.push(fn);
42
42
  },
43
43
 
44
44
  /**
45
- * Registra una rotta GET.
45
+ * Registers a GET route.
46
46
  */
47
47
  get(path, ...handler) {
48
48
  middlewares.push(route("GET", path, ...handler));
49
49
  },
50
50
 
51
51
  /**
52
- * Registra una rotta POST.
52
+ * Registers a POST route.
53
53
  */
54
54
  post(path, ...handler) {
55
55
  middlewares.push(route("POST", path, ...handler));
56
56
  },
57
57
 
58
58
  /**
59
- * Registra una rotta PUT.
59
+ * Registers a PUT route.
60
60
  */
61
61
  put(path, ...handler) {
62
62
  middlewares.push(route("PUT", path, ...handler));
63
63
  },
64
64
 
65
65
  /**
66
- * Registra una rotta DELETE.
66
+ * Registers a DELETE route.
67
67
  */
68
68
  delete(path, ...handler) {
69
69
  middlewares.push(route("DELETE", path, ...handler));
70
70
  },
71
71
 
72
72
  /**
73
- * Registra una rotta PATCH.
73
+ * Registers a PATCH route.
74
74
  */
75
75
  patch(path, ...handler) {
76
76
  middlewares.push(route("PATCH", path, ...handler));
77
77
  },
78
78
 
79
79
  /**
80
- * Il delegato (req, res) da passare a http.createServer().
80
+ * The delegate (req, res) to pass to http.createServer().
81
81
  */
82
82
  handler(req, res) {
83
83
  runMiddlewares(middlewares, req, res);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mkgabri18/mini-serve",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A tiny, zero-dependency HTTP framework for Node.js",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -36,4 +36,4 @@
36
36
  ],
37
37
  "author": "",
38
38
  "license": "MIT"
39
- }
39
+ }