multermate 1.0.1 → 1.1.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/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.
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ targets: {
7
+ node: "current",
8
+ },
9
+ },
10
+ ],
11
+ ],
12
+ };
@@ -1,193 +1,197 @@
1
- const path = require("path");
2
- const multer = require("multer");
3
- const { v4: uuidv4 } = require("uuid");
4
-
5
- // Constants for allowed MIME types
6
- const ALLOWED_MIME_TYPES = {
7
- images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
8
- videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
9
- pdfs: ["application/pdf"],
10
- all: [
11
- "image/jpeg",
12
- "image/jpg",
13
- "image/png",
14
- "image/gif",
15
- "video/mp4",
16
- "video/mpeg",
17
- "video/ogg",
18
- "video/webm",
19
- "video/avi",
20
- "application/pdf",
21
- ],
22
- };
23
-
24
- /**
25
- * Function to configure storage for Multer.
26
- *
27
- * @param {string} destination - The destination folder where files will be stored. Default is "uploads".
28
- * @returns {object} - Multer storage configuration object.
29
- */
30
- const configureStorage = (destination) => {
31
- return multer.diskStorage({
32
- destination: (req, file, cb) => {
33
- cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
34
- },
35
- filename: (req, file, cb) => {
36
- const sanitizedFilename = file.originalname.replace(/\\/g, "/");
37
- const extension = path.extname(sanitizedFilename);
38
- const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
39
- const uniqueName = uuidv4(); // Generate a unique name using uuid.
40
- const fileName = `${uniqueName}-${fieldName}${extension}`;
41
- cb(null, fileName); // Set the final filename.
42
- },
43
- });
44
- };
45
-
46
- /**
47
- * Function to configure file filter for Multer.
48
- *
49
- * @param {Array} allowedMimeTypes - Array of allowed MIME types.
50
- * @returns {function} - File filter function for Multer.
51
- */
52
- const configureFileFilter = (allowedMimeTypes) => {
53
- return (req, file, cb) => {
54
- if (allowedMimeTypes.includes(file.mimetype)) {
55
- cb(null, true); // Allow the file if its MIME type is allowed.
56
- } else {
57
- cb(
58
- new Error("Invalid file type. Only specified file types are allowed."),
59
- false
60
- ); // Reject the file if its MIME type is not allowed.
61
- }
62
- };
63
- };
64
-
65
- /**
66
- * Function to configure Multer with the provided options.
67
- *
68
- * @param {object} options - Configuration options for Multer.
69
- * @param {string} [options.destination] - Destination folder for files. Default is "uploads".
70
- * @param {string} [options.filename] - Custom filename template for saved files.
71
- * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
72
- * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
73
- * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
74
- * @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
75
- * @returns {object} - Multer instance configured with the provided options.
76
- */
77
- const configureMulter = ({
78
- destination,
79
- filename,
80
- fileTypes = [],
81
- customMimeTypes = [],
82
- fileSizeLimit,
83
- preservePath = false,
84
- }) => {
85
- const storage = configureStorage(destination);
86
-
87
- // Combine allowed MIME types based on fileTypes array
88
- let allowedMimeTypes = [];
89
-
90
- if (customMimeTypes.length > 0) {
91
- // Use custom MIME types if provided
92
- allowedMimeTypes = customMimeTypes;
93
- } else {
94
- // Use default MIME types for specified fileTypes
95
- fileTypes.forEach((type) => {
96
- if (ALLOWED_MIME_TYPES[type]) {
97
- allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
98
- }
99
- });
100
-
101
- // If no specific file types are provided, use all allowed MIME types
102
- if (allowedMimeTypes.length === 0) {
103
- allowedMimeTypes = ALLOWED_MIME_TYPES.all;
104
- }
105
- }
106
-
107
- const fileFilter = configureFileFilter(allowedMimeTypes);
108
-
109
- return multer({
110
- storage,
111
- fileFilter,
112
- limits: { fileSize: fileSizeLimit || 1024 * 1024 * 50 }, // Default 50MB file size limit
113
- preservePath,
114
- });
115
- };
116
-
117
- /**
118
- * Function to handle multiple fields in a single form submission.
119
- *
120
- * @param {Array} fields - Array of field configurations, each containing:
121
- * @param {string} fields.name - The name of the form field.
122
- * @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
123
- * @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
124
- * @returns {function} - Multer instance configured to handle multiple fields.
125
- */
126
- const uploadFields = (fields) => {
127
- const fieldConfigs = fields.map((field) => ({
128
- name: field.name,
129
- maxCount: field.maxCount || 10, // Default maxCount is 10 if not specified.
130
- }));
131
-
132
- let allowedFileTypes = [];
133
-
134
- fields.forEach((field) => {
135
- const types = field.fileTypes || [];
136
- types.forEach((type) => {
137
- if (ALLOWED_MIME_TYPES[type]) {
138
- allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
139
- }
140
- });
141
- });
142
-
143
- const multerInstance = configureMulter({
144
- fileTypes: allowedFileTypes,
145
- customMimeTypes: [],
146
- fileSizeLimit: fields[0]?.fileSizeLimit, // Assuming all fields share the same limit.
147
- });
148
-
149
- return multerInstance.fields(fieldConfigs);
150
- };
151
-
152
- // Export functions to configure multer and available file types
153
- module.exports = {
154
- /**
155
- * Function to handle a single file upload.
156
- *
157
- * @param {object} options - Configuration options for the single file upload.
158
- * @param {string} [options.destination] - Destination folder for the uploaded file.
159
- * @param {string} [options.filename] - Custom filename template for the uploaded file.
160
- * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images']).
161
- * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
162
- * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
163
- * @param {boolean} [options.preservePath] - Preserve the full path of the uploaded file. Default is false.
164
- * @returns {function} - Multer instance configured for single file upload.
165
- */
166
- uploadSingle: (options = {}) => {
167
- const multerInstance = configureMulter(options);
168
- return multerInstance.single(options.filename || "file");
169
- },
170
-
171
- /**
172
- * Function to handle multiple file uploads across multiple fields.
173
- *
174
- * @param {object} options - Configuration options for multiple file uploads.
175
- * @param {Array<object>} options.fields - Array of field configurations for multiple file uploads.
176
- * @param {string} [options.destination] - Destination folder for the uploaded files.
177
- * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
178
- * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
179
- * @param {boolean} [options.preservePath] - Preserve the full path of the uploaded files. Default is false.
180
- * @returns {function} - Multer instance configured for multiple file uploads.
181
- */
182
- uploadMultiple: (options = {}) => {
183
- const multerInstance = configureMulter(options);
184
- return multerInstance.fields(options.fields || []);
185
- },
186
-
187
- /**
188
- * Export the allowed file types for reference.
189
- *
190
- * @type {Array<string>}
191
- */
192
- ALLOWED_FILE_TYPES: Object.keys(ALLOWED_MIME_TYPES),
193
- };
1
+ const path = require("path");
2
+ const multer = require("multer");
3
+ const { v4: uuidv4 } = require("uuid");
4
+
5
+ // Constants for allowed MIME types
6
+ const ALLOWED_MIME_TYPES = {
7
+ images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
8
+ videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
9
+ pdfs: ["application/pdf"],
10
+ all: [
11
+ "image/jpeg",
12
+ "image/jpg",
13
+ "image/png",
14
+ "image/gif",
15
+ "video/mp4",
16
+ "video/mpeg",
17
+ "video/ogg",
18
+ "video/webm",
19
+ "video/avi",
20
+ "application/pdf",
21
+ ],
22
+ };
23
+
24
+ /**
25
+ * Function to configure storage for Multer.
26
+ *
27
+ * @param {string} destination - The destination folder where files will be stored. Default is "uploads".
28
+ * @returns {object} - Multer storage configuration object.
29
+ */
30
+ const configureStorage = (destination) => {
31
+ return multer.diskStorage({
32
+ destination: (req, file, cb) => {
33
+ cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
34
+ },
35
+ filename: (req, file, cb) => {
36
+ const sanitizedFilename = file.originalname.replace(/\\/g, "/");
37
+ const extension = path.extname(sanitizedFilename);
38
+ const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
39
+ const uniqueName = uuidv4(); // Generate a unique name using uuid.
40
+ let fileName = `${uniqueName}-${fieldName}${extension}`;
41
+
42
+ // Replace backslashes with forward slashes in the final filename
43
+ fileName = fileName.replace(/\\/g, "/");
44
+
45
+ cb(null, fileName); // Set the final filename.
46
+ },
47
+ });
48
+ };
49
+
50
+ /**
51
+ * Function to configure file filter for Multer.
52
+ *
53
+ * @param {Array} allowedMimeTypes - Array of allowed MIME types.
54
+ * @returns {function} - File filter function for Multer.
55
+ */
56
+ const configureFileFilter = (allowedMimeTypes) => {
57
+ return (req, file, cb) => {
58
+ if (allowedMimeTypes.includes(file.mimetype)) {
59
+ cb(null, true); // Allow the file if its MIME type is allowed.
60
+ } else {
61
+ cb(
62
+ new Error("Invalid file type. Only specified file types are allowed."),
63
+ false
64
+ ); // Reject the file if its MIME type is not allowed.
65
+ }
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Function to configure Multer with the provided options.
71
+ *
72
+ * @param {object} options - Configuration options for Multer.
73
+ * @param {string} [options.destination] - Destination folder for files. Default is "uploads".
74
+ * @param {string} [options.filename] - Custom filename template for saved files.
75
+ * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
76
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
77
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
78
+ * @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
79
+ * @returns {object} - Multer instance configured with the provided options.
80
+ */
81
+ const configureMulter = ({
82
+ destination,
83
+ filename,
84
+ fileTypes = [],
85
+ customMimeTypes = [],
86
+ fileSizeLimit,
87
+ preservePath = false,
88
+ }) => {
89
+ const storage = configureStorage(destination);
90
+
91
+ // Combine allowed MIME types based on fileTypes array
92
+ let allowedMimeTypes = [];
93
+
94
+ if (customMimeTypes.length > 0) {
95
+ // Use custom MIME types if provided
96
+ allowedMimeTypes = customMimeTypes;
97
+ } else {
98
+ // Use default MIME types for specified fileTypes
99
+ fileTypes.forEach((type) => {
100
+ if (ALLOWED_MIME_TYPES[type]) {
101
+ allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
102
+ }
103
+ });
104
+
105
+ // If no specific file types are provided, use all allowed MIME types
106
+ if (allowedMimeTypes.length === 0) {
107
+ allowedMimeTypes = ALLOWED_MIME_TYPES.all;
108
+ }
109
+ }
110
+
111
+ const fileFilter = configureFileFilter(allowedMimeTypes);
112
+
113
+ return multer({
114
+ storage,
115
+ fileFilter,
116
+ limits: { fileSize: fileSizeLimit || 1024 * 1024 * 50 }, // Default 50MB file size limit
117
+ preservePath,
118
+ });
119
+ };
120
+
121
+ /**
122
+ * Function to handle multiple fields in a single form submission.
123
+ *
124
+ * @param {Array} fields - Array of field configurations, each containing:
125
+ * @param {string} fields.name - The name of the form field.
126
+ * @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
127
+ * @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
128
+ * @returns {function} - Multer instance configured to handle multiple fields.
129
+ */
130
+ const uploadFields = (fields) => {
131
+ const fieldConfigs = fields.map((field) => ({
132
+ name: field.name,
133
+ maxCount: field.maxCount || 10, // Default maxCount is 10 if not specified.
134
+ }));
135
+
136
+ let allowedFileTypes = [];
137
+
138
+ fields.forEach((field) => {
139
+ const types = field.fileTypes || [];
140
+ types.forEach((type) => {
141
+ if (ALLOWED_MIME_TYPES[type]) {
142
+ allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
143
+ }
144
+ });
145
+ });
146
+
147
+ const multerInstance = configureMulter({
148
+ fileTypes: allowedFileTypes,
149
+ customMimeTypes: [],
150
+ fileSizeLimit: fields[0]?.fileSizeLimit, // Assuming all fields share the same limit.
151
+ });
152
+
153
+ return multerInstance.fields(fieldConfigs);
154
+ };
155
+
156
+ // Export functions to configure multer and available file types
157
+ module.exports = {
158
+ /**
159
+ * Function to handle a single file upload.
160
+ *
161
+ * @param {object} options - Configuration options for the single file upload.
162
+ * @param {string} [options.destination] - Destination folder for the uploaded file.
163
+ * @param {string} [options.filename] - Custom filename template for the uploaded file.
164
+ * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images']).
165
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
166
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
167
+ * @param {boolean} [options.preservePath] - Preserve the full path of the uploaded file. Default is false.
168
+ * @returns {function} - Multer instance configured for single file upload.
169
+ */
170
+ uploadSingle: (options = {}) => {
171
+ const multerInstance = configureMulter(options);
172
+ return multerInstance.single(options.filename || "file");
173
+ },
174
+
175
+ /**
176
+ * Function to handle multiple file uploads across multiple fields.
177
+ *
178
+ * @param {object} options - Configuration options for multiple file uploads.
179
+ * @param {Array<object>} options.fields - Array of field configurations for multiple file uploads.
180
+ * @param {string} [options.destination] - Destination folder for the uploaded files.
181
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
182
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
183
+ * @param {boolean} [options.preservePath] - Preserve the full path of the uploaded files. Default is false.
184
+ * @returns {function} - Multer instance configured for multiple file uploads.
185
+ */
186
+ uploadMultiple: (options = {}) => {
187
+ const multerInstance = configureMulter(options);
188
+ return multerInstance.fields(options.fields || []);
189
+ },
190
+
191
+ /**
192
+ * Export the allowed file types for reference.
193
+ *
194
+ * @type {Array<string>}
195
+ */
196
+ ALLOWED_FILE_TYPES: Object.keys(ALLOWED_MIME_TYPES),
197
+ };
package/dist/index.js ADDED
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.uploadSingle = exports.uploadMultiple = exports.uploadFields = exports.configureStorage = exports.configureMulter = exports.configureFileFilter = exports.ALLOWED_FILE_TYPES = void 0;
7
+ var _multer = _interopRequireDefault(require("multer"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _uuid = require("uuid");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ // Constants for allowed MIME types
12
+ const ALLOWED_MIME_TYPES = {
13
+ images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
14
+ videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
15
+ pdfs: ["application/pdf"],
16
+ all: ["image/jpeg", "image/jpg", "image/png", "image/gif", "video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi", "application/pdf"]
17
+ };
18
+
19
+ /**
20
+ * Function to configure storage for Multer.
21
+ *
22
+ * @param {string} destination - The destination folder where files will be stored. Default is "uploads".
23
+ * @returns {object} - Multer storage configuration object.
24
+ */
25
+ const configureStorage = destination => {
26
+ return _multer.default.diskStorage({
27
+ destination: (req, file, cb) => {
28
+ cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
29
+ },
30
+ filename: (req, file, cb) => {
31
+ const sanitizedFilename = file.originalname.replace(/\\/g, "/");
32
+ const extension = _path.default.extname(sanitizedFilename);
33
+ const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
34
+ const uniqueName = (0, _uuid.v4)(); // Generate a unique name using uuid.
35
+ let fileName = `${uniqueName}-${fieldName}${extension}`;
36
+
37
+ // Replace backslashes with forward slashes in the final filename
38
+ fileName = fileName.replace(/\\/g, "/");
39
+ cb(null, fileName); // Set the final filename.
40
+ }
41
+ });
42
+ };
43
+
44
+ /**
45
+ * Function to configure file filter for Multer.
46
+ *
47
+ * @param {Array} allowedMimeTypes - Array of allowed MIME types.
48
+ * @returns {function} - File filter function for Multer.
49
+ */
50
+ exports.configureStorage = configureStorage;
51
+ const configureFileFilter = allowedMimeTypes => {
52
+ return (req, file, cb) => {
53
+ if (allowedMimeTypes.includes(file.mimetype)) {
54
+ cb(null, true); // Allow the file if its MIME type is allowed.
55
+ } else {
56
+ cb(new Error("Invalid file type. Only specified file types are allowed."), false); // Reject the file if its MIME type is not allowed.
57
+ }
58
+ };
59
+ };
60
+
61
+ /**
62
+ * Function to configure Multer with the provided options.
63
+ *
64
+ * @param {object} options - Configuration options for Multer.
65
+ * @param {string} [options.destination] - Destination folder for files. Default is "uploads".
66
+ * @param {string} [options.filename] - Custom filename template for saved files.
67
+ * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
68
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
69
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
70
+ * @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
71
+ * @returns {object} - Multer instance configured with the provided options.
72
+ */
73
+ exports.configureFileFilter = configureFileFilter;
74
+ const configureMulter = ({
75
+ destination,
76
+ filename,
77
+ fileTypes = [],
78
+ customMimeTypes = [],
79
+ fileSizeLimit,
80
+ preservePath = false
81
+ }) => {
82
+ const storage = configureStorage(destination);
83
+
84
+ // Combine allowed MIME types based on fileTypes array
85
+ let allowedMimeTypes = [];
86
+ if (customMimeTypes.length > 0) {
87
+ // Use custom MIME types if provided
88
+ allowedMimeTypes = customMimeTypes;
89
+ } else {
90
+ // Use default MIME types for specified fileTypes
91
+ fileTypes.forEach(type => {
92
+ if (ALLOWED_MIME_TYPES[type]) {
93
+ allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
94
+ }
95
+ });
96
+
97
+ // If no specific file types are provided, use all allowed MIME types
98
+ if (allowedMimeTypes.length === 0) {
99
+ allowedMimeTypes = ALLOWED_MIME_TYPES.all;
100
+ }
101
+ }
102
+ const fileFilter = configureFileFilter(allowedMimeTypes);
103
+ return (0, _multer.default)({
104
+ storage,
105
+ fileFilter,
106
+ limits: {
107
+ fileSize: fileSizeLimit || 1024 * 1024 * 50
108
+ },
109
+ // Default 50MB file size limit
110
+ preservePath
111
+ });
112
+ };
113
+
114
+ /**
115
+ * Function to handle multiple fields in a single form submission.
116
+ *
117
+ * @param {Array} fields - Array of field configurations, each containing:
118
+ * @param {string} fields.name - The name of the form field.
119
+ * @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
120
+ * @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
121
+ * @returns {function} - Multer instance configured to handle multiple fields.
122
+ */
123
+ exports.configureMulter = configureMulter;
124
+ const uploadFields = fields => {
125
+ const fieldConfigs = fields.map(field => ({
126
+ name: field.name,
127
+ maxCount: field.maxCount || 10 // Default maxCount is 10 if not specified.
128
+ }));
129
+ let allowedFileTypes = [];
130
+ fields.forEach(field => {
131
+ const types = field.fileTypes || [];
132
+ types.forEach(type => {
133
+ if (ALLOWED_MIME_TYPES[type]) {
134
+ allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
135
+ }
136
+ });
137
+ });
138
+ const multerInstance = configureMulter({
139
+ fileTypes: allowedFileTypes,
140
+ customMimeTypes: [],
141
+ fileSizeLimit: fields[0]?.fileSizeLimit // Assuming all fields share the same limit.
142
+ });
143
+ return multerInstance.fields(fieldConfigs);
144
+ };
145
+
146
+ // Export functions to configure multer and available file types
147
+ exports.uploadFields = uploadFields;
148
+ const uploadSingle = (options = {}) => {
149
+ const multerInstance = configureMulter(options);
150
+ return multerInstance.single(options.filename || "file");
151
+ };
152
+ exports.uploadSingle = uploadSingle;
153
+ const uploadMultiple = (options = {}) => {
154
+ const multerInstance = configureMulter(options);
155
+ return multerInstance.fields(options.fields || []);
156
+ };
157
+ exports.uploadMultiple = uploadMultiple;
158
+ const ALLOWED_FILE_TYPES = exports.ALLOWED_FILE_TYPES = Object.keys(ALLOWED_MIME_TYPES);
package/dist/index.mjs ADDED
@@ -0,0 +1,167 @@
1
+ import multer from "multer";
2
+ import path from "path";
3
+ import { v4 as uuidv4 } from "uuid";
4
+
5
+ // Constants for allowed MIME types
6
+ const ALLOWED_MIME_TYPES = {
7
+ images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
8
+ videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
9
+ pdfs: ["application/pdf"],
10
+ all: [
11
+ "image/jpeg",
12
+ "image/jpg",
13
+ "image/png",
14
+ "image/gif",
15
+ "video/mp4",
16
+ "video/mpeg",
17
+ "video/ogg",
18
+ "video/webm",
19
+ "video/avi",
20
+ "application/pdf",
21
+ ],
22
+ };
23
+
24
+ /**
25
+ * Function to configure storage for Multer.
26
+ *
27
+ * @param {string} destination - The destination folder where files will be stored. Default is "uploads".
28
+ * @returns {object} - Multer storage configuration object.
29
+ */
30
+ export const configureStorage = (destination) => {
31
+ return multer.diskStorage({
32
+ destination: (req, file, cb) => {
33
+ cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
34
+ },
35
+ filename: (req, file, cb) => {
36
+ const sanitizedFilename = file.originalname.replace(/\\/g, "/");
37
+ const extension = path.extname(sanitizedFilename);
38
+ const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
39
+ const uniqueName = uuidv4(); // Generate a unique name using uuid.
40
+ let fileName = `${uniqueName}-${fieldName}${extension}`;
41
+
42
+ // Replace backslashes with forward slashes in the final filename
43
+ fileName = fileName.replace(/\\/g, "/");
44
+
45
+ cb(null, fileName); // Set the final filename.
46
+ },
47
+ });
48
+ };
49
+
50
+ /**
51
+ * Function to configure file filter for Multer.
52
+ *
53
+ * @param {Array} allowedMimeTypes - Array of allowed MIME types.
54
+ * @returns {function} - File filter function for Multer.
55
+ */
56
+ export const configureFileFilter = (allowedMimeTypes) => {
57
+ return (req, file, cb) => {
58
+ if (allowedMimeTypes.includes(file.mimetype)) {
59
+ cb(null, true); // Allow the file if its MIME type is allowed.
60
+ } else {
61
+ cb(
62
+ new Error("Invalid file type. Only specified file types are allowed."),
63
+ false
64
+ ); // Reject the file if its MIME type is not allowed.
65
+ }
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Function to configure Multer with the provided options.
71
+ *
72
+ * @param {object} options - Configuration options for Multer.
73
+ * @param {string} [options.destination] - Destination folder for files. Default is "uploads".
74
+ * @param {string} [options.filename] - Custom filename template for saved files.
75
+ * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
76
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
77
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
78
+ * @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
79
+ * @returns {object} - Multer instance configured with the provided options.
80
+ */
81
+ export const configureMulter = ({
82
+ destination,
83
+ filename,
84
+ fileTypes = [],
85
+ customMimeTypes = [],
86
+ fileSizeLimit,
87
+ preservePath = false,
88
+ }) => {
89
+ const storage = configureStorage(destination);
90
+
91
+ // Combine allowed MIME types based on fileTypes array
92
+ let allowedMimeTypes = [];
93
+
94
+ if (customMimeTypes.length > 0) {
95
+ // Use custom MIME types if provided
96
+ allowedMimeTypes = customMimeTypes;
97
+ } else {
98
+ // Use default MIME types for specified fileTypes
99
+ fileTypes.forEach((type) => {
100
+ if (ALLOWED_MIME_TYPES[type]) {
101
+ allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
102
+ }
103
+ });
104
+
105
+ // If no specific file types are provided, use all allowed MIME types
106
+ if (allowedMimeTypes.length === 0) {
107
+ allowedMimeTypes = ALLOWED_MIME_TYPES.all;
108
+ }
109
+ }
110
+
111
+ const fileFilter = configureFileFilter(allowedMimeTypes);
112
+
113
+ return multer({
114
+ storage,
115
+ fileFilter,
116
+ limits: { fileSize: fileSizeLimit || 1024 * 1024 * 50 }, // Default 50MB file size limit
117
+ preservePath,
118
+ });
119
+ };
120
+
121
+ /**
122
+ * Function to handle multiple fields in a single form submission.
123
+ *
124
+ * @param {Array} fields - Array of field configurations, each containing:
125
+ * @param {string} fields.name - The name of the form field.
126
+ * @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
127
+ * @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
128
+ * @returns {function} - Multer instance configured to handle multiple fields.
129
+ */
130
+ export const uploadFields = (fields) => {
131
+ const fieldConfigs = fields.map((field) => ({
132
+ name: field.name,
133
+ maxCount: field.maxCount || 10, // Default maxCount is 10 if not specified.
134
+ }));
135
+
136
+ let allowedFileTypes = [];
137
+
138
+ fields.forEach((field) => {
139
+ const types = field.fileTypes || [];
140
+ types.forEach((type) => {
141
+ if (ALLOWED_MIME_TYPES[type]) {
142
+ allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
143
+ }
144
+ });
145
+ });
146
+
147
+ const multerInstance = configureMulter({
148
+ fileTypes: allowedFileTypes,
149
+ customMimeTypes: [],
150
+ fileSizeLimit: fields[0]?.fileSizeLimit, // Assuming all fields share the same limit.
151
+ });
152
+
153
+ return multerInstance.fields(fieldConfigs);
154
+ };
155
+
156
+ // Export functions to configure multer and available file types
157
+ export const uploadSingle = (options = {}) => {
158
+ const multerInstance = configureMulter(options);
159
+ return multerInstance.single(options.filename || "file");
160
+ };
161
+
162
+ export const uploadMultiple = (options = {}) => {
163
+ const multerInstance = configureMulter(options);
164
+ return multerInstance.fields(options.fields || []);
165
+ };
166
+
167
+ export const ALLOWED_FILE_TYPES = Object.keys(ALLOWED_MIME_TYPES);
package/package.json CHANGED
@@ -1,30 +1,23 @@
1
1
  {
2
2
  "name": "multermate",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "A flexible and customizable npm package for configuring Multer",
5
- "main": "index.js",
5
+ "main": "./dist/index.cjs.js",
6
+ "module": "./dist/index.mjs",
6
7
  "scripts": {
8
+ "build:cjs": "babel src --out-dir dist --extensions \".js\" --plugins=@babel/plugin-transform-modules-commonjs",
9
+ "build:esm": "babel src --out-dir dist --extensions \".js\"",
10
+ "build": "npm run build:cjs && npm run build:esm",
7
11
  "test": "echo \"Error: no test specified\" && exit 1"
8
12
  },
9
- "keywords": [
10
- "multer",
11
- "file upload",
12
- "middleware",
13
- "node.js",
14
- "configurable"
15
- ],
16
- "author": "Wasim Zaman",
17
- "license": "MIT",
18
13
  "dependencies": {
19
14
  "multer": "1.4.5-lts.1",
20
15
  "uuid": "^10.0.0"
21
16
  },
22
- "repository": {
23
- "type": "git",
24
- "url": "git+https://github.com/Wasim-Zaman/multermate.git"
25
- },
26
- "bugs": {
27
- "url": "https://github.com/Wasim-Zaman/multermate/issues"
28
- },
29
- "homepage": "https://github.com/Wasim-Zaman/multermate#readme"
17
+ "devDependencies": {
18
+ "@babel/cli": "^7.25.6",
19
+ "@babel/core": "^7.25.2",
20
+ "@babel/plugin-transform-modules-commonjs": "^7.24.8",
21
+ "@babel/preset-env": "^7.25.4"
22
+ }
30
23
  }
@@ -1,159 +1,159 @@
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.
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.
package/src/index.js ADDED
@@ -0,0 +1,167 @@
1
+ import multer from "multer";
2
+ import path from "path";
3
+ import { v4 as uuidv4 } from "uuid";
4
+
5
+ // Constants for allowed MIME types
6
+ const ALLOWED_MIME_TYPES = {
7
+ images: ["image/jpeg", "image/jpg", "image/png", "image/gif"],
8
+ videos: ["video/mp4", "video/mpeg", "video/ogg", "video/webm", "video/avi"],
9
+ pdfs: ["application/pdf"],
10
+ all: [
11
+ "image/jpeg",
12
+ "image/jpg",
13
+ "image/png",
14
+ "image/gif",
15
+ "video/mp4",
16
+ "video/mpeg",
17
+ "video/ogg",
18
+ "video/webm",
19
+ "video/avi",
20
+ "application/pdf",
21
+ ],
22
+ };
23
+
24
+ /**
25
+ * Function to configure storage for Multer.
26
+ *
27
+ * @param {string} destination - The destination folder where files will be stored. Default is "uploads".
28
+ * @returns {object} - Multer storage configuration object.
29
+ */
30
+ export const configureStorage = (destination) => {
31
+ return multer.diskStorage({
32
+ destination: (req, file, cb) => {
33
+ cb(null, destination || "uploads"); // Default folder is "uploads" if none is provided.
34
+ },
35
+ filename: (req, file, cb) => {
36
+ const sanitizedFilename = file.originalname.replace(/\\/g, "/");
37
+ const extension = path.extname(sanitizedFilename);
38
+ const fieldName = file.fieldname || "file"; // Use the field name as part of the filename.
39
+ const uniqueName = uuidv4(); // Generate a unique name using uuid.
40
+ let fileName = `${uniqueName}-${fieldName}${extension}`;
41
+
42
+ // Replace backslashes with forward slashes in the final filename
43
+ fileName = fileName.replace(/\\/g, "/");
44
+
45
+ cb(null, fileName); // Set the final filename.
46
+ },
47
+ });
48
+ };
49
+
50
+ /**
51
+ * Function to configure file filter for Multer.
52
+ *
53
+ * @param {Array} allowedMimeTypes - Array of allowed MIME types.
54
+ * @returns {function} - File filter function for Multer.
55
+ */
56
+ export const configureFileFilter = (allowedMimeTypes) => {
57
+ return (req, file, cb) => {
58
+ if (allowedMimeTypes.includes(file.mimetype)) {
59
+ cb(null, true); // Allow the file if its MIME type is allowed.
60
+ } else {
61
+ cb(
62
+ new Error("Invalid file type. Only specified file types are allowed."),
63
+ false
64
+ ); // Reject the file if its MIME type is not allowed.
65
+ }
66
+ };
67
+ };
68
+
69
+ /**
70
+ * Function to configure Multer with the provided options.
71
+ *
72
+ * @param {object} options - Configuration options for Multer.
73
+ * @param {string} [options.destination] - Destination folder for files. Default is "uploads".
74
+ * @param {string} [options.filename] - Custom filename template for saved files.
75
+ * @param {Array<string>} [options.fileTypes] - Array of file types to allow (e.g., ['images', 'videos']).
76
+ * @param {Array<string>} [options.customMimeTypes] - Array of custom MIME types to allow.
77
+ * @param {number} [options.fileSizeLimit] - Maximum file size allowed (in bytes). Default is 50MB.
78
+ * @param {boolean} [options.preservePath] - Preserve the full path of files. Default is false.
79
+ * @returns {object} - Multer instance configured with the provided options.
80
+ */
81
+ export const configureMulter = ({
82
+ destination,
83
+ filename,
84
+ fileTypes = [],
85
+ customMimeTypes = [],
86
+ fileSizeLimit,
87
+ preservePath = false,
88
+ }) => {
89
+ const storage = configureStorage(destination);
90
+
91
+ // Combine allowed MIME types based on fileTypes array
92
+ let allowedMimeTypes = [];
93
+
94
+ if (customMimeTypes.length > 0) {
95
+ // Use custom MIME types if provided
96
+ allowedMimeTypes = customMimeTypes;
97
+ } else {
98
+ // Use default MIME types for specified fileTypes
99
+ fileTypes.forEach((type) => {
100
+ if (ALLOWED_MIME_TYPES[type]) {
101
+ allowedMimeTypes = allowedMimeTypes.concat(ALLOWED_MIME_TYPES[type]);
102
+ }
103
+ });
104
+
105
+ // If no specific file types are provided, use all allowed MIME types
106
+ if (allowedMimeTypes.length === 0) {
107
+ allowedMimeTypes = ALLOWED_MIME_TYPES.all;
108
+ }
109
+ }
110
+
111
+ const fileFilter = configureFileFilter(allowedMimeTypes);
112
+
113
+ return multer({
114
+ storage,
115
+ fileFilter,
116
+ limits: { fileSize: fileSizeLimit || 1024 * 1024 * 50 }, // Default 50MB file size limit
117
+ preservePath,
118
+ });
119
+ };
120
+
121
+ /**
122
+ * Function to handle multiple fields in a single form submission.
123
+ *
124
+ * @param {Array} fields - Array of field configurations, each containing:
125
+ * @param {string} fields.name - The name of the form field.
126
+ * @param {number} [fields.maxCount=10] - The maximum number of files to accept per field.
127
+ * @param {Array<string>} [fields.fileTypes] - Array of file types to allow for this field (e.g., ['images']).
128
+ * @returns {function} - Multer instance configured to handle multiple fields.
129
+ */
130
+ export const uploadFields = (fields) => {
131
+ const fieldConfigs = fields.map((field) => ({
132
+ name: field.name,
133
+ maxCount: field.maxCount || 10, // Default maxCount is 10 if not specified.
134
+ }));
135
+
136
+ let allowedFileTypes = [];
137
+
138
+ fields.forEach((field) => {
139
+ const types = field.fileTypes || [];
140
+ types.forEach((type) => {
141
+ if (ALLOWED_MIME_TYPES[type]) {
142
+ allowedFileTypes = allowedFileTypes.concat(ALLOWED_MIME_TYPES[type]);
143
+ }
144
+ });
145
+ });
146
+
147
+ const multerInstance = configureMulter({
148
+ fileTypes: allowedFileTypes,
149
+ customMimeTypes: [],
150
+ fileSizeLimit: fields[0]?.fileSizeLimit, // Assuming all fields share the same limit.
151
+ });
152
+
153
+ return multerInstance.fields(fieldConfigs);
154
+ };
155
+
156
+ // Export functions to configure multer and available file types
157
+ export const uploadSingle = (options = {}) => {
158
+ const multerInstance = configureMulter(options);
159
+ return multerInstance.single(options.filename || "file");
160
+ };
161
+
162
+ export const uploadMultiple = (options = {}) => {
163
+ const multerInstance = configureMulter(options);
164
+ return multerInstance.fields(options.fields || []);
165
+ };
166
+
167
+ export const ALLOWED_FILE_TYPES = Object.keys(ALLOWED_MIME_TYPES);