koa-classic-server 1.2.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,178 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Setup script for performance benchmarks
5
+ * Creates test files and directories for realistic performance testing
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const BENCHMARK_DIR = path.join(__dirname, '../benchmark-data');
12
+
13
+ console.log('πŸ”§ Setting up benchmark environment...\n');
14
+
15
+ // Clean up old benchmark data
16
+ if (fs.existsSync(BENCHMARK_DIR)) {
17
+ console.log('Cleaning old benchmark data...');
18
+ fs.rmSync(BENCHMARK_DIR, { recursive: true, force: true });
19
+ }
20
+
21
+ // Create benchmark directory
22
+ fs.mkdirSync(BENCHMARK_DIR, { recursive: true });
23
+
24
+ // Create small files (1KB each)
25
+ console.log('Creating small files (1KB each)...');
26
+ const smallDir = path.join(BENCHMARK_DIR, 'small-files');
27
+ fs.mkdirSync(smallDir);
28
+ for (let i = 1; i <= 100; i++) {
29
+ const content = 'X'.repeat(1024); // 1KB
30
+ fs.writeFileSync(path.join(smallDir, `file-${i}.txt`), content);
31
+ }
32
+ console.log(`βœ“ Created 100 small files (1KB each) = 100KB total`);
33
+
34
+ // Create medium files (100KB each)
35
+ console.log('Creating medium files (100KB each)...');
36
+ const mediumDir = path.join(BENCHMARK_DIR, 'medium-files');
37
+ fs.mkdirSync(mediumDir);
38
+ for (let i = 1; i <= 50; i++) {
39
+ const content = 'X'.repeat(100 * 1024); // 100KB
40
+ fs.writeFileSync(path.join(mediumDir, `file-${i}.txt`), content);
41
+ }
42
+ console.log(`βœ“ Created 50 medium files (100KB each) = 5MB total`);
43
+
44
+ // Create large files (1MB each)
45
+ console.log('Creating large files (1MB each)...');
46
+ const largeDir = path.join(BENCHMARK_DIR, 'large-files');
47
+ fs.mkdirSync(largeDir);
48
+ for (let i = 1; i <= 10; i++) {
49
+ const content = 'X'.repeat(1024 * 1024); // 1MB
50
+ fs.writeFileSync(path.join(largeDir, `file-${i}.txt`), content);
51
+ }
52
+ console.log(`βœ“ Created 10 large files (1MB each) = 10MB total`);
53
+
54
+ // Create directory with many files for listing test
55
+ console.log('Creating large directory (1000 files)...');
56
+ const largeDirListing = path.join(BENCHMARK_DIR, 'large-directory');
57
+ fs.mkdirSync(largeDirListing);
58
+ for (let i = 1; i <= 1000; i++) {
59
+ const content = `File number ${i}\n`;
60
+ fs.writeFileSync(path.join(largeDirListing, `item-${String(i).padStart(4, '0')}.txt`), content);
61
+ }
62
+ console.log(`βœ“ Created directory with 1000 files`);
63
+
64
+ // Create directory with very many files (10,000) for stress test
65
+ console.log('Creating very large directory (10,000 files) - this may take a while...');
66
+ const veryLargeDirListing = path.join(BENCHMARK_DIR, 'very-large-directory');
67
+ fs.mkdirSync(veryLargeDirListing);
68
+ for (let i = 1; i <= 10000; i++) {
69
+ const content = `File number ${i}\n`;
70
+ fs.writeFileSync(path.join(veryLargeDirListing, `item-${String(i).padStart(5, '0')}.txt`), content);
71
+ if (i % 1000 === 0) {
72
+ process.stdout.write(` Progress: ${i}/10000 files created...\r`);
73
+ }
74
+ }
75
+ console.log(`βœ“ Created directory with 10,000 files `);
76
+
77
+ // Create HTML file for caching test
78
+ console.log('Creating HTML files for caching test...');
79
+ const htmlContent = `<!DOCTYPE html>
80
+ <html>
81
+ <head>
82
+ <meta charset="UTF-8">
83
+ <title>Benchmark Test Page</title>
84
+ <style>
85
+ body { font-family: Arial, sans-serif; margin: 40px; }
86
+ h1 { color: #333; }
87
+ p { line-height: 1.6; }
88
+ </style>
89
+ </head>
90
+ <body>
91
+ <h1>Benchmark Test Page</h1>
92
+ <p>${'Lorem ipsum dolor sit amet. '.repeat(100)}</p>
93
+ </body>
94
+ </html>`;
95
+ fs.writeFileSync(path.join(BENCHMARK_DIR, 'test.html'), htmlContent);
96
+ console.log(`βœ“ Created HTML file for caching test`);
97
+
98
+ // Create CSS file
99
+ const cssContent = `
100
+ body {
101
+ margin: 0;
102
+ padding: 20px;
103
+ font-family: system-ui, -apple-system, sans-serif;
104
+ }
105
+ ${'h1 { color: #333; }\n'.repeat(50)}
106
+ `.trim();
107
+ fs.writeFileSync(path.join(BENCHMARK_DIR, 'style.css'), cssContent);
108
+ console.log(`βœ“ Created CSS file`);
109
+
110
+ // Create JS file
111
+ const jsContent = `
112
+ function benchmark() {
113
+ console.log('Benchmark test');
114
+ ${'console.log("test");\n'.repeat(100)}
115
+ }
116
+ `.trim();
117
+ fs.writeFileSync(path.join(BENCHMARK_DIR, 'script.js'), jsContent);
118
+ console.log(`βœ“ Created JS file`);
119
+
120
+ // Create nested directory structure
121
+ console.log('Creating nested directory structure...');
122
+ const nestedBase = path.join(BENCHMARK_DIR, 'nested');
123
+ fs.mkdirSync(nestedBase);
124
+ for (let depth = 1; depth <= 5; depth++) {
125
+ const dirPath = path.join(nestedBase, ...Array(depth).fill('level'));
126
+ fs.mkdirSync(dirPath, { recursive: true });
127
+ for (let i = 1; i <= 10; i++) {
128
+ fs.writeFileSync(
129
+ path.join(dirPath, `file-depth${depth}-${i}.txt`),
130
+ `Depth ${depth}, File ${i}\n`
131
+ );
132
+ }
133
+ }
134
+ console.log(`βœ“ Created nested directory structure (5 levels deep)`);
135
+
136
+ // Create .gitignore for benchmark-data
137
+ const gitignorePath = path.join(BENCHMARK_DIR, '.gitignore');
138
+ fs.writeFileSync(gitignorePath, '*\n');
139
+ console.log(`βœ“ Created .gitignore to exclude benchmark data from git`);
140
+
141
+ // Summary
142
+ console.log('\nβœ… Benchmark environment setup complete!\n');
143
+ console.log('Directory structure:');
144
+ console.log(' benchmark-data/');
145
+ console.log(' β”œβ”€β”€ small-files/ (100 files Γ— 1KB = 100KB)');
146
+ console.log(' β”œβ”€β”€ medium-files/ (50 files Γ— 100KB = 5MB)');
147
+ console.log(' β”œβ”€β”€ large-files/ (10 files Γ— 1MB = 10MB)');
148
+ console.log(' β”œβ”€β”€ large-directory/ (1,000 files for listing test)');
149
+ console.log(' β”œβ”€β”€ very-large-directory/ (10,000 files for stress test)');
150
+ console.log(' β”œβ”€β”€ nested/ (5 levels deep, 10 files each)');
151
+ console.log(' β”œβ”€β”€ test.html (HTML for caching test)');
152
+ console.log(' β”œβ”€β”€ style.css (CSS file)');
153
+ console.log(' └── script.js (JS file)');
154
+
155
+ const stats = getDirSize(BENCHMARK_DIR);
156
+ console.log(`\nTotal size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
157
+ console.log(`Total files: ${stats.files}`);
158
+
159
+ function getDirSize(dir) {
160
+ let totalSize = 0;
161
+ let totalFiles = 0;
162
+
163
+ function traverse(currentPath) {
164
+ const items = fs.readdirSync(currentPath, { withFileTypes: true });
165
+ for (const item of items) {
166
+ const fullPath = path.join(currentPath, item.name);
167
+ if (item.isDirectory()) {
168
+ traverse(fullPath);
169
+ } else {
170
+ totalSize += fs.statSync(fullPath).size;
171
+ totalFiles++;
172
+ }
173
+ }
174
+ }
175
+
176
+ traverse(dir);
177
+ return { size: totalSize, files: totalFiles };
178
+ }
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Quick test: RegExp index option
5
+ */
6
+
7
+ const Koa = require('koa');
8
+ const koaClassicServer = require('./index.cjs');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const http = require('http');
12
+
13
+ // Crea directory di test
14
+ const testDir = path.join(__dirname, 'test-regex-temp');
15
+ if (fs.existsSync(testDir)) {
16
+ fs.readdirSync(testDir).forEach(file => {
17
+ fs.unlinkSync(path.join(testDir, file));
18
+ });
19
+ fs.rmdirSync(testDir);
20
+ }
21
+ fs.mkdirSync(testDir);
22
+
23
+ // Test case 1: Case-insensitive matching
24
+ console.log('\nπŸ“‹ TEST 1: Case-insensitive /index\\.html/i\n');
25
+ console.log('File creati:');
26
+ console.log(' - INDEX.HTML (maiuscolo)');
27
+ console.log(' - other.txt\n');
28
+
29
+ fs.writeFileSync(path.join(testDir, 'INDEX.HTML'), '<h1>INDEX.HTML (MAIUSCOLO)</h1>');
30
+ fs.writeFileSync(path.join(testDir, 'other.txt'), 'altro file');
31
+
32
+ const app1 = new Koa();
33
+ app1.use(koaClassicServer(testDir, {
34
+ index: [/index\.html/i] // ← REGEXP CASE-INSENSITIVE!
35
+ }));
36
+
37
+ const server1 = app1.listen(9001);
38
+
39
+ // Test la richiesta
40
+ setTimeout(() => {
41
+ http.get('http://localhost:9001/', (res) => {
42
+ let data = '';
43
+ res.on('data', chunk => data += chunk);
44
+ res.on('end', () => {
45
+ if (data.includes('INDEX.HTML (MAIUSCOLO)')) {
46
+ console.log('βœ… SUCCESS: Il server ha trovato INDEX.HTML usando /index\\.html/i');
47
+ console.log(' Contenuto ricevuto: ' + data.trim());
48
+ } else {
49
+ console.log('❌ FAIL: Pattern non ha matchato');
50
+ console.log(' Contenuto ricevuto: ' + data);
51
+ }
52
+
53
+ server1.close();
54
+
55
+ // Test case 2
56
+ runTest2();
57
+ });
58
+ });
59
+ }, 100);
60
+
61
+ function runTest2() {
62
+ // Pulisci directory
63
+ fs.readdirSync(testDir).forEach(file => {
64
+ fs.unlinkSync(path.join(testDir, file));
65
+ });
66
+
67
+ console.log('\nπŸ“‹ TEST 2: Multi-extension /index\\.(html|htm)/i\n');
68
+ console.log('File creati:');
69
+ console.log(' - Index.HTM (mixed case, estensione .htm)');
70
+ console.log(' - other.html\n');
71
+
72
+ fs.writeFileSync(path.join(testDir, 'Index.HTM'), '<h1>Index.HTM (mixed case)</h1>');
73
+ fs.writeFileSync(path.join(testDir, 'other.html'), '<h1>altro</h1>');
74
+
75
+ const app2 = new Koa();
76
+ app2.use(koaClassicServer(testDir, {
77
+ index: [/index\.(html|htm)/i] // ← REGEXP con (html|htm)!
78
+ }));
79
+
80
+ const server2 = app2.listen(9002);
81
+
82
+ setTimeout(() => {
83
+ http.get('http://localhost:9002/', (res) => {
84
+ let data = '';
85
+ res.on('data', chunk => data += chunk);
86
+ res.on('end', () => {
87
+ if (data.includes('Index.HTM (mixed case)')) {
88
+ console.log('βœ… SUCCESS: Il server ha trovato Index.HTM usando /index\\.(html|htm)/i');
89
+ console.log(' Contenuto ricevuto: ' + data.trim());
90
+ } else {
91
+ console.log('❌ FAIL: Pattern non ha matchato');
92
+ console.log(' Contenuto ricevuto: ' + data);
93
+ }
94
+
95
+ server2.close();
96
+
97
+ // Test case 3
98
+ runTest3();
99
+ });
100
+ });
101
+ }, 100);
102
+ }
103
+
104
+ function runTest3() {
105
+ // Pulisci directory
106
+ fs.readdirSync(testDir).forEach(file => {
107
+ fs.unlinkSync(path.join(testDir, file));
108
+ });
109
+
110
+ console.log('\nπŸ“‹ TEST 3: Array con prioritΓ  [/index\\.html/i, /default\\.html/i]\n');
111
+ console.log('File creati:');
112
+ console.log(' - DEFAULT.HTML (maiuscolo)');
113
+ console.log(' - other.txt\n');
114
+ console.log('Nota: index.html NON esiste, dovrebbe trovare default.html\n');
115
+
116
+ fs.writeFileSync(path.join(testDir, 'DEFAULT.HTML'), '<h1>DEFAULT.HTML (fallback)</h1>');
117
+ fs.writeFileSync(path.join(testDir, 'other.txt'), 'altro');
118
+
119
+ const app3 = new Koa();
120
+ app3.use(koaClassicServer(testDir, {
121
+ index: [
122
+ /index\.html/i, // Prima cerca index.html (NON esiste)
123
+ /default\.html/i // Poi cerca default.html (ESISTE!)
124
+ ]
125
+ }));
126
+
127
+ const server3 = app3.listen(9003);
128
+
129
+ setTimeout(() => {
130
+ http.get('http://localhost:9003/', (res) => {
131
+ let data = '';
132
+ res.on('data', chunk => data += chunk);
133
+ res.on('end', () => {
134
+ if (data.includes('DEFAULT.HTML (fallback)')) {
135
+ console.log('βœ… SUCCESS: Il server ha fatto fallback a DEFAULT.HTML');
136
+ console.log(' Contenuto ricevuto: ' + data.trim());
137
+ } else {
138
+ console.log('❌ FAIL: Fallback non ha funzionato');
139
+ console.log(' Contenuto ricevuto: ' + data);
140
+ }
141
+
142
+ server3.close();
143
+
144
+ // Cleanup finale
145
+ cleanup();
146
+ });
147
+ });
148
+ }, 100);
149
+ }
150
+
151
+ function cleanup() {
152
+ console.log('\n🧹 Pulizia...\n');
153
+ fs.readdirSync(testDir).forEach(file => {
154
+ fs.unlinkSync(path.join(testDir, file));
155
+ });
156
+ fs.rmdirSync(testDir);
157
+ console.log('βœ… Tutti i test completati!\n');
158
+ }