node-server-engine 1.10.8 → 1.10.10

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.
@@ -31,11 +31,13 @@ function fileUploader(filesOptions, validator) {
31
31
 
32
32
  // Setup multer with memory storage
33
33
  const storage = _multer.default.memoryStorage();
34
+ // Resolve global per-file upload size from env (e.g. "32MB") or fallback to 32MB
35
+ const globalMaxSize = process.env.UPLOAD_MAX_SIZE && (0, _bytes.default)(process.env.UPLOAD_MAX_SIZE) || 32 * 1024 * 1024;
34
36
  const upload = (0, _multer.default)({
35
37
  storage,
36
38
  limits: {
37
- fileSize: 32 * 1024 * 1024
38
- } // Default global limit (10MB)
39
+ fileSize: globalMaxSize
40
+ } // Global per-file limit (bytes)
39
41
  }).any();
40
42
  upload(request, response, async err => {
41
43
  if (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"fileUploader.js","names":["_WebError","require","_report","_multer","_interopRequireDefault","_validate","_path","_bytes","namespace","fileUploader","filesOptions","validator","request","response","next","reportDebug","message","data","storage","multer","memoryStorage","upload","limits","fileSize","any","err","error","uploadedFiles","Array","isArray","files","Object","values","flat","map","file","originalname","validate","uploadedFileKeys","fieldname","missingFiles","filter","option","required","includes","key","length","WebError","statusCode","errorCode","fileOption","find","mimeTypes","mimetype","expected","received","maxSize","maxSizeInBytes","bytes","size","receivedSize","noExtension","path","basename","extname"],"sources":["../../../src/middleware/fileUploader/fileUploader.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport { Schema } from 'express-validator';\nimport { WebError } from 'entities/WebError';\nimport { reportDebug } from 'utils/report';\nimport multer from 'multer';\nimport { FileUploaderConfig } from './fileUploader.types';\nimport { validate } from './validate';\nimport path from 'path';\nimport bytes from 'bytes';\n\nconst namespace = 'engine:middleware:fileUploader';\n\n/**\n * Middleware for handling file uploads.\n * @param filesOptions Configuration options for expected files.\n * @param validator Validation schema for request fields.\n */\nexport function fileUploader(\n filesOptions: Array<FileUploaderConfig>,\n validator: Schema\n) {\n return async (\n request: Request,\n response: Response,\n next: NextFunction\n ): Promise<void> => {\n reportDebug({\n namespace,\n message: 'Received request to upload file',\n data: { filesOptions, validator }\n });\n\n // Setup multer with memory storage\n const storage = multer.memoryStorage();\n const upload = multer({\n storage,\n limits: { fileSize: 32 * 1024 * 1024 } // Default global limit (10MB)\n }).any();\n\n upload(request, response, async (err) => {\n if (err) {\n reportDebug({\n namespace,\n message: 'Multer upload error',\n data: { error: err.message }\n });\n return next(err);\n }\n\n // Ensure `request.files` is properly typed\n let uploadedFiles: Express.Multer.File[] = [];\n if (Array.isArray(request.files)) {\n uploadedFiles = request.files;\n } else if (typeof request.files === 'object') {\n uploadedFiles = Object.values(request.files).flat();\n }\n\n // Log uploaded files\n reportDebug({\n namespace,\n message: 'Files Received',\n data: { uploadedFiles: uploadedFiles.map((file) => file.originalname) }\n });\n\n // Validate request body fields\n try {\n await validate(request, validator);\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Validation failed',\n data: { error }\n });\n return next(error);\n }\n\n // Extract uploaded field names\n const uploadedFileKeys = uploadedFiles.map((file) => file.fieldname);\n\n // Check for missing required files\n const missingFiles = filesOptions.filter(\n (option) => option.required && !uploadedFileKeys.includes(option.key)\n );\n\n if (missingFiles.length > 0) {\n reportDebug({\n namespace,\n message: 'Missing required files',\n data: { missingFiles, uploadedFileKeys }\n });\n\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'missing-field',\n message: 'Some required files have not been uploaded',\n data: { missingFiles, uploadedFileKeys }\n })\n );\n }\n\n // Validate each uploaded file\n for (const file of uploadedFiles) {\n const fileOption = filesOptions.find(\n (option) => option.key === file.fieldname\n );\n\n if (!fileOption) continue;\n\n // MIME Type Validation\n if (\n fileOption.mimeTypes &&\n !fileOption.mimeTypes.includes(file.mimetype)\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'invalid-mime-type',\n message: `Invalid file type for ${file.fieldname}`,\n data: { expected: fileOption.mimeTypes, received: file.mimetype }\n })\n );\n }\n\n // Max File Size Validation\n if (fileOption.maxSize) {\n const maxSizeInBytes = bytes(fileOption.maxSize);\n if (maxSizeInBytes && file.size > maxSizeInBytes) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'file-too-large',\n message: `File ${file.originalname} exceeds the allowed size`,\n data: { maxSize: fileOption.maxSize, receivedSize: file.size }\n })\n );\n }\n }\n\n // No Extension Handling\n if (fileOption.noExtension) {\n file.originalname = path.basename(\n file.originalname,\n path.extname(file.originalname)\n );\n }\n }\n\n request.files = uploadedFiles;\n\n next();\n });\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"fileUploader.js","names":["_WebError","require","_report","_multer","_interopRequireDefault","_validate","_path","_bytes","namespace","fileUploader","filesOptions","validator","request","response","next","reportDebug","message","data","storage","multer","memoryStorage","globalMaxSize","process","env","UPLOAD_MAX_SIZE","bytes","upload","limits","fileSize","any","err","error","uploadedFiles","Array","isArray","files","Object","values","flat","map","file","originalname","validate","uploadedFileKeys","fieldname","missingFiles","filter","option","required","includes","key","length","WebError","statusCode","errorCode","fileOption","find","mimeTypes","mimetype","expected","received","maxSize","maxSizeInBytes","size","receivedSize","noExtension","path","basename","extname"],"sources":["../../../src/middleware/fileUploader/fileUploader.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport { Schema } from 'express-validator';\nimport { WebError } from 'entities/WebError';\nimport { reportDebug } from 'utils/report';\nimport multer from 'multer';\nimport { FileUploaderConfig } from './fileUploader.types';\nimport { validate } from './validate';\nimport path from 'path';\nimport bytes from 'bytes';\n\nconst namespace = 'engine:middleware:fileUploader';\n\n/**\n * Middleware for handling file uploads.\n * @param filesOptions Configuration options for expected files.\n * @param validator Validation schema for request fields.\n */\nexport function fileUploader(\n filesOptions: Array<FileUploaderConfig>,\n validator: Schema\n) {\n return async (\n request: Request,\n response: Response,\n next: NextFunction\n ): Promise<void> => {\n reportDebug({\n namespace,\n message: 'Received request to upload file',\n data: { filesOptions, validator }\n });\n\n // Setup multer with memory storage\n const storage = multer.memoryStorage();\n // Resolve global per-file upload size from env (e.g. \"32MB\") or fallback to 32MB\n const globalMaxSize =\n (process.env.UPLOAD_MAX_SIZE && bytes(process.env.UPLOAD_MAX_SIZE)) ||\n 32 * 1024 * 1024;\n\n const upload = multer({\n storage,\n limits: { fileSize: globalMaxSize } // Global per-file limit (bytes)\n }).any();\n\n upload(request, response, async (err) => {\n if (err) {\n reportDebug({\n namespace,\n message: 'Multer upload error',\n data: { error: err.message }\n });\n return next(err);\n }\n\n // Ensure `request.files` is properly typed\n let uploadedFiles: Express.Multer.File[] = [];\n if (Array.isArray(request.files)) {\n uploadedFiles = request.files;\n } else if (typeof request.files === 'object') {\n uploadedFiles = Object.values(request.files).flat();\n }\n\n // Log uploaded files\n reportDebug({\n namespace,\n message: 'Files Received',\n data: { uploadedFiles: uploadedFiles.map((file) => file.originalname) }\n });\n\n // Validate request body fields\n try {\n await validate(request, validator);\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Validation failed',\n data: { error }\n });\n return next(error);\n }\n\n // Extract uploaded field names\n const uploadedFileKeys = uploadedFiles.map((file) => file.fieldname);\n\n // Check for missing required files\n const missingFiles = filesOptions.filter(\n (option) => option.required && !uploadedFileKeys.includes(option.key)\n );\n\n if (missingFiles.length > 0) {\n reportDebug({\n namespace,\n message: 'Missing required files',\n data: { missingFiles, uploadedFileKeys }\n });\n\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'missing-field',\n message: 'Some required files have not been uploaded',\n data: { missingFiles, uploadedFileKeys }\n })\n );\n }\n\n // Validate each uploaded file\n for (const file of uploadedFiles) {\n const fileOption = filesOptions.find(\n (option) => option.key === file.fieldname\n );\n\n if (!fileOption) continue;\n\n // MIME Type Validation\n if (\n fileOption.mimeTypes &&\n !fileOption.mimeTypes.includes(file.mimetype)\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'invalid-mime-type',\n message: `Invalid file type for ${file.fieldname}`,\n data: { expected: fileOption.mimeTypes, received: file.mimetype }\n })\n );\n }\n\n // Max File Size Validation\n if (fileOption.maxSize) {\n const maxSizeInBytes = bytes(fileOption.maxSize);\n if (maxSizeInBytes && file.size > maxSizeInBytes) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'file-too-large',\n message: `File ${file.originalname} exceeds the allowed size`,\n data: { maxSize: fileOption.maxSize, receivedSize: file.size }\n })\n );\n }\n }\n\n // No Extension Handling\n if (fileOption.noExtension) {\n file.originalname = path.basename(\n file.originalname,\n path.extname(file.originalname)\n );\n }\n }\n\n request.files = uploadedFiles;\n\n next();\n });\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -11,6 +11,7 @@ var _path = _interopRequireDefault(require("path"));
11
11
  var _utils = require("../../utils");
12
12
  var _WebError = require("../../entities/WebError");
13
13
  var _validate = require("./validate");
14
+ var _bytes = _interopRequireDefault(require("bytes"));
14
15
  const namespace = 'engine:middleware:multiPartFileUploader';
15
16
  const TEMP_DIR = _path.default.join(process.env.FILE_STORAGE_FOLDER || './uploads', 'temp_chunks');
16
17
  const FILE_DIR = _path.default.join(process.env.FILE_STORAGE_FOLDER || './uploads', 'completed_files');
@@ -92,7 +93,7 @@ function multiPartFileUploader(filesOption, validator) {
92
93
  }
93
94
  }));
94
95
  }
95
- if (filesOption?.maxSize && req.file.size > parseInt(filesOption?.maxSize, 10)) {
96
+ if (filesOption?.maxSize && req.file.size > ((0, _bytes.default)(filesOption.maxSize) || 0)) {
96
97
  return next(new _WebError.WebError({
97
98
  statusCode: 400,
98
99
  errorCode: 'chunk-too-large',
@@ -187,12 +188,18 @@ async function mergeChunks(filename, totalChunks, sessionFolder, finalFilePath)
187
188
  finalFilePath
188
189
  }
189
190
  });
190
- for (let i = 0; i < parseInt(totalChunks, 10); i++) {
191
+ const totalChunksNum = parseInt(totalChunks, 10);
192
+ const chunks = [];
193
+
194
+ // Read all chunks into memory first
195
+ for (let i = 0; i < totalChunksNum; i++) {
191
196
  const partPath = _path.default.join(sessionFolder, `${filename}.part${i}`);
192
197
  try {
193
198
  const chunkData = await _fsExtra.default.readFile(partPath);
194
- writeStream.write(chunkData);
199
+ chunks.push(chunkData);
195
200
  } catch (error) {
201
+ // Cleanup on error
202
+ await _fsExtra.default.remove(sessionFolder).catch(cleanupErr => (0, _utils.reportError)(`Error cleaning up folder ${sessionFolder}: ${cleanupErr.message}`));
196
203
  throw new _WebError.WebError({
197
204
  statusCode: 500,
198
205
  errorCode: 'chunk-read-failed',
@@ -202,19 +209,39 @@ async function mergeChunks(filename, totalChunks, sessionFolder, finalFilePath)
202
209
  }
203
210
  });
204
211
  }
212
+ }
213
+
214
+ // Write all chunks sequentially
215
+ for (const chunkData of chunks) {
216
+ writeStream.write(chunkData);
217
+ }
218
+
219
+ // Remove temp files
220
+ for (let i = 0; i < totalChunksNum; i++) {
221
+ const partPath = _path.default.join(sessionFolder, `${filename}.part${i}`);
205
222
  _fsExtra.default.remove(partPath).catch(err => (0, _utils.reportError)(`Error removing part ${partPath}: ${err.message}`));
206
223
  }
207
224
  writeStream.end();
208
225
  return new Promise((resolve, reject) => {
209
- writeStream.on('finish', () => resolve(undefined));
210
- writeStream.on('error', error => reject(new _WebError.WebError({
211
- statusCode: 500,
212
- errorCode: 'file-merge-error',
213
- message: 'Error merging file chunks',
214
- data: {
215
- error: error.message
216
- }
217
- })));
226
+ writeStream.on('finish', () => {
227
+ // Clean up temp folder after successful merge
228
+ _fsExtra.default.remove(sessionFolder).then(() => resolve(undefined)).catch(cleanupErr => {
229
+ (0, _utils.reportError)(`Error cleaning up temp folder ${sessionFolder}: ${cleanupErr.message}`);
230
+ resolve(undefined); // Don't fail the merge if cleanup fails
231
+ });
232
+ });
233
+ writeStream.on('error', error => {
234
+ // Cleanup on write error
235
+ _fsExtra.default.remove(sessionFolder).catch(cleanupErr => (0, _utils.reportError)(`Error cleaning up folder after write error: ${cleanupErr.message}`));
236
+ reject(new _WebError.WebError({
237
+ statusCode: 500,
238
+ errorCode: 'file-merge-error',
239
+ message: 'Error merging file chunks',
240
+ data: {
241
+ error: error.message
242
+ }
243
+ }));
244
+ });
218
245
  });
219
246
  }
220
247
  //# sourceMappingURL=multiPartFileUploader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"multiPartFileUploader.js","names":["_multer","_interopRequireDefault","require","_fsExtra","_path","_utils","_WebError","_validate","namespace","TEMP_DIR","path","join","process","env","FILE_STORAGE_FOLDER","FILE_DIR","fs","ensureDirSync","storage","multer","memoryStorage","multiPartFileUploader","filesOption","validator","req","res","next","reportDebug","message","uploadSingle","single","err","reportError","WebError","statusCode","errorCode","data","error","validate","filename","totalChunks","chunkIndex","uniqueID","body","undefined","file","receivedChunk","maxSize","size","parseInt","receivedSize","sessionFolder","chunkPath","writeFile","buffer","writeErr","uploadedChunks","readdir","length","finalFilePath","mergeChunks","multipartFile","isPending","originalname","filePath","mergeErr","writeStream","createWriteStream","i","partPath","chunkData","readFile","write","remove","catch","end","Promise","resolve","reject","on"],"sources":["../../../src/middleware/multiPartFileUploader/multiPartFileUploader.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport multer from 'multer';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { Schema } from 'express-validator';\nimport { reportDebug, reportError } from 'utils';\nimport { WebError } from 'entities/WebError';\nimport { validate } from './validate';\nimport { MultiPartFileUploaderConfig } from './multiPartFileUploader.types';\n\nconst namespace = 'engine:middleware:multiPartFileUploader';\n\nconst TEMP_DIR: string = path.join(\n process.env.FILE_STORAGE_FOLDER || './uploads',\n 'temp_chunks'\n);\nconst FILE_DIR: string = path.join(\n process.env.FILE_STORAGE_FOLDER || './uploads',\n 'completed_files'\n);\n\nfs.ensureDirSync(FILE_DIR);\nfs.ensureDirSync(TEMP_DIR);\n\nconst storage = multer.memoryStorage();\n\nexport function multiPartFileUploader(\n filesOption: MultiPartFileUploaderConfig,\n validator: Schema\n) {\n return async (\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> => {\n try {\n reportDebug({ namespace, message: 'Starting file upload middleware' });\n\n const uploadSingle = multer({ storage }).single('file');\n uploadSingle(req, res, async (err) => {\n if (err) {\n reportError('Error uploading chunk');\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'upload-failed',\n message: 'Error uploading file chunk',\n data: { error: err.message }\n })\n );\n }\n\n try {\n reportDebug({ namespace, message: 'Validating request' });\n await validate(req, validator);\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Validation failed',\n data: { error }\n });\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'validation-failed',\n message: 'Validation failed for file upload',\n data: { error: (error as Error).message }\n })\n );\n }\n\n const { filename, totalChunks, chunkIndex, uniqueID } = req.body;\n reportDebug({\n namespace,\n message: 'Received chunk data',\n data: { filename, totalChunks, chunkIndex, uniqueID }\n });\n\n if (\n !filename ||\n !totalChunks ||\n chunkIndex === undefined ||\n !uniqueID ||\n !req.file\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'missing-field',\n message: 'Missing required fields',\n data: {\n filename,\n totalChunks,\n chunkIndex,\n uniqueID,\n receivedChunk: !!req.file\n }\n })\n );\n }\n\n if (\n filesOption?.maxSize &&\n req.file.size > parseInt(filesOption?.maxSize, 10)\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'chunk-too-large',\n message: 'Uploaded chunk exceeds the maximum allowed size',\n data: {\n maxSize: filesOption.maxSize,\n receivedSize: req.file.size\n }\n })\n );\n }\n\n const sessionFolder = path.join(TEMP_DIR, uniqueID);\n fs.ensureDirSync(sessionFolder);\n const chunkPath = path.join(\n sessionFolder,\n `${filename}.part${chunkIndex}`\n );\n\n try {\n reportDebug({\n namespace,\n message: 'Writing chunk to disk',\n data: { chunkPath }\n });\n await fs.writeFile(chunkPath, req.file.buffer);\n } catch (writeErr) {\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'chunk-write-failed',\n message: 'Failed to write chunk',\n data: { chunkIndex, error: (writeErr as Error).message }\n })\n );\n }\n\n const uploadedChunks = await fs.readdir(sessionFolder);\n reportDebug({\n namespace,\n message: 'Uploaded chunk count',\n data: { uploadedChunks: uploadedChunks.length, totalChunks }\n });\n\n if (uploadedChunks.length === parseInt(totalChunks, 10)) {\n try {\n const finalFilePath = path.join(\n FILE_DIR,\n `${uniqueID}_${filename}`\n );\n await mergeChunks(\n filename,\n totalChunks,\n sessionFolder,\n finalFilePath\n );\n req.multipartFile = {\n isPending: false,\n originalname: filename,\n uniqueID,\n filePath: finalFilePath\n };\n } catch (mergeErr) {\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'file-merge-failed',\n message: 'Error merging file chunks',\n data: { error: (mergeErr as Error).message }\n })\n );\n }\n return next();\n }\n\n req.multipartFile = {\n isPending: true,\n originalname: filename,\n uniqueID,\n chunkIndex,\n totalChunks\n };\n next();\n });\n } catch (error) {\n next(\n new WebError({\n statusCode: 500,\n errorCode: 'unexpected-error',\n message: 'Unexpected error in file upload',\n data: { error: (error as Error).message }\n })\n );\n }\n };\n}\n\nasync function mergeChunks(\n filename: string,\n totalChunks: string | number,\n sessionFolder: string,\n finalFilePath: string\n): Promise<void> {\n const writeStream = fs.createWriteStream(finalFilePath);\n reportDebug({\n namespace,\n message: 'Merging file chunks',\n data: { finalFilePath }\n });\n\n for (let i = 0; i < parseInt(totalChunks as string, 10); i++) {\n const partPath = path.join(sessionFolder, `${filename}.part${i}`);\n try {\n const chunkData = await fs.readFile(partPath);\n writeStream.write(chunkData);\n } catch (error) {\n throw new WebError({\n statusCode: 500,\n errorCode: 'chunk-read-failed',\n message: `Error reading chunk ${i}`,\n data: { error: (error as Error).message }\n });\n }\n fs.remove(partPath).catch((err: Error) =>\n reportError(`Error removing part ${partPath}: ${err.message}`)\n );\n }\n\n writeStream.end();\n return new Promise<void>((resolve, reject) => {\n writeStream.on('finish', () => resolve(undefined));\n writeStream.on('error', (error) =>\n reject(\n new WebError({\n statusCode: 500,\n errorCode: 'file-merge-error',\n message: 'Error merging file chunks',\n data: { error: (error as Error).message }\n })\n )\n );\n });\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"multiPartFileUploader.js","names":["_multer","_interopRequireDefault","require","_fsExtra","_path","_utils","_WebError","_validate","_bytes","namespace","TEMP_DIR","path","join","process","env","FILE_STORAGE_FOLDER","FILE_DIR","fs","ensureDirSync","storage","multer","memoryStorage","multiPartFileUploader","filesOption","validator","req","res","next","reportDebug","message","uploadSingle","single","err","reportError","WebError","statusCode","errorCode","data","error","validate","filename","totalChunks","chunkIndex","uniqueID","body","undefined","file","receivedChunk","maxSize","size","bytes","receivedSize","sessionFolder","chunkPath","writeFile","buffer","writeErr","uploadedChunks","readdir","length","parseInt","finalFilePath","mergeChunks","multipartFile","isPending","originalname","filePath","mergeErr","writeStream","createWriteStream","totalChunksNum","chunks","i","partPath","chunkData","readFile","push","remove","catch","cleanupErr","write","end","Promise","resolve","reject","on","then"],"sources":["../../../src/middleware/multiPartFileUploader/multiPartFileUploader.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport multer from 'multer';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { Schema } from 'express-validator';\nimport { reportDebug, reportError } from 'utils';\nimport { WebError } from 'entities/WebError';\nimport { validate } from './validate';\nimport { MultiPartFileUploaderConfig } from './multiPartFileUploader.types';\nimport bytes from 'bytes';\n\nconst namespace = 'engine:middleware:multiPartFileUploader';\n\nconst TEMP_DIR: string = path.join(\n process.env.FILE_STORAGE_FOLDER || './uploads',\n 'temp_chunks'\n);\nconst FILE_DIR: string = path.join(\n process.env.FILE_STORAGE_FOLDER || './uploads',\n 'completed_files'\n);\n\nfs.ensureDirSync(FILE_DIR);\nfs.ensureDirSync(TEMP_DIR);\n\nconst storage = multer.memoryStorage();\n\nexport function multiPartFileUploader(\n filesOption: MultiPartFileUploaderConfig,\n validator: Schema\n) {\n return async (\n req: Request,\n res: Response,\n next: NextFunction\n ): Promise<void> => {\n try {\n reportDebug({ namespace, message: 'Starting file upload middleware' });\n\n const uploadSingle = multer({ storage }).single('file');\n uploadSingle(req, res, async (err) => {\n if (err) {\n reportError('Error uploading chunk');\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'upload-failed',\n message: 'Error uploading file chunk',\n data: { error: err.message }\n })\n );\n }\n\n try {\n reportDebug({ namespace, message: 'Validating request' });\n await validate(req, validator);\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Validation failed',\n data: { error }\n });\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'validation-failed',\n message: 'Validation failed for file upload',\n data: { error: (error as Error).message }\n })\n );\n }\n\n const { filename, totalChunks, chunkIndex, uniqueID } = req.body;\n reportDebug({\n namespace,\n message: 'Received chunk data',\n data: { filename, totalChunks, chunkIndex, uniqueID }\n });\n\n if (\n !filename ||\n !totalChunks ||\n chunkIndex === undefined ||\n !uniqueID ||\n !req.file\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'missing-field',\n message: 'Missing required fields',\n data: {\n filename,\n totalChunks,\n chunkIndex,\n uniqueID,\n receivedChunk: !!req.file\n }\n })\n );\n }\n\n if (\n filesOption?.maxSize &&\n req.file.size > (bytes(filesOption.maxSize) || 0)\n ) {\n return next(\n new WebError({\n statusCode: 400,\n errorCode: 'chunk-too-large',\n message: 'Uploaded chunk exceeds the maximum allowed size',\n data: {\n maxSize: filesOption.maxSize,\n receivedSize: req.file.size\n }\n })\n );\n }\n\n const sessionFolder = path.join(TEMP_DIR, uniqueID);\n fs.ensureDirSync(sessionFolder);\n const chunkPath = path.join(\n sessionFolder,\n `${filename}.part${chunkIndex}`\n );\n\n try {\n reportDebug({\n namespace,\n message: 'Writing chunk to disk',\n data: { chunkPath }\n });\n await fs.writeFile(chunkPath, req.file.buffer);\n } catch (writeErr) {\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'chunk-write-failed',\n message: 'Failed to write chunk',\n data: { chunkIndex, error: (writeErr as Error).message }\n })\n );\n }\n\n const uploadedChunks = await fs.readdir(sessionFolder);\n reportDebug({\n namespace,\n message: 'Uploaded chunk count',\n data: { uploadedChunks: uploadedChunks.length, totalChunks }\n });\n\n if (uploadedChunks.length === parseInt(totalChunks, 10)) {\n try {\n const finalFilePath = path.join(\n FILE_DIR,\n `${uniqueID}_${filename}`\n );\n await mergeChunks(\n filename,\n totalChunks,\n sessionFolder,\n finalFilePath\n );\n req.multipartFile = {\n isPending: false,\n originalname: filename,\n uniqueID,\n filePath: finalFilePath\n };\n } catch (mergeErr) {\n return next(\n new WebError({\n statusCode: 500,\n errorCode: 'file-merge-failed',\n message: 'Error merging file chunks',\n data: { error: (mergeErr as Error).message }\n })\n );\n }\n return next();\n }\n\n req.multipartFile = {\n isPending: true,\n originalname: filename,\n uniqueID,\n chunkIndex,\n totalChunks\n };\n next();\n });\n } catch (error) {\n next(\n new WebError({\n statusCode: 500,\n errorCode: 'unexpected-error',\n message: 'Unexpected error in file upload',\n data: { error: (error as Error).message }\n })\n );\n }\n };\n}\n\nasync function mergeChunks(\n filename: string,\n totalChunks: string | number,\n sessionFolder: string,\n finalFilePath: string\n): Promise<void> {\n const writeStream = fs.createWriteStream(finalFilePath);\n reportDebug({\n namespace,\n message: 'Merging file chunks',\n data: { finalFilePath }\n });\n\n const totalChunksNum = parseInt(totalChunks as string, 10);\n const chunks: Buffer[] = [];\n\n // Read all chunks into memory first\n for (let i = 0; i < totalChunksNum; i++) {\n const partPath = path.join(sessionFolder, `${filename}.part${i}`);\n try {\n const chunkData = await fs.readFile(partPath);\n chunks.push(chunkData);\n } catch (error) {\n // Cleanup on error\n await fs.remove(sessionFolder).catch((cleanupErr: Error) =>\n reportError(`Error cleaning up folder ${sessionFolder}: ${cleanupErr.message}`)\n );\n throw new WebError({\n statusCode: 500,\n errorCode: 'chunk-read-failed',\n message: `Error reading chunk ${i}`,\n data: { error: (error as Error).message }\n });\n }\n }\n\n // Write all chunks sequentially\n for (const chunkData of chunks) {\n writeStream.write(chunkData);\n }\n\n // Remove temp files\n for (let i = 0; i < totalChunksNum; i++) {\n const partPath = path.join(sessionFolder, `${filename}.part${i}`);\n fs.remove(partPath).catch((err: Error) =>\n reportError(`Error removing part ${partPath}: ${err.message}`)\n );\n }\n\n writeStream.end();\n return new Promise<void>((resolve, reject) => {\n writeStream.on('finish', () => {\n // Clean up temp folder after successful merge\n fs.remove(sessionFolder)\n .then(() => resolve(undefined))\n .catch((cleanupErr: Error) => {\n reportError(\n `Error cleaning up temp folder ${sessionFolder}: ${cleanupErr.message}`\n );\n resolve(undefined); // Don't fail the merge if cleanup fails\n });\n });\n writeStream.on('error', (error) => {\n // Cleanup on write error\n fs.remove(sessionFolder).catch((cleanupErr: Error) =>\n reportError(`Error cleaning up folder after write error: ${cleanupErr.message}`)\n );\n reject(\n new WebError({\n statusCode: 500,\n errorCode: 'file-merge-error',\n message: 'Error merging file chunks',\n data: { error: (error as Error).message }\n })\n );\n });\n });\n}\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-server-engine",
3
- "version": "1.10.8",
3
+ "version": "1.10.10",
4
4
  "description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {