multermate 2.1.1 → 2.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 CHANGED
@@ -1,496 +1,524 @@
1
- # Multer Mate
2
-
3
- A robust and flexible file upload utility built on top of Multer, providing advanced file handling capabilities for Node.js applications. Now with full TypeScript support, universal JavaScript compatibility, and comprehensive error handling!
4
-
5
- ## Features
6
-
7
- - 📁 Flexible file storage configuration
8
- - 🔒 Built-in file type validation
9
- - 📦 Single and multiple file uploads
10
- - 🎯 Field-specific file type restrictions
11
- - 🗑️ File deletion utility
12
- - ⚡ Configurable file size limits
13
- - 🎨 Custom MIME type support
14
- - 🔄 Unique file naming with UUID
15
- - 🛡️ Path sanitization
16
- - 📝 Comprehensive error handling with MultermateError
17
- - 🔌 **Universal JavaScript compatibility** (CommonJS, ES Modules, TypeScript)
18
- - 📘 Full TypeScript definitions and type safety
19
- - 🌐 **Accept ANY file type** when no restrictions are specified
20
- - 🎪 **Enhanced file type categories** (fonts, archives, CAD files, 3D models, etc.)
21
- - 🚨 **Custom error classes** for better error handling
22
- - 🔧 **Fixed form data processing** issues
23
-
24
- ## Installation
25
-
26
- ```bash
27
- npm install multermate
28
- ```
29
-
30
- ## Universal JavaScript Compatibility
31
-
32
- MulterMate works seamlessly across all JavaScript environments:
33
-
34
- ### CommonJS
35
-
36
- ```javascript
37
- const {
38
- uploadSingle,
39
- uploadMultiple,
40
- deleteFile,
41
- MultermateError,
42
- } = require("multermate");
43
- ```
44
-
45
- ### ES Modules
46
-
47
- ```javascript
48
- import {
49
- uploadSingle,
50
- uploadMultiple,
51
- deleteFile,
52
- MultermateError,
53
- } from "multermate";
54
- ```
55
-
56
- ### TypeScript
57
-
58
- ```typescript
59
- import {
60
- uploadSingle,
61
- uploadMultiple,
62
- deleteFile,
63
- MultermateError,
64
- UploadSingleOptions,
65
- UploadMultipleOptions,
66
- } from "multermate";
67
-
68
- // With type definitions
69
- const options: UploadSingleOptions = {
70
- destination: "uploads/images",
71
- fileTypes: ["images"],
72
- fileSizeLimit: 5 * 1024 * 1024,
73
- };
74
- ```
75
-
76
- ## Upload Configurations
77
-
78
- ### Accept ANY File Type
79
-
80
- By default, when no `fileTypes` or `customMimeTypes` are specified, MulterMate accepts **ALL file types**:
81
-
82
- ```javascript
83
- // Accept any file type - no restrictions!
84
- app.post("/upload", uploadSingle(), (req, res) => {
85
- res.json({ file: req.file });
86
- });
87
-
88
- // Also works with destination
89
- app.post(
90
- "/upload-any",
91
- uploadSingle({
92
- destination: "uploads/any-files",
93
- filename: "uploaded-file",
94
- // No fileTypes specified = accept all file types
95
- }),
96
- (req, res) => {
97
- res.json({ file: req.file });
98
- }
99
- );
100
- ```
101
-
102
- ### Single File Upload
103
-
104
- ```javascript
105
- // Basic single file upload
106
- app.post("/upload", uploadSingle(), (req, res) => {
107
- if (req.fileValidationError) {
108
- return res.status(400).json({ error: req.fileValidationError });
109
- }
110
- res.json({ file: req.file });
111
- });
112
-
113
- // Advanced single file upload with specific file types
114
- app.post(
115
- "/upload/advanced",
116
- uploadSingle({
117
- destination: "uploads/images",
118
- filename: "profile",
119
- fileTypes: ["images"],
120
- fileSizeLimit: 5 * 1024 * 1024, // 5MB
121
- preservePath: false,
122
- }),
123
- (req, res) => {
124
- res.json({ file: req.file });
125
- }
126
- );
127
- ```
128
-
129
- ### Multiple Files Upload
130
-
131
- ```javascript
132
- // Multiple fields with different configurations
133
- app.post(
134
- "/upload/multiple",
135
- uploadMultiple({
136
- fields: [
137
- {
138
- name: "avatar",
139
- maxCount: 1,
140
- fileTypes: ["images"],
141
- },
142
- {
143
- name: "documents",
144
- maxCount: 5,
145
- fileTypes: ["documents", "text"],
146
- },
147
- {
148
- name: "any-files", // No fileTypes = accept any file type
149
- maxCount: 3,
150
- },
151
- ],
152
- destination: "uploads/mixed",
153
- fileSizeLimit: 10 * 1024 * 1024, // 10MB per file
154
- }),
155
- (req, res) => {
156
- res.json({ files: req.files });
157
- }
158
- );
159
- ```
160
-
161
- ### Enhanced File Type Categories
162
-
163
- MulterMate now supports comprehensive file type categories:
164
-
165
- ```javascript
166
- app.post(
167
- "/upload-comprehensive",
168
- uploadSingle({
169
- destination: "uploads/comprehensive",
170
- fileTypes: [
171
- "images", // JPEG, PNG, GIF, WebP, SVG, etc.
172
- "videos", // MP4, AVI, MOV, WebM, etc.
173
- "audio", // MP3, WAV, FLAC, AAC, etc.
174
- "documents", // PDF, DOC, DOCX, XLS, XLSX, PPT, etc.
175
- "text", // TXT, CSV, HTML, CSS, JS, MD, etc.
176
- "archives", // ZIP, RAR, 7Z, TAR, GZIP, etc.
177
- "fonts", // WOFF, WOFF2, TTF, OTF, etc.
178
- "code", // JSON, XML, JS, TS, Python, etc.
179
- "spreadsheets", // Excel, CSV files
180
- "presentations", // PowerPoint, etc.
181
- "cad", // CAD files
182
- "models", // 3D model files
183
- ],
184
- }),
185
- (req, res) => {
186
- res.json({ file: req.file });
187
- }
188
- );
189
- ```
190
-
191
- ### Custom MIME Types
192
-
193
- ```javascript
194
- app.post(
195
- "/upload/custom",
196
- uploadSingle({
197
- destination: "uploads/custom",
198
- customMimeTypes: [
199
- "application/vnd.ms-excel",
200
- "application/json",
201
- "text/csv",
202
- "application/x-custom-type",
203
- ],
204
- fileSizeLimit: 1024 * 1024, // 1MB
205
- }),
206
- (req, res) => {
207
- res.json({ file: req.file });
208
- }
209
- );
210
- ```
211
-
212
- ## Enhanced Error Handling
213
-
214
- MulterMate now includes a custom `MultermateError` class for better error handling:
215
-
216
- ```javascript
217
- app.post("/upload", uploadSingle(), (req, res) => {
218
- // Handle validation errors
219
- if (req.fileValidationError) {
220
- return res.status(400).json({
221
- error: req.fileValidationError,
222
- });
223
- }
224
-
225
- // Handle missing files
226
- if (!req.file) {
227
- return res.status(400).json({
228
- error: "No file uploaded",
229
- });
230
- }
231
-
232
- // Success response
233
- res.json({
234
- success: true,
235
- file: {
236
- filename: req.file.filename,
237
- path: req.file.path,
238
- size: req.file.size,
239
- mimetype: req.file.mimetype,
240
- },
241
- });
242
- });
243
-
244
- // Global error handler for MultermateError
245
- app.use((err, req, res, next) => {
246
- if (err instanceof MultermateError) {
247
- return res.status(400).json({
248
- success: false,
249
- error: err.message,
250
- code: err.code,
251
- field: err.field,
252
- });
253
- }
254
-
255
- // Handle other errors
256
- res.status(500).json({
257
- success: false,
258
- error: err.message,
259
- });
260
- });
261
- ```
262
-
263
- ### File Deletion with Error Handling
264
-
265
- ```javascript
266
- const { deleteFile, MultermateError } = require("multermate");
267
-
268
- app.delete("/files/:filename", async (req, res) => {
269
- try {
270
- await deleteFile(`uploads/${req.params.filename}`);
271
- res.json({
272
- success: true,
273
- message: "File deleted successfully",
274
- });
275
- } catch (error) {
276
- if (error instanceof MultermateError) {
277
- return res.status(400).json({
278
- success: false,
279
- error: error.message,
280
- code: error.code,
281
- });
282
- }
283
-
284
- res.status(500).json({
285
- success: false,
286
- message: "Failed to delete file",
287
- });
288
- }
289
- });
290
- ```
291
-
292
- ## API Reference
293
-
294
- ### uploadSingle(options)
295
-
296
- Configures single file upload with the following options:
297
-
298
- | Option | Type | Default | Description |
299
- | --------------- | -------- | --------- | ------------------------------------------ |
300
- | destination | string | 'uploads' | Upload directory path |
301
- | filename | string | 'file' | Form field name |
302
- | fileTypes | string[] | [] | Allowed file type categories (empty = all) |
303
- | customMimeTypes | string[] | [] | Custom MIME types |
304
- | fileSizeLimit | number | 50MB | Max file size in bytes |
305
- | preservePath | boolean | false | Preserve original path |
306
-
307
- ### uploadMultiple(options)
308
-
309
- Configures multiple file uploads with the following options:
310
-
311
- | Option | Type | Default | Description |
312
- | --------------- | -------- | --------- | -------------------- |
313
- | fields | Field[] | [] | Field configurations |
314
- | destination | string | 'uploads' | Upload directory |
315
- | customMimeTypes | string[] | [] | Custom MIME types |
316
- | fileSizeLimit | number | 50MB | Max file size |
317
- | preservePath | boolean | false | Preserve paths |
318
-
319
- #### Field Configuration
320
-
321
- | Option | Type | Default | Description |
322
- | ------------- | -------- | ------- | ---------------------------------------- |
323
- | name | string | - | Field name (required) |
324
- | maxCount | number | 10 | Max files per field |
325
- | fileTypes | string[] | [] | Allowed types (empty = accept all types) |
326
- | fileSizeLimit | number | 50MB | Max file size |
327
-
328
- ### deleteFile(filePath)
329
-
330
- Deletes a file from the filesystem:
331
-
332
- | Parameter | Type | Description |
333
- | --------- | ---------------- | ---------------- |
334
- | filePath | string | Path to file |
335
- | Returns | Promise<boolean> | Deletion success |
336
-
337
- ### MultermateError Class
338
-
339
- Custom error class for better error handling:
340
-
341
- ```typescript
342
- class MultermateError extends Error {
343
- code?: string; // Error code (e.g., 'FILE_SIZE_LIMIT_EXCEEDED')
344
- field?: string; // Field name that caused the error
345
- storageErrors?: string[]; // Additional storage errors
346
- }
347
- ```
348
-
349
- ### Supported File Type Categories
350
-
351
- ```javascript
352
- const SUPPORTED_CATEGORIES = {
353
- images: [
354
- "image/jpeg",
355
- "image/png",
356
- "image/gif",
357
- "image/webp",
358
- "image/svg+xml",
359
- "...",
360
- ],
361
- videos: ["video/mp4", "video/avi", "video/mov", "video/webm", "..."],
362
- audio: ["audio/mp3", "audio/wav", "audio/flac", "audio/aac", "..."],
363
- documents: ["application/pdf", "application/msword", "..."],
364
- text: ["text/plain", "text/csv", "text/html", "text/markdown", "..."],
365
- archives: ["application/zip", "application/x-rar-compressed", "..."],
366
- fonts: ["font/woff", "font/woff2", "font/ttf", "font/otf", "..."],
367
- code: ["application/json", "text/javascript", "text/x-python", "..."],
368
- spreadsheets: ["application/vnd.ms-excel", "text/csv", "..."],
369
- presentations: ["application/vnd.ms-powerpoint", "..."],
370
- cad: ["application/dwg", "application/dxf", "..."],
371
- models: ["model/obj", "model/gltf+json", "..."],
372
- pdfs: ["application/pdf"], // Backward compatibility
373
- all: [
374
- /* All supported MIME types */
375
- ],
376
- };
377
- ```
378
-
379
- ## What's New in v2.1.0
380
-
381
- ### 🚀 Major Improvements
382
-
383
- - **Universal JavaScript Compatibility**: Works seamlessly with CommonJS, ES Modules, and TypeScript
384
- - **Accept ANY File Type**: When no `fileTypes` or `customMimeTypes` are specified, ALL file types are accepted
385
- - **Enhanced File Categories**: Added support for fonts, CAD files, 3D models, and more
386
- - **Custom Error Handling**: Introduced `MultermateError` class for better error management
387
- - **Fixed Form Data Issues**: Resolved problems with form data processing
388
-
389
- ### 🔧 Technical Enhancements
390
-
391
- - Improved module exports for better compatibility
392
- - Enhanced MIME type detection and handling
393
- - Better error propagation and handling
394
- - Automatic directory creation
395
- - More robust file filtering logic
396
-
397
- ### 📁 New File Type Categories
398
-
399
- - **Fonts**: WOFF, WOFF2, TTF, OTF, EOT
400
- - **CAD Files**: DWG, DXF, DWF
401
- - **3D Models**: OBJ, GLTF, STL, PLY
402
- - **Enhanced Archives**: 7Z, XZ, LZ4, LZMA
403
- - **More Audio Formats**: OPUS, AMR, M4A
404
- - **Extended Video Support**: MOV, WMV, FLV, MKV
405
-
406
- ## Migration from v2.0.x
407
-
408
- The API remains backward compatible, but you can now take advantage of new features:
409
-
410
- ```javascript
411
- // Old way (still works)
412
- const { uploadSingle } = require("multermate");
413
-
414
- // New way with error handling
415
- const { uploadSingle, MultermateError } = require("multermate");
416
-
417
- // Accept any file type (new in v2.1.0)
418
- app.post("/upload-any", uploadSingle(), (req, res) => {
419
- // No fileTypes specified = accepts ALL file types
420
- res.json({ file: req.file });
421
- });
422
- ```
423
-
424
- ## TypeScript Support
425
-
426
- MulterMate includes complete TypeScript definitions:
427
-
428
- ```typescript
429
- import {
430
- uploadSingle,
431
- uploadMultiple,
432
- deleteFile,
433
- MultermateError,
434
- UploadSingleOptions,
435
- UploadMultipleOptions,
436
- FieldConfig,
437
- MIME_TYPES,
438
- ALLOWED_FILE_TYPES,
439
- } from "multermate";
440
-
441
- // Type-safe configuration
442
- const uploadOptions: UploadSingleOptions = {
443
- destination: "uploads/safe",
444
- fileTypes: ["images", "documents"],
445
- fileSizeLimit: 10 * 1024 * 1024,
446
- };
447
-
448
- // Error handling with types
449
- try {
450
- await deleteFile(filePath);
451
- } catch (error) {
452
- if (error instanceof MultermateError) {
453
- console.log(`Error ${error.code}: ${error.message}`);
454
- }
455
- }
456
- ```
457
-
458
- ## Best Practices
459
-
460
- 1. **Always implement error handling** with MultermateError
461
- 2. **Set appropriate file size limits** for your use case
462
- 3. **Use specific file type restrictions** when security is important
463
- 4. **Leverage "accept any file type"** for general upload scenarios
464
- 5. **Implement proper file cleanup** mechanisms
465
- 6. **Create upload directories** beforehand (MulterMate does this automatically)
466
- 7. **Use TypeScript types** for better development experience
467
- 8. **Test with different JavaScript environments** (CommonJS, ESM, TypeScript)
468
-
469
- ## Testing
470
-
471
- ```bash
472
- # Install dependencies
473
- npm install
474
-
475
- # Build the package
476
- npm run build
477
-
478
- # Run basic test
479
- node test-improved.js
480
- ```
481
-
482
- ## License
483
-
484
- MIT
485
-
486
- ## Contributing
487
-
488
- Contributions are welcome! Please feel free to submit issues and pull requests.
489
-
490
- ## Author
491
-
492
- Wasim Zaman
493
-
494
- ## Support
495
-
496
- For support, please open an issue in the GitHub repository: https://github.com/Wasim-Zaman/multermate
1
+ # Multer Mate
2
+
3
+ A robust and flexible file upload utility built on top of Multer, providing advanced file handling capabilities for Node.js applications. Now with full TypeScript support, universal JavaScript compatibility, and comprehensive error handling!
4
+
5
+ ## Features
6
+
7
+ - 📁 Flexible file storage configuration
8
+ - 🔒 Built-in file type validation
9
+ - 📦 Single and multiple file uploads
10
+ - 🎯 Field-specific file type restrictions
11
+ - 🗑️ File deletion utility
12
+ - ⚡ Configurable file size limits
13
+ - 🎨 Custom MIME type support
14
+ - 🔄 Unique file naming with UUID
15
+ - 🛡️ Path sanitization
16
+ - 📝 Comprehensive error handling with MultermateError
17
+ - 🔌 **Universal JavaScript compatibility** (CommonJS, ES Modules, TypeScript)
18
+ - 📘 Full TypeScript definitions and type safety
19
+ - 🌐 **Accept ANY file type** when no restrictions are specified
20
+ - 🎪 **Enhanced file type categories** (fonts, archives, CAD files, 3D models, etc.)
21
+ - 🚨 **Custom error classes** for better error handling
22
+ - 🔧 **Fixed form data processing** issues
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install multermate
28
+ ```
29
+
30
+ ## Universal JavaScript Compatibility
31
+
32
+ MulterMate works seamlessly across all JavaScript environments:
33
+
34
+ ### CommonJS
35
+
36
+ ```javascript
37
+ const {
38
+ uploadSingle,
39
+ uploadMultiple,
40
+ deleteFile,
41
+ MultermateError,
42
+ } = require("multermate");
43
+ ```
44
+
45
+ ### ES Modules
46
+
47
+ ```javascript
48
+ import {
49
+ uploadSingle,
50
+ uploadMultiple,
51
+ deleteFile,
52
+ MultermateError,
53
+ } from "multermate";
54
+ ```
55
+
56
+ ### TypeScript
57
+
58
+ ```typescript
59
+ import {
60
+ uploadSingle,
61
+ uploadMultiple,
62
+ deleteFile,
63
+ MultermateError,
64
+ UploadSingleOptions,
65
+ UploadMultipleOptions,
66
+ } from "multermate";
67
+
68
+ // With type definitions
69
+ const options: UploadSingleOptions = {
70
+ destination: "uploads/images",
71
+ fileTypes: ["images"],
72
+ fileSizeLimit: 5 * 1024 * 1024,
73
+ };
74
+ ```
75
+
76
+ ## Upload Configurations
77
+
78
+ ### Accept ANY File Type
79
+
80
+ By default, when no `fileTypes` or `customMimeTypes` are specified, MulterMate accepts **ALL file types**:
81
+
82
+ ```javascript
83
+ // Accept any file type - no restrictions!
84
+ app.post("/upload", uploadSingle(), (req, res) => {
85
+ res.json({ file: req.file });
86
+ });
87
+
88
+ // Also works with destination
89
+ app.post(
90
+ "/upload-any",
91
+ uploadSingle({
92
+ destination: "uploads/any-files",
93
+ filename: "uploaded-file",
94
+ // No fileTypes specified = accept all file types
95
+ }),
96
+ (req, res) => {
97
+ res.json({ file: req.file });
98
+ }
99
+ );
100
+ ```
101
+
102
+ ### Single File Upload
103
+
104
+ ```javascript
105
+ // Basic single file upload
106
+ app.post("/upload", uploadSingle(), (req, res) => {
107
+ if (req.fileValidationError) {
108
+ return res.status(400).json({ error: req.fileValidationError });
109
+ }
110
+ res.json({ file: req.file });
111
+ });
112
+
113
+ // Advanced single file upload with specific file types
114
+ app.post(
115
+ "/upload/advanced",
116
+ uploadSingle({
117
+ destination: "uploads/images",
118
+ // Files are physically saved here, but req.file.path stays clean for DB
119
+ absoluteDestination: "C:/data/my-app/uploads/images",
120
+ filename: "profile",
121
+ fileTypes: ["images"],
122
+ fileSizeLimit: 5 * 1024 * 1024, // 5MB
123
+ preservePath: false,
124
+ }),
125
+ (req, res) => {
126
+ res.json({ file: req.file });
127
+ }
128
+ );
129
+ ```
130
+
131
+ ### Multiple Files Upload
132
+
133
+ ```javascript
134
+ // Multiple fields with different configurations
135
+ app.post(
136
+ "/upload/multiple",
137
+ uploadMultiple({
138
+ fields: [
139
+ {
140
+ name: "avatar",
141
+ maxCount: 1,
142
+ fileTypes: ["images"],
143
+ },
144
+ {
145
+ name: "documents",
146
+ maxCount: 5,
147
+ fileTypes: ["documents", "text"],
148
+ },
149
+ {
150
+ name: "any-files", // No fileTypes = accept any file type
151
+ maxCount: 3,
152
+ },
153
+ ],
154
+ destination: "uploads/mixed",
155
+ absoluteDestination: "C:/data/my-app/uploads/mixed",
156
+ fileSizeLimit: 10 * 1024 * 1024, // 10MB per file
157
+ }),
158
+ (req, res) => {
159
+ res.json({ files: req.files });
160
+ }
161
+ );
162
+ ```
163
+
164
+ ### Enhanced File Type Categories
165
+
166
+ MulterMate now supports comprehensive file type categories:
167
+
168
+ ```javascript
169
+ app.post(
170
+ "/upload-comprehensive",
171
+ uploadSingle({
172
+ destination: "uploads/comprehensive",
173
+ fileTypes: [
174
+ "images", // JPEG, PNG, GIF, WebP, SVG, etc.
175
+ "videos", // MP4, AVI, MOV, WebM, etc.
176
+ "audio", // MP3, WAV, FLAC, AAC, etc.
177
+ "documents", // PDF, DOC, DOCX, XLS, XLSX, PPT, etc.
178
+ "text", // TXT, CSV, HTML, CSS, JS, MD, etc.
179
+ "archives", // ZIP, RAR, 7Z, TAR, GZIP, etc.
180
+ "fonts", // WOFF, WOFF2, TTF, OTF, etc.
181
+ "code", // JSON, XML, JS, TS, Python, etc.
182
+ "spreadsheets", // Excel, CSV files
183
+ "presentations", // PowerPoint, etc.
184
+ "cad", // CAD files
185
+ "models", // 3D model files
186
+ ],
187
+ }),
188
+ (req, res) => {
189
+ res.json({ file: req.file });
190
+ }
191
+ );
192
+ ```
193
+
194
+ ### Custom MIME Types
195
+
196
+ ```javascript
197
+ app.post(
198
+ "/upload/custom",
199
+ uploadSingle({
200
+ destination: "uploads/custom",
201
+ customMimeTypes: [
202
+ "application/vnd.ms-excel",
203
+ "application/json",
204
+ "text/csv",
205
+ "application/x-custom-type",
206
+ ],
207
+ fileSizeLimit: 1024 * 1024, // 1MB
208
+ }),
209
+ (req, res) => {
210
+ res.json({ file: req.file });
211
+ }
212
+ );
213
+ ```
214
+
215
+ ## Enhanced Error Handling
216
+
217
+ MulterMate now includes a custom `MultermateError` class for better error handling:
218
+
219
+ ```javascript
220
+ app.post("/upload", uploadSingle(), (req, res) => {
221
+ // Handle validation errors
222
+ if (req.fileValidationError) {
223
+ return res.status(400).json({
224
+ error: req.fileValidationError,
225
+ });
226
+ }
227
+
228
+ // Handle missing files
229
+ if (!req.file) {
230
+ return res.status(400).json({
231
+ error: "No file uploaded",
232
+ });
233
+ }
234
+
235
+ // Success response
236
+ res.json({
237
+ success: true,
238
+ file: {
239
+ filename: req.file.filename,
240
+ path: req.file.path,
241
+ size: req.file.size,
242
+ mimetype: req.file.mimetype,
243
+ },
244
+ });
245
+ });
246
+
247
+ // Global error handler for MultermateError
248
+ app.use((err, req, res, next) => {
249
+ if (err instanceof MultermateError) {
250
+ return res.status(400).json({
251
+ success: false,
252
+ error: err.message,
253
+ code: err.code,
254
+ field: err.field,
255
+ });
256
+ }
257
+
258
+ // Handle other errors
259
+ res.status(500).json({
260
+ success: false,
261
+ error: err.message,
262
+ });
263
+ });
264
+ ```
265
+
266
+ ### File Deletion with Error Handling
267
+
268
+ ```javascript
269
+ const { deleteFile, MultermateError } = require("multermate");
270
+
271
+ app.delete("/files/:filename", async (req, res) => {
272
+ try {
273
+ await deleteFile(`uploads/${req.params.filename}`);
274
+ res.json({
275
+ success: true,
276
+ message: "File deleted successfully",
277
+ });
278
+ } catch (error) {
279
+ if (error instanceof MultermateError) {
280
+ return res.status(400).json({
281
+ success: false,
282
+ error: error.message,
283
+ code: error.code,
284
+ });
285
+ }
286
+
287
+ res.status(500).json({
288
+ success: false,
289
+ message: "Failed to delete file",
290
+ });
291
+ }
292
+ });
293
+ ```
294
+
295
+ ## API Reference
296
+
297
+ ### uploadSingle(options)
298
+
299
+ Configures single file upload with the following options:
300
+
301
+ | Option | Type | Default | Description |
302
+ | ------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------ |
303
+ | destination | string | 'uploads' | Upload directory path |
304
+ | filename | string | 'file' | Form field name |
305
+ | fileTypes | string[] | [] | Allowed file type categories (empty = all) |
306
+ | customMimeTypes | string[] | [] | Custom MIME types |
307
+ | fileSizeLimit | number | 50MB | Max file size in bytes |
308
+ | preservePath | boolean | false | Preserve original path |
309
+
310
+ `absoluteDestination` (optional): Physical absolute directory for file storage. When provided, MulterMate keeps `req.file.path` relative so it is safer to store in DB.
311
+
312
+ ### uploadMultiple(options)
313
+
314
+ Configures multiple file uploads with the following options:
315
+
316
+ | Option | Type | Default | Description |
317
+ | ------------------- | -------- | --------- | ----------------------------------------------------------------------------------------- |
318
+ | fields | Field[] | [] | Field configurations |
319
+ | destination | string | 'uploads' | Upload directory |
320
+ | customMimeTypes | string[] | [] | Custom MIME types |
321
+ | fileSizeLimit | number | 50MB | Max file size |
322
+ | preservePath | boolean | false | Preserve paths |
323
+
324
+ `absoluteDestination` (optional): Physical absolute directory for file storage. When provided, MulterMate keeps file paths in `req.files` relative for DB storage.
325
+
326
+ ### Absolute Storage with Clean DB Path
327
+
328
+ Use `absoluteDestination` when files must be stored outside your app folder while keeping DB paths clean:
329
+
330
+ ```javascript
331
+ app.post(
332
+ "/upload/absolute",
333
+ uploadSingle({
334
+ destination: "uploads/images", // This is what goes to req.file.path
335
+ absoluteDestination: "D:/cdn-storage/project/images", // Physical storage directory
336
+ fileTypes: ["images"],
337
+ }),
338
+ (req, res) => {
339
+ // Example:
340
+ // req.file.path => "uploads/images/<generated-file-name>.jpg"
341
+ // Physical file => "D:/cdn-storage/project/images/<generated-file-name>.jpg"
342
+ res.json({ file: req.file });
343
+ }
344
+ );
345
+ ```
346
+
347
+ #### Field Configuration
348
+
349
+ | Option | Type | Default | Description |
350
+ | ------------- | -------- | ------- | ---------------------------------------- |
351
+ | name | string | - | Field name (required) |
352
+ | maxCount | number | 10 | Max files per field |
353
+ | fileTypes | string[] | [] | Allowed types (empty = accept all types) |
354
+ | fileSizeLimit | number | 50MB | Max file size |
355
+
356
+ ### deleteFile(filePath)
357
+
358
+ Deletes a file from the filesystem:
359
+
360
+ | Parameter | Type | Description |
361
+ | --------- | ---------------- | ---------------- |
362
+ | filePath | string | Path to file |
363
+ | Returns | Promise<boolean> | Deletion success |
364
+
365
+ ### MultermateError Class
366
+
367
+ Custom error class for better error handling:
368
+
369
+ ```typescript
370
+ class MultermateError extends Error {
371
+ code?: string; // Error code (e.g., 'FILE_SIZE_LIMIT_EXCEEDED')
372
+ field?: string; // Field name that caused the error
373
+ storageErrors?: string[]; // Additional storage errors
374
+ }
375
+ ```
376
+
377
+ ### Supported File Type Categories
378
+
379
+ ```javascript
380
+ const SUPPORTED_CATEGORIES = {
381
+ images: [
382
+ "image/jpeg",
383
+ "image/png",
384
+ "image/gif",
385
+ "image/webp",
386
+ "image/svg+xml",
387
+ "...",
388
+ ],
389
+ videos: ["video/mp4", "video/avi", "video/mov", "video/webm", "..."],
390
+ audio: ["audio/mp3", "audio/wav", "audio/flac", "audio/aac", "..."],
391
+ documents: ["application/pdf", "application/msword", "..."],
392
+ text: ["text/plain", "text/csv", "text/html", "text/markdown", "..."],
393
+ archives: ["application/zip", "application/x-rar-compressed", "..."],
394
+ fonts: ["font/woff", "font/woff2", "font/ttf", "font/otf", "..."],
395
+ code: ["application/json", "text/javascript", "text/x-python", "..."],
396
+ spreadsheets: ["application/vnd.ms-excel", "text/csv", "..."],
397
+ presentations: ["application/vnd.ms-powerpoint", "..."],
398
+ cad: ["application/dwg", "application/dxf", "..."],
399
+ models: ["model/obj", "model/gltf+json", "..."],
400
+ pdfs: ["application/pdf"], // Backward compatibility
401
+ all: [
402
+ /* All supported MIME types */
403
+ ],
404
+ };
405
+ ```
406
+
407
+ ## What's New in v2.1.0
408
+
409
+ ### 🚀 Major Improvements
410
+
411
+ - **Universal JavaScript Compatibility**: Works seamlessly with CommonJS, ES Modules, and TypeScript
412
+ - **Accept ANY File Type**: When no `fileTypes` or `customMimeTypes` are specified, ALL file types are accepted
413
+ - **Enhanced File Categories**: Added support for fonts, CAD files, 3D models, and more
414
+ - **Custom Error Handling**: Introduced `MultermateError` class for better error management
415
+ - **Fixed Form Data Issues**: Resolved problems with form data processing
416
+
417
+ ### 🔧 Technical Enhancements
418
+
419
+ - Improved module exports for better compatibility
420
+ - Enhanced MIME type detection and handling
421
+ - Better error propagation and handling
422
+ - Automatic directory creation
423
+ - More robust file filtering logic
424
+
425
+ ### 📁 New File Type Categories
426
+
427
+ - **Fonts**: WOFF, WOFF2, TTF, OTF, EOT
428
+ - **CAD Files**: DWG, DXF, DWF
429
+ - **3D Models**: OBJ, GLTF, STL, PLY
430
+ - **Enhanced Archives**: 7Z, XZ, LZ4, LZMA
431
+ - **More Audio Formats**: OPUS, AMR, M4A
432
+ - **Extended Video Support**: MOV, WMV, FLV, MKV
433
+
434
+ ## Migration from v2.0.x
435
+
436
+ The API remains backward compatible, but you can now take advantage of new features:
437
+
438
+ ```javascript
439
+ // Old way (still works)
440
+ const { uploadSingle } = require("multermate");
441
+
442
+ // New way with error handling
443
+ const { uploadSingle, MultermateError } = require("multermate");
444
+
445
+ // Accept any file type (new in v2.1.0)
446
+ app.post("/upload-any", uploadSingle(), (req, res) => {
447
+ // No fileTypes specified = accepts ALL file types
448
+ res.json({ file: req.file });
449
+ });
450
+ ```
451
+
452
+ ## TypeScript Support
453
+
454
+ MulterMate includes complete TypeScript definitions:
455
+
456
+ ```typescript
457
+ import {
458
+ uploadSingle,
459
+ uploadMultiple,
460
+ deleteFile,
461
+ MultermateError,
462
+ UploadSingleOptions,
463
+ UploadMultipleOptions,
464
+ FieldConfig,
465
+ MIME_TYPES,
466
+ ALLOWED_FILE_TYPES,
467
+ } from "multermate";
468
+
469
+ // Type-safe configuration
470
+ const uploadOptions: UploadSingleOptions = {
471
+ destination: "uploads/safe",
472
+ fileTypes: ["images", "documents"],
473
+ fileSizeLimit: 10 * 1024 * 1024,
474
+ };
475
+
476
+ // Error handling with types
477
+ try {
478
+ await deleteFile(filePath);
479
+ } catch (error) {
480
+ if (error instanceof MultermateError) {
481
+ console.log(`Error ${error.code}: ${error.message}`);
482
+ }
483
+ }
484
+ ```
485
+
486
+ ## Best Practices
487
+
488
+ 1. **Always implement error handling** with MultermateError
489
+ 2. **Set appropriate file size limits** for your use case
490
+ 3. **Use specific file type restrictions** when security is important
491
+ 4. **Leverage "accept any file type"** for general upload scenarios
492
+ 5. **Implement proper file cleanup** mechanisms
493
+ 6. **Create upload directories** beforehand (MulterMate does this automatically)
494
+ 7. **Use TypeScript types** for better development experience
495
+ 8. **Test with different JavaScript environments** (CommonJS, ESM, TypeScript)
496
+
497
+ ## Testing
498
+
499
+ ```bash
500
+ # Install dependencies
501
+ npm install
502
+
503
+ # Build the package
504
+ npm run build
505
+
506
+ # Run basic test
507
+ node test-improved.js
508
+ ```
509
+
510
+ ## License
511
+
512
+ MIT
513
+
514
+ ## Contributing
515
+
516
+ Contributions are welcome! Please feel free to submit issues and pull requests.
517
+
518
+ ## Author
519
+
520
+ Wasim Zaman
521
+
522
+ ## Support
523
+
524
+ For support, please open an issue in the GitHub repository: <https://github.com/Wasim-Zaman/multermate>