koa-classic-server 1.1.0 → 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.
@@ -0,0 +1,395 @@
1
+ # Enhanced Index Option - Esempi Pratici
2
+
3
+ ## ⚠️ Formato Raccomandato: Array
4
+
5
+ **IMPORTANTE:** L'opzione `index` deve essere usata in **formato array**. Il formato stringa è **deprecato** e verrà rimosso in versioni future.
6
+
7
+ ```javascript
8
+ // ✅ RACCOMANDATO
9
+ index: ['index.html']
10
+ index: ['index.html', 'index.htm']
11
+ index: [/index\.html/i]
12
+
13
+ // ⚠️ DEPRECATO (genera warning)
14
+ index: 'index.html' // NON usare! Usa ['index.html'] invece
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Opzione index con RegExp - Casi d'uso reali
20
+
21
+ ### 1. Case-insensitive matching (Windows/Mac filesystems)
22
+
23
+ ```javascript
24
+ const Koa = require('koa');
25
+ const koaClassicServer = require('koa-classic-server');
26
+
27
+ const app = new Koa();
28
+
29
+ // Trova index.html, INDEX.HTML, Index.Html, INDEX.html, etc.
30
+ app.use(koaClassicServer('./public', {
31
+ index: [/index\.html/i]
32
+ }));
33
+
34
+ app.listen(3000);
35
+ ```
36
+
37
+ **Cosa matcha:**
38
+ - `index.html`
39
+ - `INDEX.HTML`
40
+ - `Index.Html`
41
+ - `INDEX.html`
42
+ - `InDeX.HtMl`
43
+
44
+ ---
45
+
46
+ ### 2. Multiple estensioni con case-insensitive
47
+
48
+ ```javascript
49
+ // Trova index.html, index.htm, INDEX.HTML, Index.HTM, etc.
50
+ app.use(koaClassicServer('./public', {
51
+ index: [/index\.(html|htm)/i]
52
+ }));
53
+ ```
54
+
55
+ **Cosa matcha:**
56
+ - `index.html`
57
+ - `index.htm`
58
+ - `INDEX.HTML`
59
+ - `INDEX.HTM`
60
+ - `Index.Html`
61
+ - `Index.Htm`
62
+
63
+ ---
64
+
65
+ ### 3. Template engines con varianti di case
66
+
67
+ ```javascript
68
+ // Trova index.ejs, INDEX.EJS, index.pug, INDEX.PUG, etc.
69
+ app.use(koaClassicServer('./views', {
70
+ index: [
71
+ /index\.ejs/i,
72
+ /index\.pug/i,
73
+ /index\.html/i
74
+ ]
75
+ }));
76
+ ```
77
+
78
+ **Priorità:** Primo match vince
79
+ - Prima cerca: index.ejs, INDEX.EJS, Index.Ejs, etc.
80
+ - Poi cerca: index.pug, INDEX.PUG, Index.Pug, etc.
81
+ - Infine cerca: index.html, INDEX.HTML, Index.Html, etc.
82
+
83
+ ---
84
+
85
+ ### 4. Pattern complessi con numeri
86
+
87
+ ```javascript
88
+ // Trova index.html, index1.html, index2.html, INDEX10.HTML, etc.
89
+ app.use(koaClassicServer('./public', {
90
+ index: [/index\d*\.html/i]
91
+ }));
92
+ ```
93
+
94
+ **Cosa matcha:**
95
+ - `index.html`
96
+ - `index1.html`
97
+ - `index2.html`
98
+ - `index10.html`
99
+ - `INDEX.HTML`
100
+ - `INDEX99.HTML`
101
+
102
+ ---
103
+
104
+ ### 5. Default files con varianti
105
+
106
+ ```javascript
107
+ // Cerca default.html, default.htm, DEFAULT.HTML, etc.
108
+ app.use(koaClassicServer('./public', {
109
+ index: [
110
+ /index\.(html|htm)/i,
111
+ /default\.(html|htm)/i,
112
+ /home\.(html|htm)/i
113
+ ]
114
+ }));
115
+ ```
116
+
117
+ **Priorità:**
118
+ 1. index.html/htm (qualsiasi case)
119
+ 2. default.html/htm (qualsiasi case)
120
+ 3. home.html/htm (qualsiasi case)
121
+
122
+ ---
123
+
124
+ ### 6. Configurazione tipo Apache (mixed string + RegExp)
125
+
126
+ ```javascript
127
+ // Best practice: Stringhe esatte prima, RegExp dopo
128
+ app.use(koaClassicServer('./public', {
129
+ index: [
130
+ 'index.html', // 1. Exact match (più veloce)
131
+ 'index.htm', // 2. Exact match
132
+ /INDEX\.HTML/i, // 3. Case-insensitive fallback
133
+ /default\.html/i // 4. Default fallback
134
+ ]
135
+ }));
136
+ ```
137
+
138
+ **Perché questo ordine:**
139
+ - String matching è più veloce di RegExp
140
+ - Specifico prima (index.html) → generico dopo (/default\.html/i)
141
+
142
+ ---
143
+
144
+ ### 7. Pattern avanzati con gruppi opzionali
145
+
146
+ ```javascript
147
+ // Trova: index, index.html, index.htm, INDEX, INDEX.HTML, etc.
148
+ app.use(koaClassicServer('./public', {
149
+ index: [/index(\.(html|htm))?/i]
150
+ }));
151
+ ```
152
+
153
+ **Cosa matcha:**
154
+ - `index` (senza estensione!)
155
+ - `index.html`
156
+ - `index.htm`
157
+ - `INDEX`
158
+ - `INDEX.HTML`
159
+ - `INDEX.HTM`
160
+
161
+ ---
162
+
163
+ ### 8. Prefissi variabili (multilingua)
164
+
165
+ ```javascript
166
+ // Supporto multilingua: index_en.html, index_it.html, INDEX_FR.HTML, etc.
167
+ app.use(koaClassicServer('./public', {
168
+ index: [
169
+ /index_[a-z]{2}\.html/i, // index_en.html, INDEX_IT.HTML
170
+ /index\.html/i // Fallback
171
+ ]
172
+ }));
173
+ ```
174
+
175
+ **Cosa matcha:**
176
+ - `index_en.html`
177
+ - `index_it.html`
178
+ - `INDEX_FR.HTML`
179
+ - `index.html` (fallback)
180
+
181
+ ---
182
+
183
+ ### 9. Configurazione PHP-like
184
+
185
+ ```javascript
186
+ // Simula configurazione Apache/PHP con DirectoryIndex
187
+ app.use(koaClassicServer('./public', {
188
+ index: [
189
+ 'index.php',
190
+ 'index.html',
191
+ 'index.htm',
192
+ /INDEX\.(PHP|HTML|HTM)/i,
193
+ 'default.php',
194
+ 'default.html'
195
+ ]
196
+ }));
197
+ ```
198
+
199
+ ---
200
+
201
+ ### 10. Solo file che iniziano con "index"
202
+
203
+ ```javascript
204
+ // Matcha qualsiasi file che inizia con "index" (index.*, INDEX.*, Index.*)
205
+ app.use(koaClassicServer('./public', {
206
+ index: [/^index\./i]
207
+ }));
208
+ ```
209
+
210
+ **Cosa matcha:**
211
+ - `index.html`
212
+ - `index.php`
213
+ - `index.ejs`
214
+ - `INDEX.CSS` (attenzione!)
215
+ - `Index.Anything`
216
+
217
+ ---
218
+
219
+ ## Performance Tips
220
+
221
+ ### ✅ Best Practice: String prima, RegExp dopo
222
+
223
+ ```javascript
224
+ // VELOCE ⚡
225
+ index: [
226
+ 'index.html', // String match = O(1)
227
+ 'index.htm', // String match = O(1)
228
+ /INDEX\.HTML/i // RegExp match = O(n)
229
+ ]
230
+
231
+ // LENTO 🐌
232
+ index: [
233
+ /index\.html/i, // RegExp match = O(n)
234
+ /index\.htm/i, // RegExp match = O(n)
235
+ 'index.html' // Mai raggiunto!
236
+ ]
237
+ ```
238
+
239
+ ### ✅ Pattern specifici prima, generici dopo
240
+
241
+ ```javascript
242
+ // CORRETTO ✓
243
+ index: [
244
+ /^index\.html$/i, // Specifico: solo index.html
245
+ /^index\./i, // Generico: qualsiasi index.*
246
+ /\.(html|htm)$/i // Molto generico: qualsiasi .html/.htm
247
+ ]
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Validazione automatica
253
+
254
+ Il middleware filtra automaticamente elementi non validi:
255
+
256
+ ```javascript
257
+ app.use(koaClassicServer('./public', {
258
+ index: [
259
+ 'index.html', // ✓ Valid: string
260
+ /index\.htm/i, // ✓ Valid: RegExp
261
+ 123, // ✗ Filtrato: number
262
+ null, // ✗ Filtrato: null
263
+ undefined, // ✗ Filtrato: undefined
264
+ {}, // ✗ Filtrato: object
265
+ 'default.html' // ✓ Valid: string
266
+ ]
267
+ }));
268
+
269
+ // Risultato effettivo: ['index.html', /index\.htm/i, 'default.html']
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Testing
275
+
276
+ Per testare le tue configurazioni:
277
+
278
+ ```javascript
279
+ const fs = require('fs');
280
+ const path = require('path');
281
+
282
+ // Crea file di test con vari case
283
+ const testDir = './test-index';
284
+ fs.mkdirSync(testDir, { recursive: true });
285
+ fs.writeFileSync(path.join(testDir, 'index.html'), '<h1>Found index.html</h1>');
286
+ fs.writeFileSync(path.join(testDir, 'INDEX.HTML'), '<h1>Found INDEX.HTML</h1>');
287
+ fs.writeFileSync(path.join(testDir, 'Index.Html'), '<h1>Found Index.Html</h1>');
288
+
289
+ // Testa quale viene trovato per primo
290
+ app.use(koaClassicServer(testDir, {
291
+ index: [/index\.html/i]
292
+ }));
293
+
294
+ // Apri http://localhost:3000 e verifica quale file viene servito
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Casi Edge
300
+
301
+ ### File multipli con stesso pattern
302
+
303
+ Se ci sono più file che matchano lo stesso pattern, viene servito **il primo trovato nell'ordine di lettura della directory** (dipende dal filesystem):
304
+
305
+ ```javascript
306
+ // Directory contiene: index.html, INDEX.HTML, Index.Html
307
+ app.use(koaClassicServer('./public', {
308
+ index: [/index\.html/i]
309
+ }));
310
+
311
+ // Risultato: Uno dei tre file (ordine non garantito)
312
+ // Per controllo deterministico, usa stringhe esatte
313
+ ```
314
+
315
+ ### Pattern che matchano troppo
316
+
317
+ ```javascript
318
+ // ⚠️ ATTENZIONE: Pattern troppo generico!
319
+ app.use(koaClassicServer('./public', {
320
+ index: [/index/i] // Matcha anche: "my_index.txt", "reindex.html"
321
+ }));
322
+
323
+ // ✓ MEGLIO: Pattern specifico
324
+ app.use(koaClassicServer('./public', {
325
+ index: [/^index\./i] // Matcha solo: "index.*"
326
+ }));
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Esempio Completo Real-World
332
+
333
+ ```javascript
334
+ const Koa = require('koa');
335
+ const koaClassicServer = require('koa-classic-server');
336
+
337
+ const app = new Koa();
338
+
339
+ // Configurazione production-ready
340
+ app.use(koaClassicServer('./public', {
341
+ method: ['GET', 'HEAD'],
342
+ showDirContents: true,
343
+
344
+ // Index configuration con fallback multipli
345
+ index: [
346
+ // 1. Exact matches (fastest)
347
+ 'index.html',
348
+ 'index.htm',
349
+
350
+ // 2. Case-insensitive fallbacks
351
+ /INDEX\.HTML/i,
352
+ /INDEX\.HTM/i,
353
+
354
+ // 3. Default files
355
+ /default\.(html|htm)/i,
356
+
357
+ // 4. Home fallback
358
+ /home\.html/i
359
+ ],
360
+
361
+ // HTTP Caching
362
+ enableCaching: true,
363
+ cacheMaxAge: 3600,
364
+
365
+ // URL configuration
366
+ urlPrefix: '/static',
367
+ urlsReserved: ['/api', '/auth']
368
+ }));
369
+
370
+ app.listen(3000, () => {
371
+ console.log('🚀 Server running on http://localhost:3000');
372
+ console.log('📁 Static files: http://localhost:3000/static');
373
+ });
374
+ ```
375
+
376
+ ---
377
+
378
+ ## Supporto completo
379
+
380
+ L'opzione `index` supporta:
381
+
382
+ | Tipo | Esempio | Caso d'uso | Stato |
383
+ |------|---------|------------|-------|
384
+ | **Array di stringhe** | `["index.html", "index.htm"]` | Priorità definita, performance ottimale | ✅ **Raccomandato** |
385
+ | **Array di RegExp** | `[/index\.html/i, /default\.htm/i]` | Pattern multipli, case-insensitive | ✅ **Raccomandato** |
386
+ | **Mixed array** | `["index.html", /INDEX\.HTM/i]` | Best of both worlds | ✅ **Raccomandato** |
387
+ | ~~String~~ | ~~`"index.html"`~~ | Singolo file | ⚠️ **DEPRECATO** |
388
+
389
+ **Nota:** Il formato stringa (`"index.html"`) è deprecato e genera un warning. Verrà rimosso in versioni future. Usa il formato array `["index.html"]` invece.
390
+
391
+ ---
392
+
393
+ **Documentazione completa:** `index.cjs:28-48`
394
+ **Implementazione:** `index.cjs:205-250` (funzione `findIndexFile`)
395
+ **Test suite:** `__tests__/index-option.test.js` (19 test cases)