multermate 1.0.2 → 1.0.3
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/LICENSE +21 -21
- package/index.js +217 -197
- package/package.json +1 -1
- package/readme.md +255 -0
- package/README.md +0 -159
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Wasim Zaman
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Wasim Zaman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/index.js
CHANGED
|
@@ -1,197 +1,217 @@
|
|
|
1
|
-
const path = require("path");
|
|
2
|
-
const multer = require("multer");
|
|
3
|
-
const { v4: uuidv4 } = require("uuid");
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"image/
|
|
13
|
-
"image/
|
|
14
|
-
"image/
|
|
15
|
-
"
|
|
16
|
-
"video/
|
|
17
|
-
"video/
|
|
18
|
-
"video/
|
|
19
|
-
"video/
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* @
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* @param {
|
|
74
|
-
* @param {string} [options.
|
|
75
|
-
* @param {
|
|
76
|
-
* @param {Array<string>} [options.
|
|
77
|
-
* @param {
|
|
78
|
-
* @param {
|
|
79
|
-
* @
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* @param {
|
|
127
|
-
* @param {
|
|
128
|
-
*
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
types.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Function to handle
|
|
177
|
-
*
|
|
178
|
-
* @param {object} options - Configuration options for
|
|
179
|
-
* @param {
|
|
180
|
-
* @param {string} [options.
|
|
181
|
-
* @param {Array<string>} [options.
|
|
182
|
-
* @param {
|
|
183
|
-
* @param {
|
|
184
|
-
* @
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const multer = require("multer");
|
|
3
|
+
const { v4: uuidv4 } = require("uuid");
|
|
4
|
+
const fs = require("fs/promises");
|
|
5
|
+
|
|
6
|
+
// Constants for allowed MIME types
|
|
7
|
+
const ALLOWED_MIME_TYPES = {
|
|
8
|
+
images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
|
|
9
|
+
videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
|
|
10
|
+
pdfs: ["application/pdf"],
|
|
11
|
+
all: [
|
|
12
|
+
"image/jpeg",
|
|
13
|
+
"image/jpg",
|
|
14
|
+
"image/png",
|
|
15
|
+
"image/gif",
|
|
16
|
+
"video/mp4",
|
|
17
|
+
"video/mpeg",
|
|
18
|
+
"video/ogg",
|
|
19
|
+
"video/webm",
|
|
20
|
+
"video/avi",
|
|
21
|
+
"application/pdf",
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Function to configure storage for Multer.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} destination - The destination folder where files will be stored. Default is "uploads".
|
|
29
|
+
* @returns {object} - Multer storage configuration object.
|
|
30
|
+
*/
|
|
31
|
+
const configureStorage = (destination) => {
|
|
32
|
+
return multer.diskStorage({
|
|
33
|
+
destination: (req, file, cb) => {
|
|
34
|
+
cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
|
|
35
|
+
},
|
|
36
|
+
filename: (req, file, cb) => {
|
|
37
|
+
const sanitizedFilename = file.originalname.replace(/\\/g, "/");
|
|
38
|
+
const extension = path.extname(sanitizedFilename);
|
|
39
|
+
const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
|
|
40
|
+
const uniqueName = uuidv4(); // Generate a unique name using uuid.
|
|
41
|
+
let fileName = `${uniqueName}-${fieldName}${extension}`;
|
|
42
|
+
|
|
43
|
+
// Replace backslashes with forward slashes in the final filename
|
|
44
|
+
fileName = fileName.replace(/\\/g, "/");
|
|
45
|
+
|
|
46
|
+
cb(null, fileName); // Set the final filename.
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Function to configure file filter for Multer.
|
|
53
|
+
*
|
|
54
|
+
* @param {Array} allowedMimeTypes - Array of allowed MIME types.
|
|
55
|
+
* @returns {function} - File filter function for Multer.
|
|
56
|
+
*/
|
|
57
|
+
const configureFileFilter = (allowedMimeTypes) => {
|
|
58
|
+
return (req, file, cb) => {
|
|
59
|
+
if (allowedMimeTypes.includes(file.mimetype)) {
|
|
60
|
+
cb(null, true); // Allow the file if its MIME type is allowed.
|
|
61
|
+
} else {
|
|
62
|
+
cb(
|
|
63
|
+
new Error("Invalid file type. Only specified file types are allowed."),
|
|
64
|
+
false
|
|
65
|
+
); // Reject the file if its MIME type is not allowed.
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Function to configure Multer with the provided options.
|
|
72
|
+
*
|
|
73
|
+
* @param {object} options - Configuration options for Multer.
|
|
74
|
+
* @param {string} [options.destination] - Destination folder for files. Default is "uploads".
|
|
75
|
+
* @param {string} [options.filename] - Custom filename template for saved files.
|
|
76
|
+
* @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
|
|
77
|
+
* @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
|
|
78
|
+
* @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
|
|
79
|
+
* @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
|
|
80
|
+
* @returns {object} - Multer instance configured with the provided options.
|
|
81
|
+
*/
|
|
82
|
+
const configureMulter = ({
|
|
83
|
+
destination,
|
|
84
|
+
filename,
|
|
85
|
+
fileTypes = [],
|
|
86
|
+
customMimeTypes = [],
|
|
87
|
+
fileSizeLimit,
|
|
88
|
+
preservePath = false,
|
|
89
|
+
}) => {
|
|
90
|
+
const storage = configureStorage(destination);
|
|
91
|
+
|
|
92
|
+
// Combine allowed MIME types based on fileTypes array
|
|
93
|
+
let allowedMimeTypes = [];
|
|
94
|
+
|
|
95
|
+
if (customMimeTypes.length > 0) {
|
|
96
|
+
// Use custom MIME types if provided
|
|
97
|
+
allowedMimeTypes = customMimeTypes;
|
|
98
|
+
} else {
|
|
99
|
+
// Use default MIME types for specified fileTypes
|
|
100
|
+
fileTypes.forEach((type) => {
|
|
101
|
+
if (ALLOWED_MIME_TYPES[type]) {
|
|
102
|
+
allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// If no specific file types are provided, use all allowed MIME types
|
|
107
|
+
if (allowedMimeTypes.length === 0) {
|
|
108
|
+
allowedMimeTypes = ALLOWED_MIME_TYPES.all;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const fileFilter = configureFileFilter(allowedMimeTypes);
|
|
113
|
+
|
|
114
|
+
return multer({
|
|
115
|
+
storage,
|
|
116
|
+
fileFilter,
|
|
117
|
+
limits: { fileSize: fileSizeLimit || 1024 * 1024 * 50 }, // Default 50MB file size limit
|
|
118
|
+
preservePath,
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Function to handle multiple fields in a single form submission.
|
|
124
|
+
*
|
|
125
|
+
* @param {Array} fields - Array of field configurations, each containing:
|
|
126
|
+
* @param {string} fields.name - The name of the form field.
|
|
127
|
+
* @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
|
|
128
|
+
* @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
|
|
129
|
+
* @returns {function} - Multer instance configured to handle multiple fields.
|
|
130
|
+
*/
|
|
131
|
+
const uploadFields = (fields) => {
|
|
132
|
+
const fieldConfigs = fields.map((field) => ({
|
|
133
|
+
name: field.name,
|
|
134
|
+
maxCount: field.maxCount || 10, // Default maxCount is 10 if not specified.
|
|
135
|
+
}));
|
|
136
|
+
|
|
137
|
+
let allowedFileTypes = [];
|
|
138
|
+
|
|
139
|
+
fields.forEach((field) => {
|
|
140
|
+
const types = field.fileTypes || [];
|
|
141
|
+
types.forEach((type) => {
|
|
142
|
+
if (ALLOWED_MIME_TYPES[type]) {
|
|
143
|
+
allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const multerInstance = configureMulter({
|
|
149
|
+
fileTypes: allowedFileTypes,
|
|
150
|
+
customMimeTypes: [],
|
|
151
|
+
fileSizeLimit: fields[0]?.fileSizeLimit, // Assuming all fields share the same limit.
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
return multerInstance.fields(fieldConfigs);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Utility function to delete a file from the filesystem
|
|
159
|
+
*
|
|
160
|
+
* @param {string} filePath - The path to the file that needs to be deleted
|
|
161
|
+
* @returns {Promise<boolean>} - Returns true if deletion was successful, false otherwise
|
|
162
|
+
*/
|
|
163
|
+
const deleteFile = async (filePath) => {
|
|
164
|
+
try {
|
|
165
|
+
await fs.unlink(filePath);
|
|
166
|
+
return true;
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error(`Error deleting file: ${error.message}`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Export functions to configure multer and available file types
|
|
174
|
+
module.exports = {
|
|
175
|
+
/**
|
|
176
|
+
* Function to handle a single file upload.
|
|
177
|
+
*
|
|
178
|
+
* @param {object} options - Configuration options for the single file upload.
|
|
179
|
+
* @param {string} [options.destination] - Destination folder for the uploaded file.
|
|
180
|
+
* @param {string} [options.filename] - Custom filename template for the uploaded file.
|
|
181
|
+
* @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images']).
|
|
182
|
+
* @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
|
|
183
|
+
* @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
|
|
184
|
+
* @param {boolean} [options.preservePath] - Preserve the full path of the uploaded file. Default is false.
|
|
185
|
+
* @returns {function} - Multer instance configured for single file upload.
|
|
186
|
+
*/
|
|
187
|
+
uploadSingle: (options = {}) => {
|
|
188
|
+
const multerInstance = configureMulter(options);
|
|
189
|
+
return multerInstance.single(options.filename || "file");
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Function to handle multiple file uploads across multiple fields.
|
|
194
|
+
*
|
|
195
|
+
* @param {object} options - Configuration options for multiple file uploads.
|
|
196
|
+
* @param {Array<object>} options.fields - Array of field configurations for multiple file uploads.
|
|
197
|
+
* @param {string} [options.destination] - Destination folder for the uploaded files.
|
|
198
|
+
* @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
|
|
199
|
+
* @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
|
|
200
|
+
* @param {boolean} [options.preservePath] - Preserve the full path of the uploaded files. Default is false.
|
|
201
|
+
* @returns {function} - Multer instance configured for multiple file uploads.
|
|
202
|
+
*/
|
|
203
|
+
uploadMultiple: (options = {}) => {
|
|
204
|
+
const multerInstance = configureMulter(options);
|
|
205
|
+
return multerInstance.fields(options.fields || []);
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Export the allowed file types for reference.
|
|
210
|
+
*
|
|
211
|
+
* @type {Array<string>}
|
|
212
|
+
*/
|
|
213
|
+
ALLOWED_FILE_TYPES: Object.keys(ALLOWED_MIME_TYPES),
|
|
214
|
+
|
|
215
|
+
// Add the delete file utility
|
|
216
|
+
deleteFile,
|
|
217
|
+
};
|
package/package.json
CHANGED
package/readme.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
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.
|
|
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
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install multermate
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Basic Usage
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
const { uploadSingle, uploadMultiple, deleteFile } = require("multermate");
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Upload Configurations
|
|
31
|
+
|
|
32
|
+
### Single File Upload
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
// Basic single file upload
|
|
36
|
+
app.post("/upload", uploadSingle(), (req, res) => {
|
|
37
|
+
res.json({ file: req.file });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Advanced single file upload
|
|
41
|
+
app.post(
|
|
42
|
+
"/upload/advanced",
|
|
43
|
+
uploadSingle({
|
|
44
|
+
destination: "uploads/images",
|
|
45
|
+
filename: "profile",
|
|
46
|
+
fileTypes: ["images"],
|
|
47
|
+
fileSizeLimit: 5 * 1024 * 1024, // 5MB
|
|
48
|
+
preservePath: false,
|
|
49
|
+
}),
|
|
50
|
+
(req, res) => {
|
|
51
|
+
res.json({ file: req.file });
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Multiple Files Upload
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// Multiple fields with different configurations
|
|
60
|
+
app.post(
|
|
61
|
+
"/upload/multiple",
|
|
62
|
+
uploadMultiple({
|
|
63
|
+
fields: [
|
|
64
|
+
{
|
|
65
|
+
name: "avatar",
|
|
66
|
+
maxCount: 1,
|
|
67
|
+
fileTypes: ["images"],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "documents",
|
|
71
|
+
maxCount: 5,
|
|
72
|
+
fileTypes: ["pdfs"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "media",
|
|
76
|
+
maxCount: 3,
|
|
77
|
+
fileTypes: ["images", "videos"],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
destination: "uploads/mixed",
|
|
81
|
+
fileSizeLimit: 10 * 1024 * 1024, // 10MB per file
|
|
82
|
+
}),
|
|
83
|
+
(req, res) => {
|
|
84
|
+
res.json({ files: req.files });
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Custom MIME Types
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
app.post(
|
|
93
|
+
"/upload/custom",
|
|
94
|
+
uploadSingle({
|
|
95
|
+
destination: "uploads/custom",
|
|
96
|
+
customMimeTypes: [
|
|
97
|
+
"application/vnd.ms-excel",
|
|
98
|
+
"application/json",
|
|
99
|
+
"text/csv",
|
|
100
|
+
],
|
|
101
|
+
fileSizeLimit: 1024 * 1024, // 1MB
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### File Deletion
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// Simple file deletion
|
|
110
|
+
app.delete("/files/:filename", async (req, res) => {
|
|
111
|
+
const isDeleted = await deleteFile(`uploads/${req.params.filename}`);
|
|
112
|
+
res.json({ success: isDeleted });
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Advanced file deletion with error handling
|
|
116
|
+
app.delete("/files/:type/:filename", async (req, res) => {
|
|
117
|
+
try {
|
|
118
|
+
const filePath = path.join("uploads", req.params.type, req.params.filename);
|
|
119
|
+
const isDeleted = await deleteFile(filePath);
|
|
120
|
+
|
|
121
|
+
if (isDeleted) {
|
|
122
|
+
res.json({
|
|
123
|
+
success: true,
|
|
124
|
+
message: "File deleted successfully",
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
res.status(404).json({
|
|
128
|
+
success: false,
|
|
129
|
+
message: "File not found or unable to delete",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
} catch (error) {
|
|
133
|
+
res.status(500).json({
|
|
134
|
+
success: false,
|
|
135
|
+
message: error.message,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## API Reference
|
|
142
|
+
|
|
143
|
+
### uploadSingle(options)
|
|
144
|
+
|
|
145
|
+
Configures single file upload with the following options:
|
|
146
|
+
|
|
147
|
+
| Option | Type | Default | Description |
|
|
148
|
+
| --------------- | -------- | --------- | ---------------------- |
|
|
149
|
+
| destination | string | 'uploads' | Upload directory path |
|
|
150
|
+
| filename | string | 'file' | Form field name |
|
|
151
|
+
| fileTypes | string[] | ['all'] | Allowed file types |
|
|
152
|
+
| customMimeTypes | string[] | [] | Custom MIME types |
|
|
153
|
+
| fileSizeLimit | number | 50MB | Max file size in bytes |
|
|
154
|
+
| preservePath | boolean | false | Preserve original path |
|
|
155
|
+
|
|
156
|
+
### uploadMultiple(options)
|
|
157
|
+
|
|
158
|
+
Configures multiple file uploads with the following options:
|
|
159
|
+
|
|
160
|
+
| Option | Type | Default | Description |
|
|
161
|
+
| --------------- | -------- | --------- | -------------------- |
|
|
162
|
+
| fields | Field[] | [] | Field configurations |
|
|
163
|
+
| destination | string | 'uploads' | Upload directory |
|
|
164
|
+
| customMimeTypes | string[] | [] | Custom MIME types |
|
|
165
|
+
| fileSizeLimit | number | 50MB | Max file size |
|
|
166
|
+
| preservePath | boolean | false | Preserve paths |
|
|
167
|
+
|
|
168
|
+
#### Field Configuration
|
|
169
|
+
|
|
170
|
+
| Option | Type | Default | Description |
|
|
171
|
+
| --------- | -------- | ------- | --------------------- |
|
|
172
|
+
| name | string | - | Field name (required) |
|
|
173
|
+
| maxCount | number | 10 | Max files per field |
|
|
174
|
+
| fileTypes | string[] | ['all'] | Allowed types |
|
|
175
|
+
|
|
176
|
+
### deleteFile(filePath)
|
|
177
|
+
|
|
178
|
+
Deletes a file from the filesystem:
|
|
179
|
+
|
|
180
|
+
| Parameter | Type | Description |
|
|
181
|
+
| --------- | ---------------- | ---------------- |
|
|
182
|
+
| filePath | string | Path to file |
|
|
183
|
+
| Returns | Promise<boolean> | Deletion success |
|
|
184
|
+
|
|
185
|
+
### Supported File Types
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
const ALLOWED_FILE_TYPES = {
|
|
189
|
+
images: ["jpeg", "jpg", "png", "gif"],
|
|
190
|
+
videos: ["mp4", "mpeg", "ogg", "webm", "avi"],
|
|
191
|
+
pdfs: ["pdf"],
|
|
192
|
+
};
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Error Handling
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
app.post("/upload", uploadSingle(), (req, res) => {
|
|
199
|
+
try {
|
|
200
|
+
// File size validation
|
|
201
|
+
if (req.fileValidationError) {
|
|
202
|
+
return res.status(400).json({
|
|
203
|
+
error: req.fileValidationError,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// File existence check
|
|
208
|
+
if (!req.file) {
|
|
209
|
+
return res.status(400).json({
|
|
210
|
+
error: "No file uploaded",
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Success response
|
|
215
|
+
res.json({
|
|
216
|
+
success: true,
|
|
217
|
+
file: {
|
|
218
|
+
filename: req.file.filename,
|
|
219
|
+
path: req.file.path,
|
|
220
|
+
size: req.file.size,
|
|
221
|
+
mimetype: req.file.mimetype,
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
} catch (error) {
|
|
225
|
+
res.status(500).json({
|
|
226
|
+
error: error.message,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Best Practices
|
|
233
|
+
|
|
234
|
+
1. Always implement proper error handling
|
|
235
|
+
2. Set appropriate file size limits
|
|
236
|
+
3. Validate file types on the server
|
|
237
|
+
4. Use custom storage destinations for different file types
|
|
238
|
+
5. Implement file cleanup mechanisms
|
|
239
|
+
6. Consider implementing file type verification beyond MIME types
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
MIT
|
|
244
|
+
|
|
245
|
+
## Contributing
|
|
246
|
+
|
|
247
|
+
Contributions are welcome! Please feel free to submit issues and pull requests.
|
|
248
|
+
|
|
249
|
+
## Author
|
|
250
|
+
|
|
251
|
+
Your Name
|
|
252
|
+
|
|
253
|
+
## Support
|
|
254
|
+
|
|
255
|
+
For support, please open an issue in the GitHub repository.
|
package/README.md
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
# Multer Mate
|
|
2
|
-
|
|
3
|
-
`multermate` is a flexible and customizable npm package for configuring Multer, a Node.js middleware for handling `multipart/form-data` (file uploads). This package allows you to easily configure Multer for various use cases, including storing files in different directories and specifying allowed file types.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- Customizable storage destinations
|
|
8
|
-
- Unique file naming using `uuid`
|
|
9
|
-
- Support for various file types (images, videos, PDFs, etc.)
|
|
10
|
-
- Configurable file size limits
|
|
11
|
-
- Single and multiple file uploads
|
|
12
|
-
- Specify custom MIME types within broader categories
|
|
13
|
-
- Default behavior for allowing all MIME types if none specified
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
Install the package using npm:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install multermate
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
### Import the package
|
|
26
|
-
|
|
27
|
-
```javascript
|
|
28
|
-
const {
|
|
29
|
-
uploadSingle,
|
|
30
|
-
uploadMultiple,
|
|
31
|
-
ALLOWED_FILE_TYPES,
|
|
32
|
-
} = require("multermate");
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Single File Upload
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
const express = require("express");
|
|
39
|
-
const { uploadSingle } = require("multermate");
|
|
40
|
-
|
|
41
|
-
const app = express();
|
|
42
|
-
|
|
43
|
-
app.post(
|
|
44
|
-
"/upload/single",
|
|
45
|
-
uploadSingle({
|
|
46
|
-
destination: "uploads/images",
|
|
47
|
-
filename: "image",
|
|
48
|
-
fileTypes: ["images"],
|
|
49
|
-
fileSizeLimit: 1024 * 1024 * 10, // 10MB limit
|
|
50
|
-
}),
|
|
51
|
-
(req, res) => {
|
|
52
|
-
res.send("Single file uploaded!");
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
app.listen(3000, () => {
|
|
57
|
-
console.log("Server started on http://localhost:3000");
|
|
58
|
-
});
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Multiple Files Upload (Mixed File Types)
|
|
62
|
-
|
|
63
|
-
```javascript
|
|
64
|
-
const express = require("express");
|
|
65
|
-
const { uploadMultiple } = require("multermate");
|
|
66
|
-
|
|
67
|
-
const app = express();
|
|
68
|
-
|
|
69
|
-
app.post(
|
|
70
|
-
"/upload/multiple",
|
|
71
|
-
uploadMultiple({
|
|
72
|
-
fields: [
|
|
73
|
-
{ name: "media", maxCount: 1, fileTypes: ["images", "videos"] },
|
|
74
|
-
{ name: "pdf", maxCount: 1, fileTypes: ["pdfs"] },
|
|
75
|
-
],
|
|
76
|
-
}),
|
|
77
|
-
(req, res) => {
|
|
78
|
-
res.send("Multiple files uploaded!");
|
|
79
|
-
}
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
app.listen(3000, () => {
|
|
83
|
-
console.log("Server started on http://localhost:3000");
|
|
84
|
-
});
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Custom MIME Types (e.g., Only PNGs and PDFs)
|
|
88
|
-
|
|
89
|
-
```javascript
|
|
90
|
-
const express = require("express");
|
|
91
|
-
const { uploadSingle, uploadMultiple } = require("multermate");
|
|
92
|
-
|
|
93
|
-
const app = express();
|
|
94
|
-
|
|
95
|
-
// Single PNG or PDF file upload
|
|
96
|
-
app.post(
|
|
97
|
-
"/upload-custom",
|
|
98
|
-
uploadSingle({
|
|
99
|
-
destination: "uploads/custom",
|
|
100
|
-
customMimeTypes: ["image/png", "application/pdf"],
|
|
101
|
-
fileSizeLimit: 1024 * 1024 * 15, // 15MB limit
|
|
102
|
-
}),
|
|
103
|
-
(req, res) => {
|
|
104
|
-
res.send("PNG or PDF file uploaded!");
|
|
105
|
-
}
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
// Multiple PNGs or PDFs upload
|
|
109
|
-
app.post(
|
|
110
|
-
"/upload-custom-multiple",
|
|
111
|
-
uploadMultiple({
|
|
112
|
-
fields: [
|
|
113
|
-
{ name: "images", maxCount: 5, customMimeTypes: ["image/png"] },
|
|
114
|
-
{ name: "pdfs", maxCount: 2, customMimeTypes: ["application/pdf"] },
|
|
115
|
-
],
|
|
116
|
-
}),
|
|
117
|
-
(req, res) => {
|
|
118
|
-
res.send("PNG images and PDF files uploaded!");
|
|
119
|
-
}
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
app.listen(3000, () => {
|
|
123
|
-
console.log("Server started on http://localhost:3000");
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Default Behavior (Allow All MIME Types)
|
|
128
|
-
|
|
129
|
-
```javascript
|
|
130
|
-
const express = require("express");
|
|
131
|
-
const { uploadSingle, uploadMultiple } = require("multermate");
|
|
132
|
-
|
|
133
|
-
const app = express();
|
|
134
|
-
|
|
135
|
-
// Single file upload (default behavior allows all MIME types)
|
|
136
|
-
app.post("/upload", uploadSingle(), (req, res) => {
|
|
137
|
-
res.send("File uploaded!");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Multiple files upload (default behavior allows all MIME types)
|
|
141
|
-
app.post("/upload-multiple", uploadMultiple(), (req, res) => {
|
|
142
|
-
res.send("Files uploaded!");
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
app.listen(3000, () => {
|
|
146
|
-
console.log("Server started on http://localhost:3000");
|
|
147
|
-
});
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Exported Constants
|
|
151
|
-
|
|
152
|
-
```javascript
|
|
153
|
-
const { ALLOWED_FILE_TYPES } = require("multermate");
|
|
154
|
-
console.log(ALLOWED_FILE_TYPES); // ['images', 'videos', 'pdfs', 'all']
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Conclusion
|
|
158
|
-
|
|
159
|
-
multermate provides a flexible and easy-to-use configuration for handling file uploads in Node.js applications. Whether you need to handle single or multiple file uploads, restrict uploads to certain file types, or specify custom MIME types, this package has you covered.
|