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.
@@ -0,0 +1,801 @@
1
+ # 📖 Core Concepts
2
+
3
+ YinzerFlow's core concepts provide the foundation for building HTTP APIs. This guide covers the Context object, Request handling, Response control, Routing system, and Hooks - the essential building blocks for any YinzerFlow application.
4
+
5
+ For detailed configuration examples and patterns, see [Configuration Guide](../configuration/configuration.md).
6
+
7
+ # ⚙️ Usage
8
+
9
+ ## 🔧 Context Object
10
+
11
+ The Context object is the central interface for all YinzerFlow route handlers and hooks. It provides access to request data, response controls, and maintains request-scoped state throughout the request lifecycle.
12
+
13
+ ```typescript
14
+ import { YinzerFlow } from 'yinzerflow';
15
+
16
+ const app = new YinzerFlow({ port: 3000 });
17
+
18
+ // Context is automatically provided to all handlers
19
+ app.get('/api/data', (ctx) => {
20
+ // Access request data
21
+ const { path, method, headers } = ctx.request;
22
+
23
+ // Control response
24
+ ctx.response.setStatusCode(200);
25
+
26
+ // Store custom state
27
+ ctx.state.user = { id: 1, name: 'John' };
28
+
29
+ return { message: 'Success' };
30
+ });
31
+ ```
32
+
33
+ ### State Management
34
+
35
+ Request-scoped state data that persists throughout the request lifecycle.
36
+
37
+ ```typescript
38
+ app.get('/api/users', async (ctx) => {
39
+ // Store custom data in state
40
+ ctx.state.user = { id: 1, name: 'John' };
41
+ ctx.state.requestId = generateRequestId();
42
+ ctx.state.timestamp = Date.now();
43
+
44
+ // Access the data later
45
+ console.log(ctx.state.user.name); // "John"
46
+ console.log(ctx.state.requestId); // "req-123"
47
+ console.log(ctx.state.timestamp); // 1703123456789
48
+
49
+ return { users: ['John', 'Jane'] };
50
+ });
51
+ ```
52
+
53
+ ## 🔧 Request Object
54
+
55
+ YinzerFlow provides a comprehensive request object containing parsed headers, body, query parameters, route parameters, and metadata with built-in security protections.
56
+
57
+ ```typescript
58
+ app.get('/api/users/:id', ({ request }) => {
59
+ // Access route parameters
60
+ const userId = request.params.id;
61
+
62
+ // Access query parameters
63
+ const includeProfile = request.query.include_profile;
64
+
65
+ // Access headers
66
+ const contentType = request.headers['content-type'];
67
+ const authorization = request.headers['authorization'];
68
+
69
+ // Access request body
70
+ const userData = request.body;
71
+
72
+ // Access raw body for manual parsing when needed
73
+ const rawBody = request.rawBody;
74
+
75
+ const clientIp = request.ipAddress;
76
+
77
+ return {
78
+ message: 'Request processed successfully',
79
+ userId,
80
+ includeProfile,
81
+ contentType,
82
+ hasAuth: !!authorization,
83
+ receivedData: userData
84
+ };
85
+ });
86
+ ```
87
+
88
+ ### Type Safety
89
+
90
+ Request data is type-safe through TypeScript generics.
91
+
92
+ ```typescript
93
+ // Custom types for specific endpoints
94
+ interface UserCreateRequest extends HandlerCallbackGenerics {
95
+ body: { name: string; email: string; age: number };
96
+ query: { page: string; limit: string };
97
+ params: { id: string };
98
+ }
99
+
100
+ const createUser: HandlerCallback<UserCreateRequest> = async (ctx) => {
101
+ // Fully typed!
102
+ const { name, email, age } = ctx.request.body; // Type: { name: string; email: string; age: number }
103
+ const { page, limit } = ctx.request.query; // Type: { page: string; limit: string }
104
+ const { id } = ctx.request.params; // Type: { id: string }
105
+
106
+ return { success: true, user: { name, email, age, id } };
107
+ };
108
+ ```
109
+
110
+ ## 🔧 Response Object
111
+
112
+ YinzerFlow provides a powerful response object for controlling HTTP responses with automatic content type detection, header validation, and built-in security protections.
113
+
114
+ ```typescript
115
+ app.get('/api/users/:id', ({ response }) => {
116
+ // Set successful status code
117
+ response.setStatusCode(200);
118
+
119
+ // Add custom headers
120
+ response.addHeaders({
121
+ 'X-User-ID': userId,
122
+ 'Cache-Control': 'max-age=3600',
123
+ 'X-API-Version': '1.0'
124
+ });
125
+
126
+ // Return JSON response body (Content-Type automatically set)
127
+ return {
128
+ id: userId,
129
+ name: 'John Doe',
130
+ email: 'john@example.com',
131
+ timestamp: new Date().toISOString()
132
+ };
133
+ });
134
+ ```
135
+
136
+ ### Security Headers
137
+
138
+ Automatic security headers are added to every response by default.
139
+
140
+ ```typescript
141
+ // Security headers are automatically added
142
+ app.get('/api/data', ({ response }) => {
143
+ // Additional security headers can be added
144
+ response.addHeaders({
145
+ 'X-Content-Type-Options': 'nosniff',
146
+ 'X-Frame-Options': 'DENY',
147
+ 'X-XSS-Protection': '1; mode=block'
148
+ });
149
+
150
+ return { message: 'Secure response' };
151
+ });
152
+ ```
153
+
154
+ ## 🔧 Routing System
155
+
156
+ YinzerFlow provides a powerful and flexible routing system with support for HTTP methods, route parameters, query parameters, hooks, and route grouping.
157
+
158
+ ```typescript
159
+ // Basic route registration
160
+ app.get('/api/users', (ctx) => {
161
+ return { message: 'Users endpoint' };
162
+ });
163
+
164
+ // Route parameters
165
+ app.get('/users/:id', ({ request }) => {
166
+ const userId = request.params.id;
167
+ return { userId };
168
+ });
169
+
170
+ // Multiple parameters
171
+ app.get('/users/:id/posts/:postId', ({ request }) => {
172
+ const { id, postId } = request.params;
173
+ return { userId: id, postId };
174
+ });
175
+
176
+ // Route groups with hooks
177
+ app.group('/api/v1', (api) => {
178
+ api.get('/users', () => ({ users: [] }));
179
+ api.post('/users', () => ({ created: true }));
180
+ }, {
181
+ beforeHooks: [
182
+ async (ctx) => {
183
+ ctx.state.apiVersion = 'v1';
184
+ }
185
+ ],
186
+ afterHooks: [
187
+ async (ctx) => {
188
+ ctx.response.addHeaders({
189
+ 'X-API-Version': 'v1.0.0'
190
+ });
191
+ }
192
+ ]
193
+ });
194
+ ```
195
+
196
+ ### Available HTTP Methods
197
+
198
+ ```typescript
199
+ app.get('/users', handler); // GET requests
200
+ app.post('/users', handler); // POST requests
201
+ app.put('/users/:id', handler); // PUT requests
202
+ app.patch('/users/:id', handler); // PATCH requests
203
+ app.delete('/users/:id', handler); // DELETE requests
204
+ app.head('/users', handler); // HEAD requests
205
+ app.options('/users', handler); // OPTIONS requests
206
+ ```
207
+
208
+ ## 🔧 Hooks System
209
+
210
+ YinzerFlow provides a comprehensive hooks system for middleware, authentication, logging, and cross-cutting concerns. Hooks execute in a specific order and can be applied globally or to specific routes.
211
+
212
+ ### Global Hooks
213
+
214
+ Global hooks run for every request and are perfect for authentication, logging, and response modification.
215
+
216
+ ```typescript
217
+ // Global authentication hook
218
+ app.beforeAll([
219
+ async (ctx) => {
220
+ const token = ctx.request.headers.authorization;
221
+ if (token) {
222
+ const user = await validateToken(token);
223
+ ctx.state.user = user;
224
+ ctx.state.isAuthenticated = true;
225
+ }
226
+ }
227
+ ]);
228
+
229
+ // Global logging hook
230
+ app.beforeAll([
231
+ async (ctx) => {
232
+ ctx.state.requestId = generateRequestId();
233
+ ctx.state.startTime = Date.now();
234
+
235
+ console.log(`Request ${ctx.state.requestId} to ${ctx.request.path}`);
236
+ }
237
+ ], {
238
+ routesToExclude: ['/health', '/metrics'] // Skip logging for health checks
239
+ });
240
+
241
+ // Global response modification hook
242
+ app.afterAll([
243
+ async (ctx) => {
244
+ // Add response headers based on state
245
+ if (ctx.state.requestId) {
246
+ ctx.response.addHeaders({
247
+ 'X-Request-ID': ctx.state.requestId,
248
+ 'X-Processing-Time': `${Date.now() - ctx.state.startTime}ms`
249
+ });
250
+ }
251
+
252
+ // Log response
253
+ console.log(`Request ${ctx.state.requestId} completed with status ${ctx.response.statusCode}`);
254
+ }
255
+ ]);
256
+ ```
257
+
258
+ ### Route-Specific Hooks
259
+
260
+ Route-specific hooks run only for specific routes and can be applied to individual routes or route groups.
261
+
262
+ ```typescript
263
+ // Individual route with hooks
264
+ app.get('/api/users/:id',
265
+ // beforeHooks
266
+ [
267
+ async (ctx) => {
268
+ ctx.state.requiresAuth = true;
269
+ console.log(`Accessing user ${ctx.request.params.id}`);
270
+ }
271
+ ],
272
+ // route handler
273
+ async (ctx) => {
274
+ const user = await getUserById(ctx.request.params.id);
275
+ return { user };
276
+ },
277
+ // afterHooks
278
+ {
279
+ afterHooks: [
280
+ async (ctx) => {
281
+ console.log(`User ${ctx.request.params.id} accessed successfully`);
282
+ }
283
+ ]
284
+ }
285
+ );
286
+
287
+ // Route group with shared hooks
288
+ app.group('/api/v1', (api) => {
289
+ api.get('/users', () => ({ users: [] }));
290
+ api.post('/users', () => ({ created: true }));
291
+ }, {
292
+ beforeHooks: [
293
+ async (ctx) => {
294
+ ctx.state.apiVersion = 'v1';
295
+ ctx.state.requiresAuth = true;
296
+ }
297
+ ],
298
+ afterHooks: [
299
+ async (ctx) => {
300
+ ctx.response.addHeaders({
301
+ 'X-API-Version': 'v1.0.0'
302
+ });
303
+ }
304
+ ]
305
+ });
306
+ ```
307
+
308
+ ### Hook Execution Order
309
+
310
+ Hooks execute in a specific order for predictable behavior:
311
+
312
+ 1. **Global beforeAll hooks** (in registration order)
313
+ 2. **Group beforeHooks** (parent groups first, then child groups)
314
+ 3. **Route-specific beforeHooks** (in registration order)
315
+ 4. **Route handler**
316
+ 5. **Route-specific afterHooks** (in registration order)
317
+ 6. **Group afterHooks** (child groups first, then parent groups)
318
+ 7. **Global afterAll hooks** (in registration order)
319
+
320
+ ```typescript
321
+ // Example showing execution order
322
+ app.beforeAll([() => console.log('1. Global beforeAll')]);
323
+ app.beforeAll([() => console.log('2. Global beforeAll 2')]);
324
+
325
+ app.group('/api', (api) => {
326
+ api.get('/test',
327
+ [() => console.log('4. Route beforeHook')],
328
+ () => {
329
+ console.log('5. Route handler');
330
+ return { message: 'success' };
331
+ },
332
+ {
333
+ afterHooks: [() => console.log('6. Route afterHook')]
334
+ }
335
+ );
336
+ }, {
337
+ beforeHooks: [() => console.log('3. Group beforeHook')],
338
+ afterHooks: [() => console.log('7. Group afterHook')]
339
+ });
340
+
341
+ app.afterAll([() => console.log('8. Global afterAll')]);
342
+ app.afterAll([() => console.log('9. Global afterAll 2')]);
343
+
344
+ // Output order: 1, 2, 3, 4, 5, 6, 7, 8, 9
345
+ ```
346
+
347
+ ### Hook Options
348
+
349
+ Hooks support configuration options for selective execution:
350
+
351
+ ```typescript
352
+ // Hook options for selective execution
353
+ interface HookOptions {
354
+ routesToInclude?: string[]; // Only run for specific routes
355
+ routesToExclude?: string[]; // Skip for specific routes
356
+ }
357
+
358
+ // Example: Authentication hook that skips public routes
359
+ app.beforeAll([
360
+ async (ctx) => {
361
+ const token = ctx.request.headers.authorization;
362
+ if (!token) {
363
+ ctx.response.setStatusCode(401);
364
+ return { error: 'Authentication required' };
365
+ }
366
+
367
+ const user = await validateToken(token);
368
+ ctx.state.user = user;
369
+ }
370
+ ], {
371
+ routesToExclude: ['/health', '/metrics', '/public/*']
372
+ });
373
+ ```
374
+
375
+ # ✨ Best Practices
376
+
377
+ - **Use TypeScript generics** for type-safe request/response data access
378
+ - **Validate request data** before processing
379
+ - **Set appropriate status codes** for different operations (200, 201, 404, 500)
380
+ - **Use meaningful headers** for caching, security, and API versioning
381
+ - **Organize routes with groups** - Group related endpoints together
382
+ - **Use hooks for shared logic** - Authentication, logging, validation
383
+ - **Keep state minimal** - only store data that's actually needed
384
+ - **Handle errors gracefully** - Use try-catch and proper error responses
385
+
386
+ # 💻 Examples
387
+
388
+ ### Production API
389
+
390
+ **Use Case:** Secure API with comprehensive request/response handling and organized routing
391
+
392
+ **Description:** Production-ready implementation with TypeScript generics, authentication, validation, error handling, and organized route structure for maximum security and maintainability.
393
+
394
+ ```typescript
395
+ import { YinzerFlow } from 'yinzerflow';
396
+ import type { HandlerCallback } from 'yinzerflow';
397
+
398
+ // Define custom context types
399
+ interface AuthContext extends HandlerCallbackGenerics {
400
+ body: { username: string; password: string };
401
+ response: { token: string; user: User };
402
+ state: {
403
+ user: User;
404
+ permissions: string[];
405
+ requestId: string;
406
+ session: Session;
407
+ };
408
+ }
409
+
410
+ const app = new YinzerFlow({ port: 3000 });
411
+
412
+ // Global authentication middleware
413
+ const authMiddleware: HandlerCallback = async (ctx) => {
414
+ const token = ctx.request.headers.authorization;
415
+ if (!token) {
416
+ ctx.response.setStatusCode(401);
417
+ return { error: 'Authentication required' };
418
+ }
419
+
420
+ const user = await validateToken(token);
421
+ ctx.state.user = user;
422
+ ctx.state.isAuthenticated = true;
423
+ };
424
+
425
+ // Global logging middleware
426
+ const loggingMiddleware: HandlerCallback = async (ctx) => {
427
+ ctx.state.requestId = generateRequestId();
428
+ ctx.state.startTime = Date.now();
429
+
430
+ console.log(`[${ctx.state.requestId}] ${ctx.request.method} ${ctx.request.path}`);
431
+ };
432
+
433
+ // Global hooks
434
+ app.beforeAll([loggingMiddleware]);
435
+ app.afterAll([
436
+ async (ctx) => {
437
+ const processingTime = Date.now() - ctx.state.startTime;
438
+ ctx.response.addHeaders({
439
+ 'X-Request-ID': ctx.state.requestId,
440
+ 'X-Processing-Time': `${processingTime}ms`
441
+ });
442
+ }
443
+ ]);
444
+
445
+ // Custom error handler
446
+ app.onError(async (ctx, error) => {
447
+ console.error(`[${ctx.state.requestId}] Error:`, error);
448
+
449
+ ctx.response.setStatusCode(500);
450
+ return {
451
+ error: 'Internal server error',
452
+ requestId: ctx.state.requestId,
453
+ message: process.env.NODE_ENV === 'production' ? 'Something went wrong' : error.message
454
+ };
455
+ });
456
+
457
+ // API v1 routes
458
+ app.group('/api/v1', (api) => {
459
+ // Public routes
460
+ api.get('/health', async (ctx) => {
461
+ return { status: 'healthy', timestamp: new Date().toISOString() };
462
+ });
463
+
464
+ // User routes
465
+ api.group('/users', (users) => {
466
+ // Get all users
467
+ users.get('/', async (ctx) => {
468
+ const users = await getAllUsers();
469
+ return { users, count: users.length };
470
+ });
471
+
472
+ // Get user by ID
473
+ users.get('/:userId', async (ctx) => {
474
+ const { userId } = ctx.request.params;
475
+
476
+ // Validate UUID format
477
+ if (!isValidUUID(userId)) {
478
+ ctx.response.setStatusCode(400);
479
+ return { error: 'Invalid user ID format' };
480
+ }
481
+
482
+ const user = await getUserById(userId);
483
+ if (!user) {
484
+ ctx.response.setStatusCode(404);
485
+ return { error: 'User not found' };
486
+ }
487
+
488
+ return { user };
489
+ });
490
+
491
+ // Create user
492
+ users.post('/', async (ctx) => {
493
+ const userData = ctx.request.body as { name: string; email: string };
494
+
495
+ // Validate required fields
496
+ if (!userData.name || !userData.email) {
497
+ ctx.response.setStatusCode(400);
498
+ return { error: 'Name and email are required' };
499
+ }
500
+
501
+ const user = await createUser(userData);
502
+
503
+ ctx.response.setStatusCode(201);
504
+ ctx.response.addHeaders({
505
+ 'Location': `/api/v1/users/${user.id}`,
506
+ 'X-User-ID': user.id,
507
+ 'X-API-Version': 'v1.0.0',
508
+ 'Cache-Control': 'no-cache'
509
+ });
510
+
511
+ return { user };
512
+ });
513
+
514
+ // Update user
515
+ users.put('/:userId', authMiddleware, async (ctx) => {
516
+ const { userId } = ctx.request.params;
517
+ const updateData = ctx.request.body as { name?: string; email?: string };
518
+
519
+ const user = await updateUser(userId, updateData);
520
+ if (!user) {
521
+ ctx.response.setStatusCode(404);
522
+ return { error: 'User not found' };
523
+ }
524
+
525
+ return { user };
526
+ });
527
+
528
+ // Delete user
529
+ users.delete('/:userId', authMiddleware, async (ctx) => {
530
+ const { userId } = ctx.request.params;
531
+
532
+ const deleted = await deleteUser(userId);
533
+ if (!deleted) {
534
+ ctx.response.setStatusCode(404);
535
+ return { error: 'User not found' };
536
+ }
537
+
538
+ ctx.response.setStatusCode(204);
539
+ return; // No content for successful deletion
540
+ });
541
+ });
542
+ });
543
+
544
+ await app.listen();
545
+ ```
546
+
547
+ ### Dev API
548
+
549
+ **Use Case:** Development server with extensive debugging and testing capabilities
550
+
551
+ **Description:** Development configuration with comprehensive logging, debug routes, and simplified error handling for easier development and testing.
552
+
553
+ ```typescript
554
+ import { YinzerFlow } from 'yinzerflow';
555
+
556
+ const app = new YinzerFlow({ port: 3000 });
557
+
558
+ // Development logging middleware
559
+ const devLoggingMiddleware: HandlerCallback = async (ctx) => {
560
+ ctx.state.requestId = generateRequestId();
561
+ ctx.state.timestamp = Date.now();
562
+
563
+ console.log('=== Request Debug Info ===');
564
+ console.log(`Request ID: ${ctx.state.requestId}`);
565
+ console.log(`Method: ${ctx.request.method}`);
566
+ console.log(`Path: ${ctx.request.path}`);
567
+ console.log(`Headers:`, ctx.request.headers);
568
+ console.log(`Query:`, ctx.request.query);
569
+ console.log(`Params:`, ctx.request.params);
570
+ console.log(`Body:`, ctx.request.body);
571
+ };
572
+
573
+ // Global development hooks
574
+ app.beforeAll([devLoggingMiddleware]);
575
+ app.afterAll([
576
+ async (ctx) => {
577
+ const processingTime = Date.now() - ctx.state.timestamp;
578
+
579
+ ctx.response.addHeaders({
580
+ 'X-Debug-Mode': 'true',
581
+ 'X-Request-ID': ctx.state.requestId,
582
+ 'X-Processing-Time': `${processingTime}ms`,
583
+ 'X-Server-Version': 'YinzerFlow Dev'
584
+ });
585
+
586
+ console.log(`[${ctx.state.requestId}] Response sent in ${processingTime}ms`);
587
+ }
588
+ ]);
589
+
590
+ // Debug routes
591
+ app.get('/debug', async (ctx) => {
592
+ return {
593
+ message: 'Debug information',
594
+ request: {
595
+ method: ctx.request.method,
596
+ path: ctx.request.path,
597
+ headers: ctx.request.headers,
598
+ query: ctx.request.query,
599
+ params: ctx.request.params,
600
+ body: ctx.request.body,
601
+ ipAddress: ctx.request.ipAddress
602
+ },
603
+ state: ctx.state,
604
+ timestamp: new Date().toISOString()
605
+ };
606
+ });
607
+
608
+ // Echo route for testing
609
+ app.post('/echo', async (ctx) => {
610
+ return {
611
+ message: 'Echo response',
612
+ received: {
613
+ method: ctx.request.method,
614
+ path: ctx.request.path,
615
+ headers: ctx.request.headers,
616
+ body: ctx.request.body,
617
+ query: ctx.request.query,
618
+ params: ctx.request.params
619
+ },
620
+ timestamp: new Date().toISOString()
621
+ };
622
+ });
623
+
624
+ // Test different HTTP methods
625
+ app.get('/test/:type', async (ctx) => {
626
+ const { type } = ctx.request.params;
627
+
628
+ switch (type) {
629
+ case 'json':
630
+ return { message: 'JSON response', type: 'object' };
631
+ case 'text':
632
+ return 'Plain text response';
633
+ case 'error':
634
+ throw new Error('Test error');
635
+ default:
636
+ return { message: 'Default response', availableTypes: ['json', 'text', 'error'] };
637
+ }
638
+ });
639
+
640
+ // Test route parameters
641
+ app.get('/test/params/:id/:name', async (ctx) => {
642
+ const { id, name } = ctx.request.params;
643
+ return { id, name, message: 'Parameters received' };
644
+ });
645
+
646
+ // Test query parameters
647
+ app.get('/test/query', async (ctx) => {
648
+ const { q, limit, page } = ctx.request.query;
649
+ return {
650
+ query: q,
651
+ limit: parseInt(limit || '10'),
652
+ page: parseInt(page || '1'),
653
+ message: 'Query parameters received'
654
+ };
655
+ });
656
+
657
+ // Test route groups
658
+ app.group('/test', (test) => {
659
+ test.get('/group', async (ctx) => {
660
+ return { message: 'Group route accessed' };
661
+ });
662
+
663
+ test.group('/nested', (nested) => {
664
+ nested.get('/route', async (ctx) => {
665
+ return { message: 'Nested group route accessed' };
666
+ });
667
+ });
668
+ });
669
+
670
+ await app.listen();
671
+ ```
672
+
673
+ ## 🚀 Performance Notes
674
+
675
+ - **Automatic parsing**: Request data is parsed once and cached
676
+ - **Type safety**: TypeScript generics provide compile-time type checking with zero runtime overhead
677
+ - **Memory efficiency**: State and request/response objects are automatically garbage collected after each request completes
678
+ - **O(1) route lookup**: Exact routes use hash map for constant time lookup
679
+ - **Pre-compiled regex**: Parameterized routes use pre-compiled regex for fast matching
680
+ - **Hook optimization**: Hooks are executed efficiently with minimal overhead
681
+ - **Request isolation**: Each request gets its own isolated context that's cleaned up automatically
682
+
683
+ ## 🔒 Security Notes
684
+
685
+ YinzerFlow implements several security measures for core concepts:
686
+
687
+ ### 🛡️ Request Isolation
688
+ - **Problem**: State data could leak between requests, allowing one user to access another user's data
689
+ - **YinzerFlow Solution**: Each request gets its own isolated state object that's automatically cleaned up
690
+
691
+ ### 🛡️ RFC 7230 Header Compliance
692
+ - **Problem**: Invalid header names can bypass security filters and cause parsing inconsistencies
693
+ - **YinzerFlow Solution**: Strict validation against RFC 7230 specification - only valid header characters are allowed
694
+
695
+ ### 🛡️ CRLF Injection Prevention
696
+ - **Problem**: Injecting carriage return (`\r`) or line feed (`\n`) characters in header values can allow attackers to inject additional headers or even HTTP response splitting attacks
697
+ - **YinzerFlow Solution**: Comprehensive validation in `validateResponseHeaderValue()` detects and blocks:
698
+ - CRLF characters (`\r`, `\n`) in header values
699
+ - Suspicious injection patterns like `value\r\nSet-Cookie:`
700
+ - Double CRLF patterns (`\r\n\r\n`) that could inject HTTP responses
701
+ - HTTP response line injection attempts
702
+ - All validation happens before headers are set, preventing injection attacks
703
+
704
+ ### 🛡️ Route Parameter Validation
705
+ - **Problem**: Malicious route parameters can cause injection attacks or bypass security controls
706
+ - **YinzerFlow Solution**: Automatic parameter validation and sanitization prevents injection attacks
707
+
708
+ ### 🛡️ Path Traversal Protection
709
+ - **Problem**: Directory traversal attacks through URL paths can access unauthorized files
710
+ - **YinzerFlow Solution**: Comprehensive path normalization and validation prevents traversal attempts
711
+
712
+ ### 🛡️ Body Parsing Protection
713
+ - **Problem**: Malformed request bodies can cause parsing errors, memory exhaustion, or security vulnerabilities
714
+ - **YinzerFlow Solution**: Comprehensive body parsing security with size limits, validation, and protection against common attacks
715
+
716
+ ### 🛡️ Automatic Security Headers
717
+ - **Problem**: Missing security headers leave applications vulnerable to clickjacking, MIME sniffing, and XSS attacks
718
+ - **YinzerFlow Solution**: Automatically adds essential security headers to every response unless explicitly overridden by the application
719
+
720
+ ### 🛡️ Hook Execution Security
721
+ - **Problem**: Malicious hooks can cause security vulnerabilities or bypass controls
722
+ - **YinzerFlow Solution**: Isolated hook execution with graceful error handling and validation
723
+
724
+ ## 🔧 Troubleshooting
725
+
726
+ ### State Not Persisting Between Middleware
727
+ - **Problem**: State data set in middleware not available in route handler
728
+ - **Fix**: Ensure middleware runs before route handler
729
+
730
+ ```typescript
731
+ // ❌ Wrong - middleware runs after route handler
732
+ app.get('/api/users', getUserHandler, authMiddleware);
733
+
734
+ // ✅ Correct - middleware runs before route handler
735
+ app.get('/api/users', authMiddleware, getUserHandler);
736
+ ```
737
+
738
+ ### Request Body Not Parsed
739
+ - **Problem**: `request.body` is undefined or not parsed correctly
740
+ - **Fix**: Check Content-Type header and body parser configuration
741
+
742
+ ```typescript
743
+ // ❌ Wrong - missing Content-Type header
744
+ fetch('/api/users', {
745
+ method: 'POST',
746
+ body: JSON.stringify({ name: 'John' })
747
+ });
748
+
749
+ // ✅ Correct - include Content-Type header
750
+ fetch('/api/users', {
751
+ method: 'POST',
752
+ headers: { 'Content-Type': 'application/json' },
753
+ body: JSON.stringify({ name: 'John' })
754
+ });
755
+ ```
756
+
757
+ ### Response Headers Not Set
758
+ - **Problem**: Headers not appearing in response
759
+ - **Fix**: Check header names and values for validity
760
+
761
+ ```typescript
762
+ // ❌ Wrong - invalid header name
763
+ response.addHeaders({ 'Invalid@Header': 'value' });
764
+
765
+ // ✅ Correct - valid header name
766
+ response.addHeaders({ 'X-Custom-Header': 'value' });
767
+ ```
768
+
769
+ ### Route Not Found
770
+ - **Problem**: Route not matching requests
771
+ - **Fix**: Check route path and parameter names
772
+
773
+ ```typescript
774
+ // ❌ Wrong - route not found
775
+ app.get('/users/:id', handler);
776
+ // Request: GET /users/123/extra
777
+
778
+ // ✅ Correct - match the exact path
779
+ app.get('/users/:id', handler);
780
+ // Request: GET /users/123
781
+ ```
782
+
783
+ ### TypeScript Errors with Request Data
784
+ - **Problem**: TypeScript errors when accessing request properties
785
+ - **Fix**: Use proper generic typing
786
+
787
+ ```typescript
788
+ // ❌ Wrong - no type safety
789
+ const handler: HandlerCallback = async (ctx) => {
790
+ const user = ctx.request.body; // Type: unknown
791
+ };
792
+
793
+ // ✅ Correct - type-safe request access
794
+ interface UserRequest extends HandlerCallbackGenerics {
795
+ body: { name: string; email: string };
796
+ }
797
+
798
+ const handler: HandlerCallback<UserRequest> = async (ctx) => {
799
+ const { name, email } = ctx.request.body; // Type: { name: string; email: string }
800
+ };
801
+ ```