yinzerflow 0.2.5 → 0.2.7

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
@@ -0,0 +1,58 @@
1
+ # YinzerFlow
2
+
3
+ A lightweight, modular HTTP server framework for Node.js built with TypeScript. Features comprehensive security protections, Pittsburgh personality, and flexible configuration options.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ For complete documentation and examples, see **[docs/start-here.md](docs/start-here.md)**.
8
+
9
+ ## 📦 Installation
10
+
11
+ ```bash
12
+ npm install yinzerflow
13
+ # or
14
+ bun add yinzerflow
15
+ ```
16
+
17
+ ## 🔧 Basic Usage
18
+
19
+ ```typescript
20
+ import { YinzerFlow } from 'yinzerflow';
21
+
22
+ const app = new YinzerFlow({ port: 3000 });
23
+
24
+ app.get('/hello', () => {
25
+ return { message: 'Hello, World!' };
26
+ });
27
+
28
+ await app.listen();
29
+ ```
30
+
31
+ ## ✨ Features
32
+
33
+ - **Security-first** - Built-in protections against common web vulnerabilities
34
+ - **TypeScript-first** - Full type safety and IntelliSense support
35
+ - **Pittsburgh personality** - Witty logging and error messages
36
+ - **Flexible configuration** - Comprehensive options for different use cases
37
+ - **Modular architecture** - Scales from simple APIs to complex applications
38
+
39
+ ## 📚 Documentation
40
+
41
+ - **[Getting Started](docs/start-here.md)** - Complete guide and examples
42
+ - **[Routes](docs/routes.md)** - Routing system and handlers
43
+ - **[Request/Response](docs/request.md)** - Request and response objects
44
+ - **[Logging](docs/logging.md)** - Logging configuration and customization
45
+ - **[Advanced Configuration](docs/advanced-configuration-options.md)** - Detailed configuration options
46
+
47
+ ## 🛡️ Security
48
+
49
+ YinzerFlow includes comprehensive security features:
50
+ - IP security and rate limiting
51
+ - CORS protection
52
+ - Body parsing with security limits
53
+ - Header validation and sanitization
54
+ - Prototype pollution protection
55
+
56
+ ## 📄 License
57
+
58
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -90,6 +90,122 @@ const app = new YinzerFlow({
90
90
  | `keepAliveTimeout` | `number` | `65000` | Keep-alive timeout |
91
91
  | `headersTimeout` | `number` | `66000` | Headers timeout (should be > keep-alive) |
92
92
 
93
+ ### Graceful Shutdown Configuration
94
+
95
+ Control automatic graceful shutdown behavior:
96
+
97
+ ```typescript
98
+ const app = new YinzerFlow({
99
+ port: 3000,
100
+ autoGracefulShutdown: true, // Enable automatic signal handling (default)
101
+ });
102
+ ```
103
+
104
+ | Option | Type | Default | Description |
105
+ |-----|---|---|---|
106
+ | `autoGracefulShutdown` | `boolean` | `true` | Enable automatic SIGTERM/SIGINT handling |
107
+
108
+ **When enabled (default):**
109
+ - Automatically sets up SIGTERM and SIGINT signal handlers
110
+ - Logs shutdown process with Pittsburgh personality
111
+ - Calls `app.close()` and `process.exit(0)` automatically
112
+ - Prevents duplicate handlers when multiple instances are created
113
+
114
+ **When disabled:**
115
+ - No automatic signal handling
116
+ - Manual graceful shutdown setup required
117
+ - Useful for custom shutdown logic or integration with process managers
118
+
119
+ ### Custom Graceful Shutdown Example
120
+
121
+ When `autoGracefulShutdown: false`, you can implement custom shutdown logic:
122
+
123
+ ```typescript
124
+ import { YinzerFlow } from 'yinzerflow';
125
+
126
+ const app = new YinzerFlow({
127
+ port: 3000,
128
+ autoGracefulShutdown: false, // Disable automatic handling
129
+ });
130
+
131
+ // Custom shutdown with additional cleanup
132
+ const gracefulShutdown = async (signal: string) => {
133
+ console.log(`🛑 Received ${signal}, starting custom shutdown...`);
134
+
135
+ // Custom cleanup logic
136
+ await cleanupDatabase();
137
+ await saveApplicationState();
138
+
139
+ // Close the server
140
+ await app.close();
141
+
142
+ console.log('✅ Custom shutdown completed');
143
+ process.exit(0);
144
+ };
145
+
146
+ // Set up custom signal handlers
147
+ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
148
+ process.on('SIGINT', () => gracefulShutdown('SIGINT'));
149
+
150
+ await app.listen();
151
+ ```
152
+
153
+ ### Advanced Custom Shutdown Example
154
+
155
+ For complex applications with multiple cleanup steps:
156
+
157
+ ```typescript
158
+ import { YinzerFlow } from 'yinzerflow';
159
+
160
+ const app = new YinzerFlow({
161
+ port: 3000,
162
+ autoGracefulShutdown: false,
163
+ });
164
+
165
+ let isShuttingDown = false;
166
+
167
+ const advancedShutdown = async (signal: string) => {
168
+ if (isShuttingDown) {
169
+ console.log('⚠️ Shutdown already in progress, ignoring signal');
170
+ return;
171
+ }
172
+
173
+ isShuttingDown = true;
174
+ console.log(`🛑 Received ${signal}, starting advanced shutdown...`);
175
+
176
+ try {
177
+ // Phase 1: Stop accepting new requests
178
+ console.log('📝 Phase 1: Stopping new requests...');
179
+ // Your logic here
180
+
181
+ // Phase 2: Complete in-flight requests
182
+ console.log('📝 Phase 2: Completing in-flight requests...');
183
+ await waitForInFlightRequests();
184
+
185
+ // Phase 3: Cleanup resources
186
+ console.log('📝 Phase 3: Cleaning up resources...');
187
+ await cleanupDatabase();
188
+ await closeFileHandles();
189
+ await flushLogs();
190
+
191
+ // Phase 4: Close server
192
+ console.log('📝 Phase 4: Closing server...');
193
+ await app.close();
194
+
195
+ console.log('✅ Advanced shutdown completed successfully');
196
+ process.exit(0);
197
+ } catch (error) {
198
+ console.error('❌ Shutdown failed:', error);
199
+ process.exit(1);
200
+ }
201
+ };
202
+
203
+ process.on('SIGTERM', () => advancedShutdown('SIGTERM'));
204
+ process.on('SIGINT', () => advancedShutdown('SIGINT'));
205
+
206
+ await app.listen();
207
+ ```
208
+
93
209
  ### Logging Configuration
94
210
 
95
211
  Control framework logging output with built-in Pittsburgh personality or custom logging libraries. See [Logging Documentation](./logging.md) for detailed setup, custom logger integration, and advanced use cases.
package/docs/request.md CHANGED
@@ -36,7 +36,9 @@ YinzerFlow's request parsing includes built-in security limits that are automati
36
36
 
37
37
  These limits are built into the framework and cannot be disabled, ensuring consistent security across all YinzerFlow applications.
38
38
 
39
- ## Basic Example
39
+ ## Examples
40
+
41
+ ### Basic Example
40
42
 
41
43
  ```typescript
42
44
  import { YinzerFlow } from 'yinzerflow';
@@ -56,6 +58,9 @@ app.post('/api/users/:id', ({ request }) => {
56
58
 
57
59
  // Access request body
58
60
  const userData = request.body;
61
+
62
+ // Access raw body for manual parsing when needed
63
+ const rawBody = request.rawBody;
59
64
 
60
65
  const clientIp = request.ipAddress
61
66
 
@@ -68,7 +73,67 @@ app.post('/api/users/:id', ({ request }) => {
68
73
  receivedData: userData
69
74
  };
70
75
  });
71
- ```
76
+ ```
77
+
78
+ ### Body Parsing Example
79
+
80
+ YinzerFlow automatically parses request bodies (JSON, file uploads, forms) with built-in security protections. Parsed data is available on `request.body` - see [Body Parsing Documentation](./body-parsing.md) for detailed configuration options, examples, and security considerations.
81
+
82
+ ```typescript
83
+ app.post('/api/users', ({ request, response }) => {
84
+ // Body is automatically parsed based on Content-Type
85
+ const userData = request.body;
86
+
87
+ return {
88
+ message: 'User created successfully',
89
+ data: userData
90
+ };
91
+ });
92
+ ```
93
+
94
+ ### Raw Body Access Example
95
+
96
+ For advanced use cases where you need to manually parse the request body, YinzerFlow provides access to the raw body via `request.rawBody`. This is useful when:
97
+
98
+ - You need to implement custom parsing logic
99
+ - You want to validate the raw body before parsing
100
+ - You're working with unsupported content types
101
+ - You need to implement custom security validations
102
+
103
+ ```typescript
104
+ app.post('/api/custom-parser', ({ request }) => {
105
+ // Access the raw body as string or Buffer
106
+ const rawBody = request.rawBody;
107
+
108
+ // Implement custom parsing logic
109
+ if (typeof rawBody === 'string') {
110
+ // Custom string parsing
111
+ const customData = parseCustomFormat(rawBody);
112
+ return { parsed: customData };
113
+ } else if (Buffer.isBuffer(rawBody)) {
114
+ // Custom binary parsing
115
+ const binaryData = parseBinaryFormat(rawBody);
116
+ return { parsed: binaryData };
117
+ }
118
+
119
+ return { error: 'Unsupported body format' };
120
+ });
121
+
122
+ // Example: Custom XML parser
123
+ app.post('/api/xml', ({ request }) => {
124
+ const rawBody = request.rawBody;
125
+
126
+ if (typeof rawBody === 'string') {
127
+ // Parse XML manually
128
+ const xmlData = parseXML(rawBody);
129
+ return { xml: xmlData };
130
+ }
131
+
132
+ return { error: 'Expected string body for XML' };
133
+ });
134
+ ```
135
+
136
+ **Note**: The `rawBody` property contains the unprocessed request body as either a `string` or `Buffer`, depending on the content type and framework processing. Always validate and sanitize raw body data before processing to prevent security vulnerabilities.
72
137
 
73
138
  ## Common Use Cases
74
139
 
@@ -126,20 +191,4 @@ YinzerFlow implements several security measures to prevent common request-based
126
191
  - **Problem**: Spoofed proxy headers can bypass IP-based security controls
127
192
  - **YinzerFlow Solution**: Secure IP address extraction with proxy header validation prevents spoofing attacks
128
193
 
129
- ## Body Parsing
130
-
131
- YinzerFlow automatically parses request bodies (JSON, file uploads, forms) with built-in security protections. Parsed data is available on `request.body` - see [Body Parsing Documentation](./body-parsing.md) for detailed configuration options, examples, and security considerations.
132
-
133
- ```typescript
134
- app.post('/api/users', ({ request, response }) => {
135
- // Body is automatically parsed based on Content-Type
136
- const userData = request.body;
137
-
138
- return {
139
- message: 'User created successfully',
140
- data: userData
141
- };
142
- });
143
- ```
144
-
145
194
  These security measures ensure YinzerFlow's request implementation follows security best practices and prevents common attack vectors while maintaining RFC compliance and performance.