yinzerflow 0.4.4 → 0.5.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/README.md +31 -26
- package/docs/configuration/configuration.md +815 -0
- package/docs/core/core-concepts.md +801 -0
- package/docs/core/error-handling.md +391 -153
- package/docs/core/logging.md +426 -68
- package/docs/modules/body-parsing.md +561 -0
- package/docs/modules/cors.md +369 -0
- package/docs/modules/index.md +125 -0
- package/docs/modules/ip-security.md +280 -0
- package/docs/modules/rate-limiting.md +795 -0
- package/index.d.ts +278 -76
- package/index.js +18 -18
- package/index.js.map +17 -8
- package/package.json +5 -3
- package/docs/configuration/advanced-configuration-options.md +0 -302
- package/docs/configuration/configuration-patterns.md +0 -500
- package/docs/core/context.md +0 -230
- package/docs/core/examples.md +0 -444
- package/docs/core/request.md +0 -161
- package/docs/core/response.md +0 -212
- package/docs/core/routes.md +0 -720
- package/docs/quick-reference.md +0 -346
- package/docs/security/body-parsing.md +0 -296
- package/docs/security/cors.md +0 -189
- package/docs/security/ip-security.md +0 -234
- package/docs/security/security-overview.md +0 -282
- package/docs/start-here.md +0 -184
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yinzerflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"author": "Patrick Rizzardi <patrick@redact.digital> (https://redact.digital)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/yinzers/YinzerFlow/blob/main/docs/start-here.md",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"type": "module",
|
|
28
28
|
"scripts": {
|
|
29
29
|
"test": "bun test --watch --coverage",
|
|
30
|
-
"test:production": "bun test --timeout=
|
|
30
|
+
"test:production": "bun test --timeout=5000 --rerun-each=1 --bail --coverage",
|
|
31
31
|
"clean": "rm -rf lib && rm -rf storage && echo 'Done.'",
|
|
32
32
|
"build": "bun clean; bun build.ts",
|
|
33
33
|
"build:watch": "bun build-watch.ts",
|
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
"typescript-eslint": "^8.26.1"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"typescript": "^5.0.0"
|
|
59
|
+
"typescript": "^5.0.0",
|
|
60
|
+
"redis": "^4.7.0",
|
|
61
|
+
"ioredis": "^5.4.0"
|
|
60
62
|
}
|
|
61
63
|
}
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
# Advanced Configuration Options
|
|
2
|
-
|
|
3
|
-
YinzerFlow provides advanced configuration options for fine-tuning security, performance, and functionality. These options allow you to customize the framework's behavior for specific use cases while maintaining robust security defaults.
|
|
4
|
-
|
|
5
|
-
For common configuration patterns and best practices, see [Configuration Patterns](./configuration-patterns.md).
|
|
6
|
-
|
|
7
|
-
## Body Parser Configuration
|
|
8
|
-
|
|
9
|
-
Body parsing handles all incoming request data with built-in security protections against DoS attacks, prototype pollution, and memory exhaustion vulnerabilities. See [Body Parsing Documentation](./body-parsing.md) for detailed setup, configuration options, and security considerations.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
const app = new YinzerFlow({
|
|
13
|
-
port: 3000,
|
|
14
|
-
bodyParser: {
|
|
15
|
-
json: {
|
|
16
|
-
maxSize: 262144, // 256KB
|
|
17
|
-
maxDepth: 10,
|
|
18
|
-
allowPrototypeProperties: false, // Security protection
|
|
19
|
-
maxKeys: 1000
|
|
20
|
-
},
|
|
21
|
-
fileUploads: {
|
|
22
|
-
maxFileSize: 10485760, // 10MB per file
|
|
23
|
-
maxFiles: 10,
|
|
24
|
-
allowedExtensions: ['.jpg', '.png', '.pdf']
|
|
25
|
-
},
|
|
26
|
-
urlEncoded: {
|
|
27
|
-
maxSize: 1048576, // 1MB
|
|
28
|
-
maxFields: 1000
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## CORS Configuration
|
|
35
|
-
|
|
36
|
-
Cross-Origin Resource Sharing (CORS) configuration for browser security. See [CORS Documentation](./cors.md) for detailed setup and security considerations.
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
const app = new YinzerFlow({
|
|
40
|
-
port: 3000,
|
|
41
|
-
cors: {
|
|
42
|
-
enabled: true,
|
|
43
|
-
origin: ['https://yourdomain.com'],
|
|
44
|
-
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
45
|
-
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
46
|
-
credentials: true
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## IP Security Configuration
|
|
52
|
-
|
|
53
|
-
IP address validation and spoofing protection for accurate client identification. See [IP Security Documentation](./ip-security.md) for detailed setup, security considerations, and advanced use cases.
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
const app = new YinzerFlow({
|
|
57
|
-
port: 3000,
|
|
58
|
-
ipSecurity: {
|
|
59
|
-
trustedProxies: ['127.0.0.1', '::1', '192.168.1.10'],
|
|
60
|
-
allowPrivateIps: true,
|
|
61
|
-
headerPreference: ['x-forwarded-for', 'x-real-ip', 'cf-connecting-ip'],
|
|
62
|
-
maxChainLength: 10,
|
|
63
|
-
detectSpoofing: true
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Server Configuration
|
|
69
|
-
|
|
70
|
-
### Connection Options
|
|
71
|
-
|
|
72
|
-
Fine-tune server connection behavior and timeouts:
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
const app = new YinzerFlow({
|
|
76
|
-
port: 3000,
|
|
77
|
-
host: '0.0.0.0', // Bind address
|
|
78
|
-
// IP extraction is now handled by ipSecurity configuration
|
|
79
|
-
connectionOptions: {
|
|
80
|
-
socketTimeout: 30000, // 30 seconds
|
|
81
|
-
gracefulShutdownTimeout: 30000,
|
|
82
|
-
keepAliveTimeout: 65000,
|
|
83
|
-
headersTimeout: 66000
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
| Option | Type | Default | Description |
|
|
89
|
-
|-----|---|---|---|
|
|
90
|
-
| `socketTimeout` | `number` | `30000` | Socket timeout in milliseconds |
|
|
91
|
-
| `gracefulShutdownTimeout` | `number` | `30000` | Graceful shutdown timeout |
|
|
92
|
-
| `keepAliveTimeout` | `number` | `65000` | Keep-alive timeout |
|
|
93
|
-
| `headersTimeout` | `number` | `66000` | Headers timeout (should be > keep-alive) |
|
|
94
|
-
|
|
95
|
-
### Graceful Shutdown Configuration
|
|
96
|
-
|
|
97
|
-
Control automatic graceful shutdown behavior:
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
const app = new YinzerFlow({
|
|
101
|
-
port: 3000,
|
|
102
|
-
autoGracefulShutdown: true, // Enable automatic signal handling (default)
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
| Option | Type | Default | Description |
|
|
107
|
-
|-----|---|---|---|
|
|
108
|
-
| `autoGracefulShutdown` | `boolean` | `true` | Enable automatic SIGTERM/SIGINT handling |
|
|
109
|
-
|
|
110
|
-
**When enabled (default):**
|
|
111
|
-
- Automatically sets up SIGTERM and SIGINT signal handlers
|
|
112
|
-
- Logs shutdown process with Pittsburgh personality
|
|
113
|
-
- Calls `app.close()` and `process.exit(0)` automatically
|
|
114
|
-
- Prevents duplicate handlers when multiple instances are created
|
|
115
|
-
|
|
116
|
-
**When disabled:**
|
|
117
|
-
- No automatic signal handling
|
|
118
|
-
- Manual graceful shutdown setup required
|
|
119
|
-
- Useful for custom shutdown logic or integration with process managers
|
|
120
|
-
|
|
121
|
-
### Custom Graceful Shutdown Example
|
|
122
|
-
|
|
123
|
-
When `autoGracefulShutdown: false`, you can implement custom shutdown logic:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
import { YinzerFlow } from 'yinzerflow';
|
|
127
|
-
|
|
128
|
-
const app = new YinzerFlow({
|
|
129
|
-
port: 3000,
|
|
130
|
-
autoGracefulShutdown: false, // Disable automatic handling
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Custom shutdown with additional cleanup
|
|
134
|
-
const gracefulShutdown = async (signal: string) => {
|
|
135
|
-
console.log(`🛑 Received ${signal}, starting custom shutdown...`);
|
|
136
|
-
|
|
137
|
-
// Custom cleanup logic
|
|
138
|
-
await cleanupDatabase();
|
|
139
|
-
await saveApplicationState();
|
|
140
|
-
|
|
141
|
-
// Close the server
|
|
142
|
-
await app.close();
|
|
143
|
-
|
|
144
|
-
console.log('✅ Custom shutdown completed');
|
|
145
|
-
process.exit(0);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Set up custom signal handlers
|
|
149
|
-
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
|
|
150
|
-
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
|
|
151
|
-
|
|
152
|
-
await app.listen();
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Advanced Custom Shutdown Example
|
|
156
|
-
|
|
157
|
-
For complex applications with multiple cleanup steps:
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
import { YinzerFlow } from 'yinzerflow';
|
|
161
|
-
|
|
162
|
-
const app = new YinzerFlow({
|
|
163
|
-
port: 3000,
|
|
164
|
-
autoGracefulShutdown: false,
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
let isShuttingDown = false;
|
|
168
|
-
|
|
169
|
-
const advancedShutdown = async (signal: string) => {
|
|
170
|
-
if (isShuttingDown) {
|
|
171
|
-
console.log('⚠️ Shutdown already in progress, ignoring signal');
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
isShuttingDown = true;
|
|
176
|
-
console.log(`🛑 Received ${signal}, starting advanced shutdown...`);
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
// Phase 1: Stop accepting new requests
|
|
180
|
-
console.log('📝 Phase 1: Stopping new requests...');
|
|
181
|
-
// Your logic here
|
|
182
|
-
|
|
183
|
-
// Phase 2: Complete in-flight requests
|
|
184
|
-
console.log('📝 Phase 2: Completing in-flight requests...');
|
|
185
|
-
await waitForInFlightRequests();
|
|
186
|
-
|
|
187
|
-
// Phase 3: Cleanup resources
|
|
188
|
-
console.log('📝 Phase 3: Cleaning up resources...');
|
|
189
|
-
await cleanupDatabase();
|
|
190
|
-
await closeFileHandles();
|
|
191
|
-
await flushLogs();
|
|
192
|
-
|
|
193
|
-
// Phase 4: Close server
|
|
194
|
-
console.log('📝 Phase 4: Closing server...');
|
|
195
|
-
await app.close();
|
|
196
|
-
|
|
197
|
-
console.log('✅ Advanced shutdown completed successfully');
|
|
198
|
-
process.exit(0);
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error('❌ Shutdown failed:', error);
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
process.on('SIGTERM', () => advancedShutdown('SIGTERM'));
|
|
206
|
-
process.on('SIGINT', () => advancedShutdown('SIGINT'));
|
|
207
|
-
|
|
208
|
-
await app.listen();
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Logging Configuration
|
|
212
|
-
|
|
213
|
-
Control framework logging output with built-in Pittsburgh personality or custom logging libraries. See [Logging Documentation](../core/logging.md) for detailed setup, custom logger integration, and advanced use cases.
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
const app = new YinzerFlow({
|
|
217
|
-
port: 3000,
|
|
218
|
-
logLevel: 'info', // 'off', 'error', 'warn', 'info'
|
|
219
|
-
networkLogs: true, // Enable nginx-style request logging
|
|
220
|
-
logger: customLogger // Optional custom logger implementation
|
|
221
|
-
});
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Key Points:**
|
|
225
|
-
- **Application logs** (`log.info()`, `log.warn()`, etc.) route to custom logger if provided
|
|
226
|
-
- **Network logs** (nginx-style requests) can route to custom logger or use built-in formatting
|
|
227
|
-
- **Unified interface**: Framework and user code use same `log.info()` calls
|
|
228
|
-
- **Zero breaking changes**: Existing code continues to work with custom loggers
|
|
229
|
-
- **Flexible routing**: Use same logger for both (unified monitoring) or different loggers (separate concerns)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
## Common Configuration Patterns
|
|
234
|
-
|
|
235
|
-
### High-Security API
|
|
236
|
-
```typescript
|
|
237
|
-
const secureApi = new YinzerFlow({
|
|
238
|
-
port: 443,
|
|
239
|
-
bodyParser: {
|
|
240
|
-
json: { maxSize: 32768, maxDepth: 3, maxKeys: 50 }, // Very strict
|
|
241
|
-
fileUploads: { maxFileSize: 0, maxFiles: 0 }, // No uploads
|
|
242
|
-
urlEncoded: { maxSize: 8192, maxFields: 20 } // Minimal forms
|
|
243
|
-
},
|
|
244
|
-
cors: { enabled: false } // No CORS for security
|
|
245
|
-
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### File Processing Service
|
|
249
|
-
```typescript
|
|
250
|
-
const fileService = new YinzerFlow({
|
|
251
|
-
port: 3000,
|
|
252
|
-
bodyParser: {
|
|
253
|
-
json: { maxSize: 8192 }, // Minimal JSON for metadata
|
|
254
|
-
fileUploads: {
|
|
255
|
-
maxFileSize: 2147483648, // 2GB files
|
|
256
|
-
maxTotalSize: 10737418240, // 10GB total
|
|
257
|
-
maxFiles: 50,
|
|
258
|
-
allowedExtensions: ['.zip', '.tar', '.gz', '.7z', '.rar']
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Development/Testing Environment
|
|
265
|
-
```typescript
|
|
266
|
-
const devApp = new YinzerFlow({
|
|
267
|
-
port: 3000,
|
|
268
|
-
logLevel: 'verbose', // Verbose logging
|
|
269
|
-
bodyParser: {
|
|
270
|
-
json: { maxSize: 10485760 }, // 10MB for testing
|
|
271
|
-
fileUploads: {
|
|
272
|
-
maxFileSize: 104857600, // 100MB files
|
|
273
|
-
allowedExtensions: [] // Allow all for development
|
|
274
|
-
}
|
|
275
|
-
},
|
|
276
|
-
cors: {
|
|
277
|
-
enabled: true,
|
|
278
|
-
origin: '*' // Open CORS for dev (⚠️ Never use in production)
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Configuration Best Practices
|
|
284
|
-
|
|
285
|
-
### Security First
|
|
286
|
-
- **Never enable `allowPrototypeProperties`** unless absolutely necessary
|
|
287
|
-
- **Use allowlists over blocklists** for file extensions when possible
|
|
288
|
-
- **Set conservative limits initially** and increase as needed
|
|
289
|
-
- **Enable CORS carefully** with specific origins in production
|
|
290
|
-
|
|
291
|
-
### Performance Optimization
|
|
292
|
-
- **Match limits to your use case** - don't use defaults blindly
|
|
293
|
-
- **Consider memory usage** when setting maxSize limits
|
|
294
|
-
- **Balance security vs. functionality** based on your threat model
|
|
295
|
-
|
|
296
|
-
### Monitoring and Maintenance
|
|
297
|
-
- **Watch for security warnings** in your logs
|
|
298
|
-
- **Monitor actual usage patterns** to optimize limits
|
|
299
|
-
- **Review configuration regularly** as your application evolves
|
|
300
|
-
- **Test edge cases** with your specific limits
|
|
301
|
-
|
|
302
|
-
These advanced configuration options provide fine-grained control over YinzerFlow's behavior while maintaining security best practices and preventing common vulnerabilities.
|