node-server-engine 1.2.9 → 1.3.1
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/.env.example +4 -1
- package/README.md +128 -107
- package/dist/entities/Endpoint/Endpoint.d.ts +2 -0
- package/dist/entities/Endpoint/Endpoint.js +11 -2
- package/dist/entities/Endpoint/Endpoint.js.map +1 -1
- package/dist/entities/Endpoint/Endpoint.types.d.ts +3 -0
- package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
- package/dist/entities/Server/Server.js +1 -1
- package/dist/entities/Server/Server.js.map +1 -1
- package/dist/middleware/fileUploader/fileUploader.js +45 -3
- package/dist/middleware/fileUploader/fileUploader.js.map +1 -1
- package/dist/middleware/multiPartFileUploader/index.d.ts +1 -0
- package/dist/middleware/multiPartFileUploader/index.js +11 -0
- package/dist/middleware/multiPartFileUploader/index.js.map +1 -1
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.d.ts +4 -3
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js +169 -105
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js.map +1 -1
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.d.ts +20 -0
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.js +2 -0
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.js.map +1 -0
- package/dist/middleware/multiPartFileUploader/validate/index.d.ts +1 -0
- package/dist/middleware/multiPartFileUploader/validate/index.js +17 -0
- package/dist/middleware/multiPartFileUploader/validate/index.js.map +1 -0
- package/dist/middleware/multiPartFileUploader/validate/validate.d.ts +4 -0
- package/dist/middleware/multiPartFileUploader/validate/validate.js +28 -0
- package/dist/middleware/multiPartFileUploader/validate/validate.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +11 -11
- package/dist/utils/index.js.map +1 -1
- package/package.json +3 -1
- package/src/entities/Endpoint/Endpoint.ts +22 -3
- package/src/entities/Endpoint/Endpoint.types.ts +3 -0
- package/src/entities/Server/Server.ts +0 -2
- package/src/middleware/fileUploader/fileUploader.ts +51 -2
- package/src/middleware/multiPartFileUploader/index.ts +1 -0
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +193 -128
- package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +23 -0
- package/src/middleware/multiPartFileUploader/validate/index.ts +1 -0
- package/src/middleware/multiPartFileUploader/validate/validate.ts +27 -0
- package/src/utils/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multiPartFileUploader.js","names":["_multer","_interopRequireDefault","require","_fsExtra","_path","_utils","TEMP_DIR","process","env","TEMP_CHUNK_FOLDER","namespace","fs","ensureDirSync","storage","multer","memoryStorage","multiPartFileUploader","req","res","next","uploadSingle","single","err","reportError","filename","totalChunks","chunkIndex","uniqueID","body","undefined","file","uploadDetails","status","message","details","receivedChunk","reportDebug","data","sessionFolder","path","join","chunkPath","writeFile","buffer","writeErr","uploadedChunks","readdir","length","parseInt","mergeChunks","mergeErr","finalFilePath","existsSync","Error","error","writeStream","createWriteStream","i","partPath","chunkData","readFile","write","remove","catch","end","Promise","resolve","reject","on"],"sources":["../../../src/middleware/multiPartFileUploader/multiPartFileUploader.ts"],"sourcesContent":["import express from 'express';\nimport multer from 'multer';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { reportDebug, reportError } from 'utils';\n\nconst TEMP_DIR: string =\n process.env.TEMP_CHUNK_FOLDER || './uploads/temp_chunks';\n\nconst namespace = 'engine:middleware:multiPartFileUploader';\n\nfs.ensureDirSync(TEMP_DIR);\n\nconst storage = multer.memoryStorage();\n\nasync function multiPartFileUploader(\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n): Promise<void> {\n try {\n const uploadSingle = multer({ storage }).single('file');\n\n uploadSingle(req, res, async (err) => {\n if (err) {\n reportError('Error uploading chunk');\n return next(err);\n }\n\n const { filename, totalChunks, chunkIndex, uniqueID } = req.body;\n\n if (\n !filename ||\n !totalChunks ||\n chunkIndex === undefined ||\n !uniqueID ||\n !req.file\n ) {\n req.body.uploadDetails = {\n status: 'failed',\n message: 'Missing required fields',\n details: {\n filename,\n totalChunks,\n chunkIndex,\n uniqueID,\n receivedChunk: !!req.file\n }\n };\n reportDebug({\n namespace,\n message: `Missing required fields`,\n data: {\n status: 'failed',\n details: {\n filename,\n totalChunks,\n chunkIndex,\n uniqueID\n }\n }\n });\n return next();\n }\n\n const sessionFolder = path.join(TEMP_DIR, uniqueID);\n fs.ensureDirSync(sessionFolder);\n\n const chunkPath = path.join(\n sessionFolder,\n `${filename}.part${chunkIndex}`\n );\n\n try {\n await fs.writeFile(chunkPath, req.file.buffer);\n } catch (writeErr) {\n reportError(\n `Failed to write chunk ${chunkIndex}: ${(writeErr as Error).message}`\n );\n return next(writeErr);\n }\n\n const uploadedChunks = await fs.readdir(sessionFolder);\n\n if (uploadedChunks.length === parseInt(totalChunks, 10)) {\n reportDebug({\n namespace,\n message: `All chunks uploaded. Merging file...`\n });\n\n try {\n await mergeChunks(filename, totalChunks, sessionFolder);\n } catch (mergeErr) {\n reportError(`File merging failed: ${(mergeErr as Error).message}`);\n return next(mergeErr);\n }\n\n const finalFilePath = path.join(sessionFolder, filename);\n\n if (!fs.existsSync(finalFilePath)) {\n reportError('File merging failed: File does not exist');\n return next(new Error('File merging failed'));\n }\n\n req.body.uploadDetails = {\n status: 'completed',\n message: 'File uploaded and merged successfully',\n details: { filename, uniqueID }\n };\n reportDebug({\n namespace,\n message: `File merged successfully`,\n data: {\n status: 'completed',\n details: { filename, uniqueID }\n }\n });\n\n return next();\n }\n\n reportDebug({\n namespace,\n message: `Chunk uploaded successfully`,\n data: {\n filename,\n uniqueID,\n chunkIndex,\n totalChunks\n }\n });\n\n req.body.uploadDetails = {\n status: 'pending',\n message: 'Chunk uploaded successfully',\n details: { filename, uniqueID, chunkIndex, totalChunks }\n };\n\n return next();\n });\n } catch (error) {\n reportError(\n `Failed to upload or process chunk: ${(error as Error).message}`\n );\n next(error);\n }\n}\n\nasync function mergeChunks(\n filename: string,\n totalChunks: string | number,\n sessionFolder: string\n): Promise<void> {\n const finalFilePath = path.join(sessionFolder, filename);\n const writeStream = fs.createWriteStream(finalFilePath);\n\n for (let i = 0; i < parseInt(totalChunks as string, 10); i++) {\n const partPath = path.join(sessionFolder, `${filename}.part${i}`);\n\n try {\n const chunkData = await fs.readFile(partPath);\n writeStream.write(chunkData);\n } catch (error) {\n reportError(`Error reading chunk ${i}: ${(error as Error).message}`);\n throw error;\n }\n\n fs.remove(partPath).catch((err: Error) =>\n reportError(`Error removing part ${partPath}: ${err.message}`)\n );\n }\n\n writeStream.end();\n\n return new Promise<void>((resolve, reject) => {\n writeStream.on('finish', () => resolve(undefined));\n writeStream.on('error', (error) => {\n reportError(`Error merging chunks: ${(error as Error).message}`);\n reject(error);\n });\n });\n}\n\nexport { multiPartFileUploader };\n"],"mappings":"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","ignoreList":[]}
|
|
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":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
namespace Express {
|
|
3
|
+
interface Request {
|
|
4
|
+
/** Uploaded files mapped by field name */
|
|
5
|
+
multipartFile?: {
|
|
6
|
+
isPending: boolean;
|
|
7
|
+
originalname: string;
|
|
8
|
+
uniqueID: string;
|
|
9
|
+
filePath?: string;
|
|
10
|
+
chunkIndex?: number;
|
|
11
|
+
totalChunks?: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Configuration for Multi part file upload */
|
|
17
|
+
export interface MultiPartFileUploaderConfig {
|
|
18
|
+
required?: boolean;
|
|
19
|
+
maxSize?: string;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiPartFileUploader.types.js","names":[],"sources":["../../../src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts"],"sourcesContent":["// Extend Express request object to include `files`\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n interface Request {\n /** Uploaded files mapped by field name */\n multipartFile?: {\n isPending: boolean;\n originalname: string;\n uniqueID: string;\n filePath?: string;\n chunkIndex?: number;\n totalChunks?: number;\n };\n }\n }\n}\n\n/** Configuration for Multi part file upload */\nexport interface MultiPartFileUploaderConfig {\n required?: boolean;\n maxSize?: string;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './validate';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _validate = require("./validate");
|
|
7
|
+
Object.keys(_validate).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _validate[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _validate[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["_validate","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../../src/middleware/multiPartFileUploader/validate/index.ts"],"sourcesContent":["export * from './validate';\n"],"mappings":";;;;;AAAA,IAAAA,SAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,SAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,SAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,SAAA,CAAAK,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.validate = validate;
|
|
7
|
+
var _validate = require("../../validate");
|
|
8
|
+
/** Validate a schema against a request using our validation middleware */
|
|
9
|
+
async function validate(request, schema) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
// Generate a validation chain using our middleware
|
|
12
|
+
const validationChain = (0, _validate.validate)(schema).flat();
|
|
13
|
+
if (!validationChain.length) resolve();
|
|
14
|
+
// Recursively go through each middleware by imitating the next function from express
|
|
15
|
+
let position = -1;
|
|
16
|
+
const next = error => {
|
|
17
|
+
if (error) reject(error);
|
|
18
|
+
position++;
|
|
19
|
+
if (position === validationChain.length) {
|
|
20
|
+
resolve();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
validationChain[position](request, undefined, next);
|
|
24
|
+
};
|
|
25
|
+
next();
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","names":["_validate","require","validate","request","schema","Promise","resolve","reject","validationChain","validateMiddleware","flat","length","position","next","error","undefined"],"sources":["../../../../src/middleware/multiPartFileUploader/validate/validate.ts"],"sourcesContent":["import { Request } from 'express';\nimport { Schema } from 'express-validator';\nimport { validate as validateMiddleware } from 'middleware/validate';\n\n/** Validate a schema against a request using our validation middleware */\nexport async function validate(\n request: Request,\n schema: Schema\n): Promise<void> {\n return new Promise((resolve, reject) => {\n // Generate a validation chain using our middleware\n const validationChain = validateMiddleware(schema).flat();\n if (!validationChain.length) resolve();\n // Recursively go through each middleware by imitating the next function from express\n let position = -1;\n const next = (error?: unknown): void => {\n if (error) reject(error);\n position++;\n if (position === validationChain.length) {\n resolve();\n return;\n }\n validationChain[position](request, undefined, next);\n };\n next();\n });\n}\n"],"mappings":";;;;;;AAEA,IAAAA,SAAA,GAAAC,OAAA;AAEA;AACO,eAAeC,QAAQA,CAC5BC,OAAgB,EAChBC,MAAc,EACC;EACf,OAAO,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;IACtC;IACA,MAAMC,eAAe,GAAG,IAAAC,kBAAkB,EAACL,MAAM,CAAC,CAACM,IAAI,CAAC,CAAC;IACzD,IAAI,CAACF,eAAe,CAACG,MAAM,EAAEL,OAAO,CAAC,CAAC;IACtC;IACA,IAAIM,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAMC,IAAI,GAAIC,KAAe,IAAW;MACtC,IAAIA,KAAK,EAAEP,MAAM,CAACO,KAAK,CAAC;MACxBF,QAAQ,EAAE;MACV,IAAIA,QAAQ,KAAKJ,eAAe,CAACG,MAAM,EAAE;QACvCL,OAAO,CAAC,CAAC;QACT;MACF;MACAE,eAAe,CAACI,QAAQ,CAAC,CAACT,OAAO,EAAEY,SAAS,EAAEF,IAAI,CAAC;IACrD,CAAC;IACDA,IAAI,CAAC,CAAC;EACR,CAAC,CAAC;AACJ","ignoreList":[]}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -102,6 +102,17 @@ Object.keys(_hmac).forEach(function (key) {
|
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
|
+
var _tlsConfig = require("./tlsConfig");
|
|
106
|
+
Object.keys(_tlsConfig).forEach(function (key) {
|
|
107
|
+
if (key === "default" || key === "__esModule") return;
|
|
108
|
+
if (key in exports && exports[key] === _tlsConfig[key]) return;
|
|
109
|
+
Object.defineProperty(exports, key, {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function () {
|
|
112
|
+
return _tlsConfig[key];
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
105
116
|
var _createHttpServer = require("./createHttpServer");
|
|
106
117
|
Object.keys(_createHttpServer).forEach(function (key) {
|
|
107
118
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -124,17 +135,6 @@ Object.keys(_request).forEach(function (key) {
|
|
|
124
135
|
}
|
|
125
136
|
});
|
|
126
137
|
});
|
|
127
|
-
var _tlsConfig = require("./tlsConfig");
|
|
128
|
-
Object.keys(_tlsConfig).forEach(function (key) {
|
|
129
|
-
if (key === "default" || key === "__esModule") return;
|
|
130
|
-
if (key in exports && exports[key] === _tlsConfig[key]) return;
|
|
131
|
-
Object.defineProperty(exports, key, {
|
|
132
|
-
enumerable: true,
|
|
133
|
-
get: function () {
|
|
134
|
-
return _tlsConfig[key];
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
138
|
var _tlsRequest = require("./tlsRequest");
|
|
139
139
|
Object.keys(_tlsRequest).forEach(function (key) {
|
|
140
140
|
if (key === "default" || key === "__esModule") return;
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_report","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_filter","_semverCompare","_dbMigration","_checkEnvironment","_envAssert","_createSortedObject","_jwt","_hmac","
|
|
1
|
+
{"version":3,"file":"index.js","names":["_report","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_filter","_semverCompare","_dbMigration","_checkEnvironment","_envAssert","_createSortedObject","_jwt","_hmac","_tlsConfig","_createHttpServer","_request","_tlsRequest","_sendPush","_sendEmail","_trimPathSlash","_geminiFileUpload"],"sources":["../../src/utils/index.ts"],"sourcesContent":["// general\nexport * from './report';\nexport * from './filter';\nexport * from './semverCompare';\nexport * from './dbMigration';\n\n// env\nexport * from './checkEnvironment';\nexport * from './envAssert';\n\n// auth\nexport * from './createSortedObject';\nexport * from './jwt';\nexport * from './hmac';\nexport * from './tlsConfig';\n\n// Networking\nexport * from './createHttpServer';\nexport * from './request';\nexport * from './tlsConfig';\nexport * from './tlsRequest';\nexport * from './sendPush';\nexport * from './sendEmail';\n\n// String manipulation\nexport * from './trimPathSlash';\n\n// File Upload\nexport * from './geminiFileUpload';\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.
|
|
3
|
+
"version": "1.3.1",
|
|
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": {
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"backend-test-tools": "^1.0.7",
|
|
49
49
|
"body-parser": "^1.20.3",
|
|
50
50
|
"busboy": "^1.6.0",
|
|
51
|
+
"bytes": "^3.1.2",
|
|
51
52
|
"callsite": "^1.0.0",
|
|
52
53
|
"cors": "^2.8.5",
|
|
53
54
|
"device": "^0.2.0",
|
|
@@ -104,6 +105,7 @@
|
|
|
104
105
|
"@faker-js/faker": "^9.3.0",
|
|
105
106
|
"@google-cloud/precise-date": "^4.0.0",
|
|
106
107
|
"@types/busboy": "^1.5.4",
|
|
108
|
+
"@types/bytes": "^3.1.5",
|
|
107
109
|
"@types/callsite": "^1.0.34",
|
|
108
110
|
"@types/chai": "^5.0.1",
|
|
109
111
|
"@types/chai-as-promised": "^8.0.1",
|
|
@@ -24,8 +24,14 @@ import {
|
|
|
24
24
|
EndpointHandler
|
|
25
25
|
} from './Endpoint.types';
|
|
26
26
|
import { LogSeverity } from 'const';
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
validate,
|
|
29
|
+
fileUploader,
|
|
30
|
+
requestMetrics,
|
|
31
|
+
multiPartFileUploader
|
|
32
|
+
} from 'middleware';
|
|
28
33
|
import { FileUploaderConfig } from 'middleware/fileUploader';
|
|
34
|
+
import { MultiPartFileUploaderConfig } from 'middleware/multiPartFileUploader';
|
|
29
35
|
import { reportDebug, reportError, reportInfo } from 'utils/report';
|
|
30
36
|
|
|
31
37
|
const namespace = 'engine:Endpoint';
|
|
@@ -48,6 +54,8 @@ export class Endpoint<T extends EndpointAuthType> {
|
|
|
48
54
|
private authParams?: EndpointAuthParams<T>;
|
|
49
55
|
/** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
50
56
|
private files?: Array<FileUploaderConfig>;
|
|
57
|
+
/** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
58
|
+
private multiPartFile?: MultiPartFileUploaderConfig;
|
|
51
59
|
/** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
|
|
52
60
|
private middleware?: Array<Middleware<T>>;
|
|
53
61
|
/** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
|
|
@@ -63,7 +71,9 @@ export class Endpoint<T extends EndpointAuthType> {
|
|
|
63
71
|
path: config.path,
|
|
64
72
|
authType: config.authType,
|
|
65
73
|
authParams: config.authParams,
|
|
66
|
-
file: config.file
|
|
74
|
+
file: config.file,
|
|
75
|
+
files: config.files,
|
|
76
|
+
multiPartFile: config.multiPartFile
|
|
67
77
|
}
|
|
68
78
|
});
|
|
69
79
|
|
|
@@ -113,10 +123,19 @@ export class Endpoint<T extends EndpointAuthType> {
|
|
|
113
123
|
// Register file upload
|
|
114
124
|
// Validation is included in the file upload process as this uses multipart/form-data
|
|
115
125
|
middlewareChain.push(fileUploader(this.files, this.validator));
|
|
116
|
-
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.multiPartFile) {
|
|
129
|
+
middlewareChain.push(
|
|
130
|
+
multiPartFileUploader(this.multiPartFile, this.validator)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!this.files && !this.multiPartFile) {
|
|
117
135
|
// Register validator for regular cases
|
|
118
136
|
middlewareChain.push(validate(this.validator));
|
|
119
137
|
}
|
|
138
|
+
|
|
120
139
|
// Register additional middleware
|
|
121
140
|
if (this.middleware) {
|
|
122
141
|
middlewareChain.push(...this.middleware);
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
authStatic,
|
|
18
18
|
FileUploaderConfig
|
|
19
19
|
} from 'middleware';
|
|
20
|
+
import { MultiPartFileUploaderConfig } from 'middleware/multiPartFileUploader/multiPartFileUploader.types';
|
|
20
21
|
|
|
21
22
|
export enum EndpointMethod {
|
|
22
23
|
GET = 'get',
|
|
@@ -129,6 +130,8 @@ export interface EndpointOptions<T extends EndpointAuthType> {
|
|
|
129
130
|
file?: FileUploaderConfig;
|
|
130
131
|
/** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
131
132
|
files?: Array<FileUploaderConfig>;
|
|
133
|
+
/** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
|
|
134
|
+
multiPartFile?: MultiPartFileUploaderConfig;
|
|
132
135
|
/** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
|
|
133
136
|
middleware?: MiddlewareChainElement<T>;
|
|
134
137
|
/** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
|
|
@@ -348,11 +348,9 @@ export class Server {
|
|
|
348
348
|
private watchTlsCaFileChange(): void {
|
|
349
349
|
[
|
|
350
350
|
'TLS_REQUEST_KEY',
|
|
351
|
-
'TLS_REQUEST_KEY_PASSPHRASE',
|
|
352
351
|
'TLS_REQUEST_CERT',
|
|
353
352
|
'TLS_REQUEST_CA',
|
|
354
353
|
'TLS_SERVER_KEY',
|
|
355
|
-
'TLS_SERVER_KEY_PASSPHRASE',
|
|
356
354
|
'TLS_SERVER_CERT',
|
|
357
355
|
'TLS_CA'
|
|
358
356
|
].forEach((key) => {
|
|
@@ -5,6 +5,8 @@ import { reportDebug } from 'utils/report';
|
|
|
5
5
|
import multer from 'multer';
|
|
6
6
|
import { FileUploaderConfig } from './fileUploader.types';
|
|
7
7
|
import { validate } from './validate';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import bytes from 'bytes';
|
|
8
10
|
|
|
9
11
|
const namespace = 'engine:middleware:fileUploader';
|
|
10
12
|
|
|
@@ -32,7 +34,7 @@ export function fileUploader(
|
|
|
32
34
|
const storage = multer.memoryStorage();
|
|
33
35
|
const upload = multer({
|
|
34
36
|
storage,
|
|
35
|
-
limits: { fileSize:
|
|
37
|
+
limits: { fileSize: 32 * 1024 * 1024 } // Default global limit (10MB)
|
|
36
38
|
}).any();
|
|
37
39
|
|
|
38
40
|
upload(request, response, async (err) => {
|
|
@@ -97,7 +99,54 @@ export function fileUploader(
|
|
|
97
99
|
);
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
// Validate each uploaded file
|
|
103
|
+
for (const file of uploadedFiles) {
|
|
104
|
+
const fileOption = filesOptions.find(
|
|
105
|
+
(option) => option.key === file.fieldname
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (!fileOption) continue;
|
|
109
|
+
|
|
110
|
+
// MIME Type Validation
|
|
111
|
+
if (
|
|
112
|
+
fileOption.mimeTypes &&
|
|
113
|
+
!fileOption.mimeTypes.includes(file.mimetype)
|
|
114
|
+
) {
|
|
115
|
+
return next(
|
|
116
|
+
new WebError({
|
|
117
|
+
statusCode: 400,
|
|
118
|
+
errorCode: 'invalid-mime-type',
|
|
119
|
+
message: `Invalid file type for ${file.fieldname}`,
|
|
120
|
+
data: { expected: fileOption.mimeTypes, received: file.mimetype }
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Max File Size Validation
|
|
126
|
+
if (fileOption.maxSize) {
|
|
127
|
+
const maxSizeInBytes = bytes(fileOption.maxSize);
|
|
128
|
+
if (maxSizeInBytes && file.size > maxSizeInBytes) {
|
|
129
|
+
return next(
|
|
130
|
+
new WebError({
|
|
131
|
+
statusCode: 400,
|
|
132
|
+
errorCode: 'file-too-large',
|
|
133
|
+
message: `File ${file.originalname} exceeds the allowed size`,
|
|
134
|
+
data: { maxSize: fileOption.maxSize, receivedSize: file.size }
|
|
135
|
+
})
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// No Extension Handling
|
|
141
|
+
if (fileOption.noExtension) {
|
|
142
|
+
file.originalname = path.basename(
|
|
143
|
+
file.originalname,
|
|
144
|
+
path.extname(file.originalname)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
request.files = uploadedFiles;
|
|
101
150
|
|
|
102
151
|
next();
|
|
103
152
|
});
|