xypriss 2.2.0 → 2.2.2

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.
Files changed (49) hide show
  1. package/README.md +85 -30
  2. package/dist/cjs/src/file-upload.js +311 -0
  3. package/dist/cjs/src/file-upload.js.map +1 -0
  4. package/dist/cjs/src/index.js +8 -0
  5. package/dist/cjs/src/index.js.map +1 -1
  6. package/dist/cjs/src/plugins/modules/network/builtin/CompressionPlugin.js +2 -110
  7. package/dist/cjs/src/plugins/modules/network/builtin/CompressionPlugin.js.map +1 -1
  8. package/dist/cjs/src/plugins/modules/network/builtin/ConnectionPlugin.js.map +1 -1
  9. package/dist/cjs/src/plugins/modules/network/core/NetworkPlugin.js.map +1 -1
  10. package/dist/cjs/src/plugins/modules/network/types/NetworkTypes.js.map +1 -1
  11. package/dist/cjs/src/server/FastServer.js +64 -23
  12. package/dist/cjs/src/server/FastServer.js.map +1 -1
  13. package/dist/cjs/src/server/components/fastapi/FileUploadManager.js +13 -4
  14. package/dist/cjs/src/server/components/fastapi/FileUploadManager.js.map +1 -1
  15. package/dist/cjs/src/server/components/fastapi/RouteManager.js.map +1 -1
  16. package/dist/cjs/src/server/components/fastapi/smart-routes.js.map +1 -1
  17. package/dist/cjs/src/server/core/HttpServer.js +13 -0
  18. package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
  19. package/dist/cjs/src/server/core/XyprissApp.js.map +1 -1
  20. package/dist/cjs/src/server/handlers/NotFoundHandler.js.map +1 -1
  21. package/dist/cjs/src/server/optimization/RequestPreCompiler.js +1 -0
  22. package/dist/cjs/src/server/optimization/RequestPreCompiler.js.map +1 -1
  23. package/dist/cjs/src/server/utils/ConfigLoader.js +245 -148
  24. package/dist/cjs/src/server/utils/ConfigLoader.js.map +1 -1
  25. package/dist/esm/src/file-upload.js +304 -0
  26. package/dist/esm/src/file-upload.js.map +1 -0
  27. package/dist/esm/src/index.js +1 -0
  28. package/dist/esm/src/index.js.map +1 -1
  29. package/dist/esm/src/plugins/modules/network/builtin/CompressionPlugin.js +2 -110
  30. package/dist/esm/src/plugins/modules/network/builtin/CompressionPlugin.js.map +1 -1
  31. package/dist/esm/src/plugins/modules/network/builtin/ConnectionPlugin.js.map +1 -1
  32. package/dist/esm/src/plugins/modules/network/core/NetworkPlugin.js.map +1 -1
  33. package/dist/esm/src/plugins/modules/network/types/NetworkTypes.js.map +1 -1
  34. package/dist/esm/src/server/FastServer.js +64 -23
  35. package/dist/esm/src/server/FastServer.js.map +1 -1
  36. package/dist/esm/src/server/components/fastapi/FileUploadManager.js +13 -4
  37. package/dist/esm/src/server/components/fastapi/FileUploadManager.js.map +1 -1
  38. package/dist/esm/src/server/components/fastapi/RouteManager.js.map +1 -1
  39. package/dist/esm/src/server/components/fastapi/smart-routes.js.map +1 -1
  40. package/dist/esm/src/server/core/HttpServer.js +13 -0
  41. package/dist/esm/src/server/core/HttpServer.js.map +1 -1
  42. package/dist/esm/src/server/core/XyprissApp.js.map +1 -1
  43. package/dist/esm/src/server/handlers/NotFoundHandler.js.map +1 -1
  44. package/dist/esm/src/server/optimization/RequestPreCompiler.js +1 -0
  45. package/dist/esm/src/server/optimization/RequestPreCompiler.js.map +1 -1
  46. package/dist/esm/src/server/utils/ConfigLoader.js +227 -151
  47. package/dist/esm/src/server/utils/ConfigLoader.js.map +1 -1
  48. package/dist/index.d.ts +3854 -3734
  49. package/package.json +1 -2
package/README.md CHANGED
@@ -226,51 +226,106 @@ app.get(
226
226
 
227
227
  ## File Upload
228
228
 
229
- XyPriss provides seamless file upload support with full compatibility for multer and other multipart form-data parsers. No additional configuration needed - it works out of the box!
229
+ XyPriss provides powerful file upload support with **automatic error handling** and both class-based and functional APIs. No manual error handling required!
230
230
 
231
- ### Basic File Upload
231
+ ### Quick Start (Class-Based API - Recommended)
232
232
 
233
233
  ```typescript
234
234
  import { createServer } from "xypriss";
235
- import multer from "multer";
235
+ import { FileUploadAPI } from "xypriss";
236
236
 
237
237
  const app = createServer({
238
- server: { port: 3000 },
239
238
  fileUpload: {
239
+ enabled: true,
240
240
  maxFileSize: 5 * 1024 * 1024, // 5MB
241
- allowedMimeTypes: ["image/jpeg", "image/png", "application/pdf"]
242
- }
241
+ allowedMimeTypes: ["image/jpeg", "image/png"],
242
+ },
243
243
  });
244
244
 
245
- const upload = multer({ storage: multer.memoryStorage() });
246
-
247
- app.post("/upload", upload.single("file"), (req, res) => {
248
- if (!req.file) {
249
- return res.status(400).json({ error: "No file uploaded" });
250
- }
245
+ // Initialize file upload API
246
+ const fileUpload = new FileUploadAPI();
247
+ await fileUpload.initialize(app.options.fileUpload);
251
248
 
249
+ app.post("/upload", fileUpload.single("file"), (req, res) => {
250
+ // Automatic error handling - only success code here!
252
251
  res.json({
252
+ success: true,
253
253
  message: "File uploaded successfully",
254
254
  file: {
255
255
  name: req.file.originalname,
256
256
  size: req.file.size,
257
- type: req.file.mimetype
258
- }
257
+ type: req.file.mimetype,
258
+ },
259
+ });
260
+ });
261
+
262
+ app.start();
263
+ ```
264
+
265
+ ### Functional API (Simple)
266
+
267
+ ```typescript
268
+ import { createServer } from "xypriss";
269
+ import { uploadSingle } from "xypriss";
270
+
271
+ const app = createServer({
272
+ fileUpload: {
273
+ enabled: true,
274
+ maxFileSize: 5 * 1024 * 1024, // 5MB
275
+ storage: "memory",
276
+ },
277
+ });
278
+
279
+ app.post("/upload", uploadSingle("file"), (req, res) => {
280
+ // Automatic error handling - no try/catch needed!
281
+ res.json({
282
+ success: true,
283
+ file: req.file,
259
284
  });
260
285
  });
261
286
 
262
287
  app.start();
263
288
  ```
264
289
 
290
+ ### Automatic Error Responses
291
+
292
+ **File Too Large:**
293
+
294
+ ```json
295
+ {
296
+ "success": false,
297
+ "error": "File too large",
298
+ "message": "File size exceeds the maximum limit of 1.00MB",
299
+ "details": {
300
+ "maxSize": 1048576,
301
+ "maxSizeMB": "1.00",
302
+ "fileSize": "unknown"
303
+ }
304
+ }
305
+ ```
306
+
307
+ **File Type Not Allowed:**
308
+
309
+ ```json
310
+ {
311
+ "success": false,
312
+ "error": "File type not allowed",
313
+ "message": "File type 'application/exe' not allowed. Allowed types: image/jpeg, image/png"
314
+ }
315
+ ```
316
+
265
317
  ### Features
266
318
 
267
- - **Zero Configuration**: Works with existing multer code without changes
268
- - **Security**: Built-in file validation, virus scanning, and sanitization
269
- - **Flexible Storage**: Memory, disk, or cloud storage options
270
- - **Type Safety**: Full TypeScript support with proper type definitions
271
- - **Performance**: Optimized for large file uploads with streaming support
319
+ - **Automatic Error Handling**: Multer errors converted to user-friendly JSON responses
320
+ - **Class-Based API**: Modern `FileUploadAPI` class for better organization
321
+ - **Legacy Compatibility**: Functional API still available for simple use cases
322
+ - **Multipart Support**: Fixed multipart/form-data handling (no more "Unexpected end of form" errors)
323
+ - **Security**: Built-in file validation, type checking, and size limits
324
+ - ✅ **Flexible Storage**: Memory, disk, or custom storage backends
325
+ - ✅ **Type Safety**: Full TypeScript support with proper type definitions
326
+ - ✅ **Performance**: Optimized for large file uploads with streaming support
272
327
 
273
- For detailed configuration options, see the [File Upload Documentation](./docs/file-upload.md).
328
+ For comprehensive documentation, configuration options, and advanced usage, see the [File Upload Guide](./docs/file-upload.md).
274
329
 
275
330
  ---
276
331
 
@@ -291,17 +346,17 @@ const app = createServer({
291
346
  id: "api-server",
292
347
  port: 3001,
293
348
  routePrefix: "/api",
294
- allowedRoutes: ["/api/*"]
349
+ allowedRoutes: ["/api/*"],
295
350
  },
296
351
  {
297
352
  id: "admin-server",
298
353
  port: 3002,
299
354
  routePrefix: "/admin",
300
355
  allowedRoutes: ["/admin/*"],
301
- security: { level: "maximum" }
302
- }
303
- ]
304
- }
356
+ security: { level: "maximum" },
357
+ },
358
+ ],
359
+ },
305
360
  });
306
361
 
307
362
  // Routes are automatically distributed to appropriate servers
@@ -314,11 +369,11 @@ await app.startAllServers();
314
369
 
315
370
  ### Features
316
371
 
317
- - **Simple API**: `startAllServers()` and `stopAllServers()` hide complexity
318
- - **Automatic Route Distribution**: Routes are filtered and distributed automatically
319
- - **Server-Specific Overrides**: Each server can have different security, cache, and performance settings
320
- - **Microservices Ready**: Perfect for API versioning and service separation
321
- - **Load Balancing**: Built-in support for reverse proxy load balancing
372
+ - **Simple API**: `startAllServers()` and `stopAllServers()` hide complexity
373
+ - **Automatic Route Distribution**: Routes are filtered and distributed automatically
374
+ - **Server-Specific Overrides**: Each server can have different security, cache, and performance settings
375
+ - **Microservices Ready**: Perfect for API versioning and service separation
376
+ - **Load Balancing**: Built-in support for reverse proxy load balancing
322
377
 
323
378
  For comprehensive multi-server documentation, see the [Multi-Server Guide](./docs/multi-server.md).
324
379
 
@@ -0,0 +1,311 @@
1
+ 'use strict';
2
+
3
+ var FileUploadManager = require('./server/components/fastapi/FileUploadManager.js');
4
+
5
+ /**
6
+ * XyPriss File Upload API
7
+ *
8
+ * This module provides file upload middleware functions that can be used
9
+ * independently of the app instance initialization timing.
10
+ *
11
+ * Usage:
12
+ * ```typescript
13
+ * import { FileUploadAPI } from 'xypriss';
14
+ *
15
+ * const fileUpload = new FileUploadAPI();
16
+ * router.post('/upload', fileUpload.single('file'), (req, res) => {
17
+ * console.log(req.file);
18
+ * res.json({ success: true });
19
+ * });
20
+ * ```
21
+ */
22
+ /**
23
+ * File Upload API Class
24
+ * Provides a clean, class-based interface for file upload middleware
25
+ */
26
+ class FileUploadAPI {
27
+ constructor(logger) {
28
+ this.manager = null;
29
+ this.initialized = false;
30
+ // Use a default logger if none provided
31
+ this.logger =
32
+ logger ||
33
+ {
34
+ debug: console.debug.bind(console),
35
+ info: console.info.bind(console),
36
+ warn: console.warn.bind(console),
37
+ error: console.error.bind(console),
38
+ };
39
+ }
40
+ /**
41
+ * Initialize the file upload API with configuration
42
+ */
43
+ async initialize(options) {
44
+ if (this.initialized) {
45
+ return; // Already initialized
46
+ }
47
+ try {
48
+ this.logger.debug("server", "Initializing FileUploadAPI...");
49
+ this.manager = new FileUploadManager.FileUploadManager(options, this.logger);
50
+ await this.manager.initialize();
51
+ this.initialized = true;
52
+ this.logger.debug("server", `FileUploadAPI initialized, enabled: ${this.manager.isEnabled()}`);
53
+ }
54
+ catch (error) {
55
+ this.logger.error("server", "Failed to initialize FileUploadAPI:", error.message);
56
+ throw error;
57
+ }
58
+ }
59
+ /**
60
+ * Check if the file upload API is enabled
61
+ */
62
+ isEnabled() {
63
+ return this.manager?.isEnabled() === true;
64
+ }
65
+ /**
66
+ * Handle multer errors and convert them to proper HTTP responses
67
+ */
68
+ handleMulterError(err, req, res) {
69
+ if (err.code === "LIMIT_FILE_SIZE") {
70
+ const maxSize = this.manager?.getConfig()?.maxFileSize || 1024 * 1024;
71
+ const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2);
72
+ res.status(400).json({
73
+ success: false,
74
+ error: "File too large",
75
+ message: `File size exceeds the maximum limit of ${maxSizeMB}MB`,
76
+ details: {
77
+ maxSize,
78
+ maxSizeMB,
79
+ fileSize: req.file ? req.file.size : "unknown",
80
+ },
81
+ });
82
+ return;
83
+ }
84
+ if (err.code === "LIMIT_UNEXPECTED_FILE") {
85
+ res.status(400).json({
86
+ success: false,
87
+ error: "Unexpected field",
88
+ message: "Unexpected file field name",
89
+ });
90
+ return;
91
+ }
92
+ if (err.code === "LIMIT_FILE_COUNT") {
93
+ res.status(400).json({
94
+ success: false,
95
+ error: "Too many files",
96
+ message: "Too many files uploaded",
97
+ });
98
+ return;
99
+ }
100
+ // Handle custom file filter errors
101
+ if (err.message) {
102
+ if (err.message.includes("File too large")) {
103
+ res.status(400).json({
104
+ success: false,
105
+ error: "File too large",
106
+ message: err.message,
107
+ });
108
+ return;
109
+ }
110
+ if (err.message.includes("not allowed")) {
111
+ res.status(400).json({
112
+ success: false,
113
+ error: "File type not allowed",
114
+ message: err.message,
115
+ });
116
+ return;
117
+ }
118
+ }
119
+ // Generic multer error
120
+ res.status(400).json({
121
+ success: false,
122
+ error: "Upload error",
123
+ message: err.message || "An error occurred during file upload",
124
+ });
125
+ }
126
+ /**
127
+ * Create a middleware for uploading a single file
128
+ *
129
+ * @param fieldname - The name of the form field containing the file
130
+ * @returns Express middleware function
131
+ */
132
+ single(fieldname) {
133
+ return (req, res, next) => {
134
+ if (!this.isEnabled()) {
135
+ return res.status(500).json({
136
+ success: false,
137
+ error: "Configuration Error",
138
+ message: "File upload not enabled. Set fileUpload.enabled to true in server options.",
139
+ });
140
+ }
141
+ // Use multer middleware with built-in error handling
142
+ this.manager.single(fieldname)(req, res, (err) => {
143
+ if (err) {
144
+ this.handleMulterError(err, req, res);
145
+ }
146
+ else {
147
+ next();
148
+ }
149
+ });
150
+ };
151
+ }
152
+ /**
153
+ * Create a middleware for uploading multiple files with the same field name
154
+ *
155
+ * @param fieldname - The name of the form field containing the files
156
+ * @param maxCount - Maximum number of files to accept (optional)
157
+ * @returns Express middleware function
158
+ */
159
+ array(fieldname, maxCount) {
160
+ return (req, res, next) => {
161
+ if (!this.isEnabled()) {
162
+ return res.status(500).json({
163
+ success: false,
164
+ error: "Configuration Error",
165
+ message: "File upload not enabled. Set fileUpload.enabled to true in server options.",
166
+ });
167
+ }
168
+ this.manager.array(fieldname, maxCount)(req, res, (err) => {
169
+ if (err) {
170
+ this.handleMulterError(err, req, res);
171
+ }
172
+ else {
173
+ next();
174
+ }
175
+ });
176
+ };
177
+ }
178
+ /**
179
+ * Create a middleware for uploading multiple files with different field names
180
+ *
181
+ * @param fields - Array of field configurations
182
+ * @returns Express middleware function
183
+ */
184
+ fields(fields) {
185
+ return (req, res, next) => {
186
+ if (!this.isEnabled()) {
187
+ return res.status(500).json({
188
+ success: false,
189
+ error: "Configuration Error",
190
+ message: "File upload not enabled. Set fileUpload.enabled to true in server options.",
191
+ });
192
+ }
193
+ this.manager.fields(fields)(req, res, (err) => {
194
+ if (err) {
195
+ this.handleMulterError(err, req, res);
196
+ }
197
+ else {
198
+ next();
199
+ }
200
+ });
201
+ };
202
+ }
203
+ /**
204
+ * Create a middleware for uploading any files (accepts all files)
205
+ *
206
+ * @returns Express middleware function
207
+ */
208
+ any() {
209
+ return (req, res, next) => {
210
+ if (!this.isEnabled()) {
211
+ return res.status(500).json({
212
+ success: false,
213
+ error: "Configuration Error",
214
+ message: "File upload not enabled. Set fileUpload.enabled to true in server options.",
215
+ });
216
+ }
217
+ this.manager.any()(req, res, (err) => {
218
+ if (err) {
219
+ this.handleMulterError(err, req, res);
220
+ }
221
+ else {
222
+ next();
223
+ }
224
+ });
225
+ };
226
+ }
227
+ }
228
+ // Legacy function exports for backward compatibility
229
+ // These will be deprecated in favor of the class-based API
230
+ // Global instance for backward compatibility
231
+ let globalFileUploadAPI = null;
232
+ /**
233
+ * Initialize the global file upload manager (legacy)
234
+ * This is called automatically when the server starts with file upload enabled
235
+ */
236
+ function initializeFileUpload(options, logger) {
237
+ if (!globalFileUploadAPI) {
238
+ globalFileUploadAPI = new FileUploadAPI(logger);
239
+ }
240
+ globalFileUploadAPI.initialize(options);
241
+ }
242
+ /**
243
+ * Create a middleware for uploading a single file (legacy)
244
+ */
245
+ function uploadSingle(fieldname) {
246
+ return (req, res, next) => {
247
+ if (!globalFileUploadAPI) {
248
+ return res.status(500).json({
249
+ success: false,
250
+ error: "Configuration Error",
251
+ message: "File upload not initialized. Make sure fileUpload.enabled is true in server options.",
252
+ });
253
+ }
254
+ return globalFileUploadAPI.single(fieldname)(req, res, next);
255
+ };
256
+ }
257
+ /**
258
+ * Create a middleware for uploading multiple files with the same field name (legacy)
259
+ */
260
+ function uploadArray(fieldname, maxCount) {
261
+ return (req, res, next) => {
262
+ if (!globalFileUploadAPI) {
263
+ return res.status(500).json({
264
+ success: false,
265
+ error: "Configuration Error",
266
+ message: "File upload not initialized. Make sure fileUpload.enabled is true in server options.",
267
+ });
268
+ }
269
+ return globalFileUploadAPI.array(fieldname, maxCount)(req, res, next);
270
+ };
271
+ }
272
+ /**
273
+ * Create a middleware for uploading multiple files with different field names (legacy)
274
+ */
275
+ function uploadFields(fields) {
276
+ return (req, res, next) => {
277
+ if (!globalFileUploadAPI) {
278
+ return res.status(500).json({
279
+ success: false,
280
+ error: "Configuration Error",
281
+ message: "File upload not initialized. Make sure fileUpload.enabled is true in server options.",
282
+ });
283
+ }
284
+ return globalFileUploadAPI.fields(fields)(req, res, next);
285
+ };
286
+ }
287
+ /**
288
+ * Create a middleware for uploading any files (legacy)
289
+ */
290
+ function uploadAny() {
291
+ return (req, res, next) => {
292
+ if (!globalFileUploadAPI) {
293
+ return res.status(500).json({
294
+ success: false,
295
+ error: "Configuration Error",
296
+ message: "File upload not initialized. Make sure fileUpload.enabled is true in server options.",
297
+ });
298
+ }
299
+ return globalFileUploadAPI.any()(req, res, next);
300
+ };
301
+ }
302
+ // Export types for TypeScript users
303
+ // Types are available through the main types export
304
+
305
+ exports.FileUploadAPI = FileUploadAPI;
306
+ exports.initializeFileUpload = initializeFileUpload;
307
+ exports.uploadAny = uploadAny;
308
+ exports.uploadArray = uploadArray;
309
+ exports.uploadFields = uploadFields;
310
+ exports.uploadSingle = uploadSingle;
311
+ //# sourceMappingURL=file-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.js","sources":["../../../src/file-upload.ts"],"sourcesContent":[null],"names":["FileUploadManager"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var fileUpload = require('./file-upload.js');
3
4
  var Router$1 = require('./server/routing/Router.js');
4
5
  var ServerFactory = require('./server/ServerFactory.js');
5
6
  var smartRoutes = require('./server/components/fastapi/smart-routes.js');
@@ -65,6 +66,13 @@ function Router() {
65
66
  });
66
67
  }
67
68
 
69
+ exports.FLA = fileUpload.FileUploadAPI;
70
+ exports.FileUploadAPI = fileUpload.FileUploadAPI;
71
+ exports.initializeFileUpload = fileUpload.initializeFileUpload;
72
+ exports.uploadAny = fileUpload.uploadAny;
73
+ exports.uploadArray = fileUpload.uploadArray;
74
+ exports.uploadFields = fileUpload.uploadFields;
75
+ exports.uploadSingle = fileUpload.uploadSingle;
68
76
  exports.XyPrissRouter = Router$1.XyPrissRouter;
69
77
  exports.createCacheMiddleware = ServerFactory.createCacheMiddleware;
70
78
  exports.createServer = ServerFactory.createServer;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":[null],"names":["XyPrissRouter"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBiF;AAgCjF;;AAEG;SACa,MAAM,GAAA;IAClB,OAAO,IAAIA,sBAAa,CAAC;AACrB,QAAA,aAAa,EAAE,KAAK;AACpB,QAAA,WAAW,EAAE,KAAK;AAClB,QAAA,MAAM,EAAE,KAAK;AAChB,KAAA,CAAC,CAAC;AACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":[null],"names":["XyPrissRouter"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBiF;AAoCjF;;AAEG;SACa,MAAM,GAAA;IAClB,OAAO,IAAIA,sBAAa,CAAC;AACrB,QAAA,aAAa,EAAE,KAAK;AACpB,QAAA,WAAW,EAAE,KAAK;AAClB,QAAA,MAAM,EAAE,KAAK;AAChB,KAAA,CAAC,CAAC;AACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -183,7 +183,7 @@ class CompressionPlugin extends NetworkPlugin.NetworkPlugin {
183
183
  return false;
184
184
  }
185
185
  // Check content type
186
- const contentType = res.get("Content-Type") || "";
186
+ const contentType = String(res.get("Content-Type") || "");
187
187
  if (!this.shouldCompressContentType(contentType)) {
188
188
  return false;
189
189
  }
@@ -192,7 +192,7 @@ class CompressionPlugin extends NetworkPlugin.NetworkPlugin {
192
192
  return false;
193
193
  }
194
194
  // Check content length threshold
195
- const contentLength = parseInt(res.get("Content-Length") || "0");
195
+ const contentLength = parseInt(String(res.get("Content-Length") || "0"));
196
196
  if (contentLength > 0 && contentLength < (config.threshold || 1024)) {
197
197
  return false;
198
198
  }
@@ -238,112 +238,6 @@ class CompressionPlugin extends NetworkPlugin.NetworkPlugin {
238
238
  }
239
239
  return contentType.toLowerCase().includes(pattern.toLowerCase());
240
240
  }
241
- /**
242
- * Select best compression algorithm based on client support and preferences
243
- */
244
- selectCompressionAlgorithm(req) {
245
- const acceptEncoding = req.get("Accept-Encoding") || "";
246
- const encodings = acceptEncoding.toLowerCase();
247
- // Priority order: brotli > gzip > deflate
248
- const priorityOrder = [
249
- "brotli",
250
- "gzip",
251
- "deflate",
252
- ];
253
- for (const algorithm of priorityOrder) {
254
- if (this.supportedAlgorithms.includes(algorithm) &&
255
- encodings.includes(algorithm)) {
256
- return algorithm;
257
- }
258
- }
259
- return null;
260
- }
261
- /**
262
- * Apply compression to response
263
- */
264
- async applyCompression(context, algorithm) {
265
- const { res } = context;
266
- const config = this.getCompressionConfig();
267
- // Set compression headers
268
- res.setHeader("Content-Encoding", algorithm);
269
- res.setHeader("Vary", "Accept-Encoding");
270
- // Remove content-length header as it will change
271
- res.removeHeader("Content-Length");
272
- // Create compression stream
273
- const compressionStream = this.createCompressionStream(algorithm, config.level || 6);
274
- // Intercept response write/end methods
275
- this.interceptResponse(res, compressionStream, context);
276
- }
277
- /**
278
- * Create compression stream for algorithm
279
- */
280
- createCompressionStream(algorithm, level) {
281
- switch (algorithm) {
282
- case "gzip":
283
- return zlib__namespace.createGzip({ level });
284
- case "deflate":
285
- return zlib__namespace.createDeflate({ level });
286
- case "brotli":
287
- return zlib__namespace.createBrotliCompress({
288
- params: {
289
- [zlib__namespace.constants.BROTLI_PARAM_QUALITY]: level,
290
- },
291
- });
292
- default:
293
- throw new Error(`Unsupported compression algorithm: ${algorithm}`);
294
- }
295
- }
296
- /**
297
- * Intercept response to apply compression
298
- */
299
- interceptResponse(res, compressionStream, context) {
300
- res.write.bind(res);
301
- res.end.bind(res);
302
- let originalSize = 0;
303
- let compressedSize = 0;
304
- // Track compressed data
305
- compressionStream.on("data", (chunk) => {
306
- compressedSize += chunk.length;
307
- });
308
- // Override write method
309
- res.write = function (chunk, encoding, callback) {
310
- if (chunk) {
311
- originalSize += Buffer.isBuffer(chunk)
312
- ? chunk.length
313
- : Buffer.byteLength(chunk, encoding);
314
- return compressionStream.write(chunk, encoding, callback);
315
- }
316
- return true;
317
- };
318
- // Override end method
319
- res.end = function (chunk, encoding, callback) {
320
- if (chunk) {
321
- originalSize += Buffer.isBuffer(chunk)
322
- ? chunk.length
323
- : Buffer.byteLength(chunk, encoding);
324
- }
325
- compressionStream.end(chunk, encoding, () => {
326
- // Update metrics
327
- context.networkMetrics.bytesSent = compressedSize;
328
- context.networkMetrics.compressionRatio =
329
- originalSize > 0 ? compressedSize / originalSize : 1;
330
- if (callback)
331
- callback();
332
- });
333
- return this;
334
- };
335
- // Pipe compression stream to response
336
- compressionStream.pipe(res, { end: false });
337
- }
338
- /**
339
- * Update compression statistics
340
- */
341
- updateCompressionStats(algorithm) {
342
- this.compressionStats.totalRequests++;
343
- this.compressionStats.compressedRequests++;
344
- const currentUsage = this.compressionStats.algorithmUsage.get(algorithm) || 0;
345
- this.compressionStats.algorithmUsage.set(algorithm, currentUsage + 1);
346
- }
347
241
  /**
348
242
  * Get compression configuration
349
243
  */
@@ -371,8 +265,6 @@ class CompressionPlugin extends NetworkPlugin.NetworkPlugin {
371
265
  async checkNetworkHealth() {
372
266
  const errorRate = this.performanceMetrics.errorCount /
373
267
  Math.max(this.performanceMetrics.totalExecutions, 1);
374
- this.compressionStats.compressedRequests /
375
- Math.max(this.compressionStats.totalRequests, 1);
376
268
  return {
377
269
  healthy: errorRate < 0.1 &&
378
270
  this.performanceMetrics.averageExecutionTime <