yinzerflow 0.1.18 → 0.2.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 +0 -296
- package/YinzerFlow.d.ts +565 -0
- package/YinzerFlow.js +24 -0
- package/YinzerFlow.js.map +42 -0
- package/docs/advanced-configuration-options.md +175 -0
- package/docs/body-parsing.md +294 -0
- package/docs/cors.md +187 -0
- package/docs/ip-security.md +232 -0
- package/docs/request.md +145 -0
- package/docs/response.md +251 -0
- package/docs/start-here.MD +116 -0
- package/example/index.ts +109 -53
- package/package.json +15 -17
- package/constants/index.d.ts +0 -86
- package/constants/index.js +0 -3
- package/constants/index.js.map +0 -13
- package/docs/README.md +0 -327
- package/docs/content-types.md +0 -390
- package/docs/error-handling.md +0 -266
- package/docs/file-parsers.md +0 -276
- package/docs/hooks.md +0 -289
- package/docs/routing.md +0 -204
- package/example/bun.lock +0 -866
- package/example/hooks/authentication.middleware.ts +0 -77
- package/example/package.json +0 -61
- package/example/routes/authentication.routes.ts +0 -243
- package/example/routes/content-types.ts +0 -116
- package/example/tsconfig.json +0 -32
- package/index.d.ts +0 -395
- package/index.js +0 -23
- package/index.js.map +0 -33
package/docs/error-handling.md
DELETED
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
# Error Handling in YinzerFlow
|
|
2
|
-
|
|
3
|
-
YinzerFlow provides a flexible and robust error handling system that allows you to gracefully handle errors in your application. This document explains the core concepts, features, and best practices for error handling.
|
|
4
|
-
|
|
5
|
-
## Core Concepts
|
|
6
|
-
|
|
7
|
-
Error handling in YinzerFlow occurs at multiple levels:
|
|
8
|
-
|
|
9
|
-
1. **Route and Hook Level**: Explicit error handling in your route handlers and hooks
|
|
10
|
-
2. **Global Error Handler**: A centralized error handler for unhandled errors
|
|
11
|
-
3. **Framework Level**: Built-in error handling for framework-level errors
|
|
12
|
-
|
|
13
|
-
## Route and Hook Level Error Handling
|
|
14
|
-
|
|
15
|
-
The most direct way to handle errors is within your route handlers and hooks using try/catch blocks:
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
app.get('/users/:id', async ({ request, response }) => {
|
|
19
|
-
try {
|
|
20
|
-
const user = await getUserById(request.params.id);
|
|
21
|
-
if (!user) {
|
|
22
|
-
response.setStatus(404);
|
|
23
|
-
return { error: 'User not found' };
|
|
24
|
-
}
|
|
25
|
-
return user;
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.error('Failed to retrieve user:', error);
|
|
28
|
-
response.setStatus(500);
|
|
29
|
-
return { error: 'Failed to retrieve user' };
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
This approach gives you fine-grained control over error handling for specific routes.
|
|
35
|
-
|
|
36
|
-
### Setting Status Codes
|
|
37
|
-
|
|
38
|
-
When an error occurs, you should set an appropriate HTTP status code using the `response.setStatus()` method:
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
response.setStatus(400); // Bad Request
|
|
42
|
-
response.setStatus(401); // Unauthorized
|
|
43
|
-
response.setStatus(403); // Forbidden
|
|
44
|
-
response.setStatus(404); // Not Found
|
|
45
|
-
response.setStatus(500); // Internal Server Error
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Returning Error Responses
|
|
49
|
-
|
|
50
|
-
After setting the status code, return an object with an error message:
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
return { error: 'Resource not found' };
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
You can include additional information in the error response:
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
return {
|
|
60
|
-
error: 'Validation failed',
|
|
61
|
-
details: [
|
|
62
|
-
{ field: 'email', message: 'Invalid email format' },
|
|
63
|
-
{ field: 'password', message: 'Password too short' }
|
|
64
|
-
]
|
|
65
|
-
};
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Global Error Handler
|
|
69
|
-
|
|
70
|
-
YinzerFlow provides a global error handler that catches unhandled errors in your application. By default, it:
|
|
71
|
-
|
|
72
|
-
1. Logs the error to the console
|
|
73
|
-
2. Sets the response status to 500 (Internal Server Error)
|
|
74
|
-
3. Returns a JSON object with an error message
|
|
75
|
-
|
|
76
|
-
### Default Error Handler
|
|
77
|
-
|
|
78
|
-
The default error handler is implemented as follows:
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
private readonly _defaultErrorHandler: TErrorFunction = ({ response }, error): unknown => {
|
|
82
|
-
console.error('Unhandled error:', error);
|
|
83
|
-
response.setStatus(HttpStatusCode.INTERNAL_SERVER_ERROR);
|
|
84
|
-
return { error: 'Internal Server Error' };
|
|
85
|
-
};
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Custom Error Handler
|
|
89
|
-
|
|
90
|
-
You can provide your own error handler when initializing YinzerFlow:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
const app = new YinzerFlow({
|
|
94
|
-
port: 3000,
|
|
95
|
-
errorHandler: ({ response }, error) => {
|
|
96
|
-
console.error('Custom error handler:', error);
|
|
97
|
-
response.setStatus(500);
|
|
98
|
-
|
|
99
|
-
// In development, include the stack trace
|
|
100
|
-
if (process.env.NODE_ENV === 'development') {
|
|
101
|
-
return {
|
|
102
|
-
error: error.message,
|
|
103
|
-
stack: error.stack,
|
|
104
|
-
timestamp: new Date().toISOString()
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// In production, return a generic message
|
|
109
|
-
return {
|
|
110
|
-
error: 'An unexpected error occurred',
|
|
111
|
-
timestamp: new Date().toISOString()
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Framework Level Error Handling
|
|
118
|
-
|
|
119
|
-
YinzerFlow handles framework-level errors automatically, such as:
|
|
120
|
-
|
|
121
|
-
- Invalid route paths
|
|
122
|
-
- Malformed request bodies
|
|
123
|
-
- Unsupported content types
|
|
124
|
-
|
|
125
|
-
These errors are handled internally and appropriate responses are sent to the client.
|
|
126
|
-
|
|
127
|
-
## Best Practices
|
|
128
|
-
|
|
129
|
-
### Use Specific Status Codes
|
|
130
|
-
|
|
131
|
-
Use the most specific HTTP status code for each error situation:
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
// Authentication error
|
|
135
|
-
response.setStatus(401);
|
|
136
|
-
return { error: 'Authentication required' };
|
|
137
|
-
|
|
138
|
-
// Authorization error
|
|
139
|
-
response.setStatus(403);
|
|
140
|
-
return { error: 'Permission denied' };
|
|
141
|
-
|
|
142
|
-
// Resource not found
|
|
143
|
-
response.setStatus(404);
|
|
144
|
-
return { error: 'User not found' };
|
|
145
|
-
|
|
146
|
-
// Validation error
|
|
147
|
-
response.setStatus(400);
|
|
148
|
-
return { error: 'Invalid input' };
|
|
149
|
-
|
|
150
|
-
// Server error
|
|
151
|
-
response.setStatus(500);
|
|
152
|
-
return { error: 'Internal server error' };
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Provide Helpful Error Messages
|
|
156
|
-
|
|
157
|
-
Error messages should be clear and actionable:
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
// Good
|
|
161
|
-
return { error: 'Email format is invalid' };
|
|
162
|
-
|
|
163
|
-
// Better
|
|
164
|
-
return {
|
|
165
|
-
error: 'Validation failed',
|
|
166
|
-
details: [
|
|
167
|
-
{ field: 'email', message: 'Email must be a valid email address' }
|
|
168
|
-
]
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// Avoid
|
|
172
|
-
return { error: 'Error occurred' };
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Log Errors Appropriately
|
|
176
|
-
|
|
177
|
-
Log errors with sufficient context for debugging:
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
try {
|
|
181
|
-
// Operation that might fail
|
|
182
|
-
} catch (error) {
|
|
183
|
-
console.error(`Failed to process order ${orderId}:`, error);
|
|
184
|
-
response.setStatus(500);
|
|
185
|
-
return { error: 'Failed to process order' };
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Handle Async Errors
|
|
190
|
-
|
|
191
|
-
Always use try/catch blocks with async operations:
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
app.get('/data', async ({ response }) => {
|
|
195
|
-
try {
|
|
196
|
-
const data = await fetchDataFromDatabase();
|
|
197
|
-
return data;
|
|
198
|
-
} catch (error) {
|
|
199
|
-
console.error('Database error:', error);
|
|
200
|
-
response.setStatus(500);
|
|
201
|
-
return { error: 'Failed to fetch data' };
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Common Error Scenarios
|
|
207
|
-
|
|
208
|
-
### Authentication Errors
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
app.beforeAll(({ request, response }) => {
|
|
212
|
-
const token = request.headers.authorization?.split(' ')[1];
|
|
213
|
-
if (!token) {
|
|
214
|
-
response.setStatus(401);
|
|
215
|
-
return { error: 'Authentication required' };
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
try {
|
|
219
|
-
const user = verifyToken(token);
|
|
220
|
-
request.state.user = user;
|
|
221
|
-
} catch (error) {
|
|
222
|
-
response.setStatus(401);
|
|
223
|
-
return { error: 'Invalid token' };
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Validation Errors
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
app.post('/users', ({ request, response }) => {
|
|
232
|
-
const { name, email, password } = request.body;
|
|
233
|
-
const errors = [];
|
|
234
|
-
|
|
235
|
-
if (!name) errors.push({ field: 'name', message: 'Name is required' });
|
|
236
|
-
if (!email) errors.push({ field: 'email', message: 'Email is required' });
|
|
237
|
-
if (!password) errors.push({ field: 'password', message: 'Password is required' });
|
|
238
|
-
|
|
239
|
-
if (errors.length > 0) {
|
|
240
|
-
response.setStatus(400);
|
|
241
|
-
return { error: 'Validation failed', details: errors };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Process valid data...
|
|
245
|
-
return { success: true };
|
|
246
|
-
});
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Not Found Errors
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
app.get('/users/:id', ({ request, response }) => {
|
|
253
|
-
const user = findUserById(request.params.id);
|
|
254
|
-
|
|
255
|
-
if (!user) {
|
|
256
|
-
response.setStatus(404);
|
|
257
|
-
return { error: 'User not found' };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return user;
|
|
261
|
-
});
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Conclusion
|
|
265
|
-
|
|
266
|
-
Effective error handling is crucial for building robust and user-friendly applications. YinzerFlow provides a flexible error handling system that allows you to handle errors at multiple levels, from route-specific handling to global error management. By following the best practices outlined in this document, you can ensure that your application gracefully handles errors and provides helpful feedback to users.
|
package/docs/file-parsers.md
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
# File Parsers
|
|
2
|
-
|
|
3
|
-
YinzerFlow provides robust support for parsing various file formats in HTTP requests and responses. This document explains the core concepts, features, and best practices for working with different file formats.
|
|
4
|
-
|
|
5
|
-
## Core Concepts
|
|
6
|
-
|
|
7
|
-
In web applications, files can be uploaded in various formats, such as YAML, CSV, and more. YinzerFlow automatically detects and parses these formats based on the file extension and content type, making it easy to work with different types of files.
|
|
8
|
-
|
|
9
|
-
### Parser Configuration
|
|
10
|
-
|
|
11
|
-
YinzerFlow allows you to configure how files are parsed through the `parserOptions` in your server configuration. You can control whether files should be automatically parsed:
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
const app = new YinzerFlow({
|
|
15
|
-
port: 5000,
|
|
16
|
-
parserOptions: {
|
|
17
|
-
yaml: {
|
|
18
|
-
raw: true,
|
|
19
|
-
},
|
|
20
|
-
json: {
|
|
21
|
-
raw: true,
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
// Other options...
|
|
25
|
-
});
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### Raw Mode
|
|
29
|
-
|
|
30
|
-
Setting `raw: true` in the parser options disables automatic parsing of files. This is useful when:
|
|
31
|
-
|
|
32
|
-
- You want to handle the parsing yourself
|
|
33
|
-
- You're dealing with binary files that don't need parsing
|
|
34
|
-
- You need to implement custom parsing logic
|
|
35
|
-
- You want to improve performance by avoiding unnecessary parsing
|
|
36
|
-
|
|
37
|
-
When raw mode is enabled, file contents will be provided as Buffer objects or strings, depending on the file type.
|
|
38
|
-
|
|
39
|
-
### Type Safety
|
|
40
|
-
|
|
41
|
-
YinzerFlow provides TypeScript interfaces and type guards for each supported file format, allowing you to work with file contents in a type-safe manner.
|
|
42
|
-
|
|
43
|
-
## Supported File Formats
|
|
44
|
-
|
|
45
|
-
YinzerFlow supports the following file formats out of the box:
|
|
46
|
-
|
|
47
|
-
| Format | MIME Type | Type Interface | Type Guard | Description |
|
|
48
|
-
|--------|-----------|----------------|------------|-------------|
|
|
49
|
-
| YAML | `text/yaml`, `application/x-yaml` | `TYamlData` | `isYamlData` | YAML data with support for complex structures |
|
|
50
|
-
| CSV (Coming Soon) | `text/csv` | `TCsvData` | `isCsvData` | CSV data with headers and rows |
|
|
51
|
-
| JSON (Coming Soon) | `application/json` | `TJsonData` | `isJsonData` | JSON data as a generic object |
|
|
52
|
-
|
|
53
|
-
## Working with File Parsers
|
|
54
|
-
|
|
55
|
-
There are two main approaches to working with parsed file contents in YinzerFlow:
|
|
56
|
-
|
|
57
|
-
### Approach 1: Type Casting (Simple but Less Safe)
|
|
58
|
-
|
|
59
|
-
This approach uses TypeScript's type assertion to specify the expected file format:
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { TYamlData } from 'yinzerflow/types/parsers/fileParsers/Yaml';
|
|
63
|
-
|
|
64
|
-
app.post('/upload', ({ request }) => {
|
|
65
|
-
// Use type assertion - simple but no runtime validation
|
|
66
|
-
const fileContent = request.file.content as TYamlData;
|
|
67
|
-
|
|
68
|
-
// Access the parsed data directly
|
|
69
|
-
const config = fileContent;
|
|
70
|
-
|
|
71
|
-
// Process the data...
|
|
72
|
-
return { success: true };
|
|
73
|
-
});
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**When to use this approach:**
|
|
77
|
-
- When you're certain about the file format (e.g., an internal API with controlled clients)
|
|
78
|
-
- When performance is critical and you want to avoid runtime type checking
|
|
79
|
-
- In simple applications where type safety is less important
|
|
80
|
-
|
|
81
|
-
### Approach 2: Type Guards (Safer and Recommended)
|
|
82
|
-
|
|
83
|
-
This approach uses runtime type checking for better safety:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
import { isYamlData } from 'yinzerflow/types/parsers/fileParsers/Yaml';
|
|
87
|
-
|
|
88
|
-
app.post('/upload', ({ request, response }) => {
|
|
89
|
-
// Runtime type checking
|
|
90
|
-
if (!isYamlData(request.file.content)) {
|
|
91
|
-
response.setStatus(400);
|
|
92
|
-
return { error: 'Expected YAML file' };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// TypeScript knows request.file.content is TYamlData here
|
|
96
|
-
const config = request.file.content;
|
|
97
|
-
|
|
98
|
-
// Process the data...
|
|
99
|
-
return { success: true };
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**When to use this approach:**
|
|
104
|
-
- When handling files from external clients
|
|
105
|
-
- When an endpoint might receive different file formats
|
|
106
|
-
- When you want to provide clear error messages for invalid files
|
|
107
|
-
- In most production applications (recommended approach)
|
|
108
|
-
|
|
109
|
-
### Approach 3: Manual Parsing (When Raw Mode is Enabled)
|
|
110
|
-
|
|
111
|
-
When you've configured YinzerFlow with `raw: true` in the parser options, you'll need to manually parse file contents:
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
// Your own custom parser
|
|
115
|
-
import { parseYaml } from 'custom/parser';
|
|
116
|
-
|
|
117
|
-
app.post('/upload', ({ request, response }) => {
|
|
118
|
-
// Get the raw file content (as Buffer or string)
|
|
119
|
-
const rawContent = request.file.content;
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
// Manually parse the content
|
|
123
|
-
const parsedContent = parseYaml(rawContent.toString());
|
|
124
|
-
|
|
125
|
-
// Process the parsed content
|
|
126
|
-
// ...
|
|
127
|
-
|
|
128
|
-
return { success: true };
|
|
129
|
-
} catch (error) {
|
|
130
|
-
response.setStatus(400);
|
|
131
|
-
return { error: 'Failed to parse YAML file' };
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**When to use this approach:**
|
|
137
|
-
- When you've disabled automatic parsing with `raw: true`
|
|
138
|
-
- When you need custom parsing logic
|
|
139
|
-
- When you want to handle parsing errors in a specific way
|
|
140
|
-
- When working with binary files or non-standard formats
|
|
141
|
-
|
|
142
|
-
## Detailed File Format Examples
|
|
143
|
-
|
|
144
|
-
### YAML Files
|
|
145
|
-
|
|
146
|
-
YAML is commonly used for configuration files and structured data:
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
import { isYamlData } from 'yinzerflow/types/parsers/fileParsers/Yaml';
|
|
150
|
-
|
|
151
|
-
app.post('/api/config', ({ request, response }) => {
|
|
152
|
-
if (!isYamlData(request.file.content)) {
|
|
153
|
-
response.setStatus(400);
|
|
154
|
-
return { error: 'Expected YAML file' };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Validate required fields
|
|
158
|
-
const config = request.file.content;
|
|
159
|
-
if (!config.version || !config.settings) {
|
|
160
|
-
response.setStatus(400);
|
|
161
|
-
return { error: 'Invalid YAML structure' };
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Process the configuration
|
|
165
|
-
const processedConfig = {
|
|
166
|
-
version: config.version,
|
|
167
|
-
settings: config.settings,
|
|
168
|
-
processedAt: new Date().toISOString()
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// Save the configuration (example)
|
|
172
|
-
saveConfig(processedConfig);
|
|
173
|
-
|
|
174
|
-
response.setStatus(201);
|
|
175
|
-
return processedConfig;
|
|
176
|
-
});
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
#### Type Definition
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
// The YAML data type
|
|
183
|
-
type TYamlData = Array<TYamlData> | boolean | number | string | { [key: string]: TYamlData } | null;
|
|
184
|
-
|
|
185
|
-
// Type guard for YAML data
|
|
186
|
-
const isYamlData = (content: unknown): content is TYamlData => {
|
|
187
|
-
// Implementation details...
|
|
188
|
-
};
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### CSV Files (Coming Soon)
|
|
192
|
-
|
|
193
|
-
CSV files are commonly used for data import/export:
|
|
194
|
-
|
|
195
|
-
### JSON Files (Coming Soon)
|
|
196
|
-
|
|
197
|
-
JSON files are commonly used for structured data:
|
|
198
|
-
|
|
199
|
-
## Best Practices
|
|
200
|
-
|
|
201
|
-
### 1. Always Validate File Contents
|
|
202
|
-
|
|
203
|
-
Always validate the file format and structure, especially for public APIs:
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
app.post('/api/import', ({ request, response }) => {
|
|
207
|
-
// Validate file format
|
|
208
|
-
if (!isYamlData(request.file.content)) {
|
|
209
|
-
response.setStatus(400);
|
|
210
|
-
return { error: 'Expected YAML file' };
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Validate required structure
|
|
214
|
-
const data = request.file.content;
|
|
215
|
-
if (!data || typeof data !== 'object') {
|
|
216
|
-
response.setStatus(400);
|
|
217
|
-
return { error: 'Invalid YAML structure' };
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Validate specific fields
|
|
221
|
-
const { name, version } = data;
|
|
222
|
-
if (!name || !version) {
|
|
223
|
-
response.setStatus(400);
|
|
224
|
-
return { error: 'Missing required fields' };
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Process the data...
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### 2. Use Type Guards for Public APIs
|
|
232
|
-
|
|
233
|
-
Always use type guards when handling files from external sources:
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
app.post('/api/upload', ({ request, response }) => {
|
|
237
|
-
// Check file type
|
|
238
|
-
if (!request.file.contentType.startsWith('text/yaml')) {
|
|
239
|
-
response.setStatus(415);
|
|
240
|
-
return { error: 'Unsupported file type' };
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Validate file content
|
|
244
|
-
if (!isYamlData(request.file.content)) {
|
|
245
|
-
response.setStatus(400);
|
|
246
|
-
return { error: 'Invalid YAML format' };
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Process the file...
|
|
250
|
-
});
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### 3. Handle Large Files Efficiently
|
|
254
|
-
|
|
255
|
-
When dealing with large files, consider using streams and processing data in chunks:
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
app.post('/api/import', async ({ request, response }) => {
|
|
259
|
-
if (!isYamlData(request.file.content)) {
|
|
260
|
-
response.setStatus(400);
|
|
261
|
-
return { error: 'Expected YAML file' };
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Process large files in chunks
|
|
265
|
-
const chunkSize = 1000;
|
|
266
|
-
const data = request.file.content;
|
|
267
|
-
|
|
268
|
-
for (let i = 0; i < data.length; i += chunkSize) {
|
|
269
|
-
const chunk = data.slice(i, i + chunkSize);
|
|
270
|
-
await processChunk(chunk);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return { success: true };
|
|
274
|
-
});
|
|
275
|
-
```
|
|
276
|
-
|