node-server-engine 1.2.9 → 1.3.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.
Files changed (33) hide show
  1. package/.env.example +4 -1
  2. package/README.md +128 -107
  3. package/dist/entities/Endpoint/Endpoint.d.ts +2 -0
  4. package/dist/entities/Endpoint/Endpoint.js +11 -2
  5. package/dist/entities/Endpoint/Endpoint.js.map +1 -1
  6. package/dist/entities/Endpoint/Endpoint.types.d.ts +3 -0
  7. package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
  8. package/dist/middleware/fileUploader/fileUploader.js +45 -3
  9. package/dist/middleware/fileUploader/fileUploader.js.map +1 -1
  10. package/dist/middleware/multiPartFileUploader/index.d.ts +1 -0
  11. package/dist/middleware/multiPartFileUploader/index.js +11 -0
  12. package/dist/middleware/multiPartFileUploader/index.js.map +1 -1
  13. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.d.ts +4 -3
  14. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js +169 -105
  15. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js.map +1 -1
  16. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.d.ts +20 -0
  17. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.js +2 -0
  18. package/dist/middleware/multiPartFileUploader/multiPartFileUploader.types.js.map +1 -0
  19. package/dist/middleware/multiPartFileUploader/validate/index.d.ts +1 -0
  20. package/dist/middleware/multiPartFileUploader/validate/index.js +17 -0
  21. package/dist/middleware/multiPartFileUploader/validate/index.js.map +1 -0
  22. package/dist/middleware/multiPartFileUploader/validate/validate.d.ts +4 -0
  23. package/dist/middleware/multiPartFileUploader/validate/validate.js +28 -0
  24. package/dist/middleware/multiPartFileUploader/validate/validate.js.map +1 -0
  25. package/package.json +3 -1
  26. package/src/entities/Endpoint/Endpoint.ts +22 -3
  27. package/src/entities/Endpoint/Endpoint.types.ts +3 -0
  28. package/src/middleware/fileUploader/fileUploader.ts +51 -2
  29. package/src/middleware/multiPartFileUploader/index.ts +1 -0
  30. package/src/middleware/multiPartFileUploader/multiPartFileUploader.ts +193 -128
  31. package/src/middleware/multiPartFileUploader/multiPartFileUploader.types.ts +23 -0
  32. package/src/middleware/multiPartFileUploader/validate/index.ts +1 -0
  33. package/src/middleware/multiPartFileUploader/validate/validate.ts +27 -0
package/.env.example CHANGED
@@ -167,4 +167,7 @@ SMTP_PORT=587
167
167
  SMTP_USER=your-email@example.com
168
168
 
169
169
  # SMTP authentication password (your email password or app password)
170
- SMTP_PASS=your-email-password
170
+ SMTP_PASS=your-email-password
171
+
172
+
173
+ FILE_STORAGE_FOLDER=./uploads
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Framework used to develop Node backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.
4
4
 
5
- - [Node Server Engine](#Node-server-engine)
5
+ - [Node Server Engine](#node-server-engine)
6
6
  - [Install](#install)
7
7
  - [Entities](#entities)
8
8
  - [Server](#server)
@@ -12,6 +12,18 @@ Framework used to develop Node backend services. This package ships with a lot o
12
12
  - [Methods](#methods)
13
13
  - [Authentication](#authentication)
14
14
  - [File Upload Middleware](#file-upload-middleware)
15
+ - [Usage](#usage)
16
+ - [Example](#example)
17
+ - [Middleware Output](#middleware-output)
18
+ - [Features](#features)
19
+ - [Multipart File Upload Middleware](#multipart-file-upload-middleware)
20
+ - [Usage](#usage-1)
21
+ - [Configuration Options](#configuration-options)
22
+ - [Expected Request Format](#expected-request-format)
23
+ - [Middleware Output](#middleware-output-1)
24
+ - [When all chunks are not yet received, req.multipartFile has the below JSON:](#when-all-chunks-are-not-yet-received-reqmultipartfile-has-the-below-json)
25
+ - [When the upload is complete, req.multipartFile has the below JSON:](#when-the-upload-is-complete-reqmultipartfile-has-the-below-json)
26
+ - [Example](#example-1)
15
27
  - [Socket Client](#socket-client)
16
28
  - [Socket Client Options](#socket-client-options)
17
29
  - [Properties](#properties)
@@ -35,15 +47,22 @@ Framework used to develop Node backend services. This package ships with a lot o
35
47
  - [Schemas and Responses](#schemas-and-responses)
36
48
  - [User Resolver](#user-resolver)
37
49
  - [Gemini File Upload](#gemini-file-upload)
38
- - [Multipart File Uploader](#multipart-file-uploader)
39
- - [checkPermission](#check-permission-middleware)
50
+ - [Check Permission Middleware](#check-permission-middleware)
40
51
  - [Utilities](#utilities)
41
52
  - [Request](#request)
42
53
  - [TLS Request](#tls-request)
43
54
  - [TLS Config](#tls-config)
44
55
  - [Send Push Notification](#send-push-notification)
45
56
  - [Send Email](#send-email)
46
- - [Gemini File Upload](#gemini-file-upload)
57
+ - [Parameters](#parameters)
58
+ - [Return Status](#return-status)
59
+ - [Gemini File Upload](#gemini-file-upload-1)
60
+ - [Parameters](#parameters-1)
61
+ - [Response](#response)
62
+ - [**Success Response**](#success-response)
63
+ - [**Failure Response**](#failure-response)
64
+ - [Return Fields](#return-fields)
65
+ - [Error Handling](#error-handling)
47
66
  - [Filter](#filter)
48
67
  - [Database Migration](#database-migration)
49
68
  - [Environment Variables Verification](#environment-variables-verification)
@@ -203,11 +222,11 @@ The server engine exposes an enumeration for auth types.
203
222
 
204
223
  <!-- markdownlint-enable MD033 -->
205
224
 
206
- ### File Upload Middleware
225
+ #### File Upload Middleware
207
226
 
208
227
  This middleware handles multipart file uploads in an Express application. It processes files in memory, validates them based on configuration options, and ensures that required files are uploaded.
209
228
 
210
- ## Usage
229
+ ##### Usage
211
230
 
212
231
  The request must be made using `multipart/form-data`. The uploaded files will be available in `req.files`.
213
232
 
@@ -221,7 +240,7 @@ The following settings can be used on each object the Endpoint's `options.files`
221
240
  | required | boolean | Will fail the request and not store the files if this one is missing | false |
222
241
  | noExtension | boolean | Store the file with no extension | false |
223
242
 
224
- ## Example
243
+ ##### Example
225
244
 
226
245
  ```typescript
227
246
  import { body } from 'express-validator';
@@ -243,7 +262,30 @@ new Endpoint({
243
262
  });
244
263
  ```
245
264
 
246
- ## Features
265
+ ##### Middleware Output
266
+
267
+ The middleware adds a `files` object to the `req` object, which contains information about the uploaded file.
268
+
269
+ ```json
270
+ [
271
+ {
272
+ "fieldname": "avatar",
273
+ "originalname": "profile.png",
274
+ "mimetype": "image/png",
275
+ "size": 204800,
276
+ "buffer":[]
277
+ },
278
+ {
279
+ "fieldname": "document",
280
+ "originalname": "resume.pdf",
281
+ "mimetype": "application/pdf",
282
+ "size": 512000,
283
+ "buffer":[]
284
+ }
285
+ ]
286
+ ```
287
+
288
+ ##### Features
247
289
 
248
290
  - Supports multiple file uploads.
249
291
  - Validates file types and sizes.
@@ -254,6 +296,82 @@ This middleware simplifies file handling in Express, making it easy to manage up
254
296
 
255
297
  ---
256
298
 
299
+ #### Multipart File Upload Middleware
300
+
301
+ This middleware enables chunked file uploads in an Express application. It allows uploading large files by splitting them into smaller chunks, validating them, and merging them once all parts are received.
302
+
303
+ ##### Usage
304
+
305
+ The request must be made using `multipart/form-data`. The uploaded chunks are processed in memory before being stored in temporary directories. Once all chunks are uploaded, they are merged into a single file.
306
+
307
+ ##### Configuration Options
308
+
309
+ The following settings can be used when configuring file uploads:
310
+
311
+ | Property | Type | Description | Default |
312
+ | -------- | ------- | --------------------------------------------------- | -------- |
313
+ | maxSize | string | Maximum allowed size for each chunk (e.g., `"5MB"`) | No limit |
314
+ | required | boolean | Whether the file is mandatory for the request | `false` |
315
+
316
+ ##### Expected Request Format
317
+
318
+ The client must send the following fields in the `multipart/form-data` request:
319
+
320
+ | Field | Type | Description |
321
+ | ------------- | ------ | ---------------------------------------- |
322
+ | `file` | File | The chunked file data |
323
+ | `filename` | String | Name of the original file |
324
+ | `uniqueID` | String | Unique identifier for the upload session |
325
+ | `chunkIndex` | Number | Current chunk number (0-based index) |
326
+ | `totalChunks` | Number | Total number of chunks for the file |
327
+
328
+ ##### Middleware Output
329
+
330
+ The middleware adds a `multipartFile` object to the `req` object, which contains information about the uploaded file.
331
+
332
+ ##### When all chunks are not yet received, req.multipartFile has the below JSON:
333
+
334
+ ```json
335
+ {
336
+ "isPending": true,
337
+ "originalname": "example.pdf",
338
+ "uniqueID": "abc123",
339
+ "chunkIndex": 2,
340
+ "totalChunks": 5
341
+ }
342
+ ```
343
+
344
+ ##### When the upload is complete, req.multipartFile has the below JSON:
345
+
346
+ ```json
347
+ {
348
+ "isPending": false,
349
+ "originalname": "example.pdf",
350
+ "uniqueID": "abc123",
351
+ "filePath": "/uploads/completed_files/abc123_example.pdf"
352
+ }
353
+ ```
354
+
355
+ ##### Example
356
+
357
+ ```typescript
358
+ import { body } from 'express-validator';
359
+ import { Endpoint, middleware, AuthType, Method } from 'node-server-engine';
360
+
361
+ const fileConfig = { maxSize: '10MB', required: true };
362
+
363
+ new Endpoint({
364
+ path: '/upload',
365
+ method: Method.POST,
366
+ authType: AuthType.JWT,
367
+ multipartFile: fileConfig,
368
+ handler: (req, res) => {
369
+ console.log(req.multipartFile);
370
+ }
371
+ });
372
+ ```
373
+ ---
374
+
257
375
  ### Socket Client
258
376
 
259
377
  The socket server start if the [Server](#server)'s webSocket option is not undefined.
@@ -704,7 +822,7 @@ new Endpoint({
704
822
 
705
823
  ---
706
824
 
707
- #### Gemini File Upload
825
+ ### Gemini File Upload
708
826
 
709
827
  An endpoint can upload a file to a google gemini AI
710
828
 
@@ -716,104 +834,7 @@ The file's data will be available at `req.body.fileUri req.body.mimeType req.bo
716
834
 
717
835
  ---
718
836
 
719
- #### Multipart File Uploader
720
-
721
- This middleware handles multipart file uploads by accepting file chunks, storing them temporarily, and merging them once all chunks are uploaded.
722
-
723
- ## Usage
724
-
725
- The request must be made using `multipart/form-data`.
726
- The file should be uploaded under the key `file`.
727
-
728
- Once the upload is complete, the following data will be available in `req.body.uploadDetails`:
729
-
730
- - **status**: `"pending"` (if chunk upload is in progress) or `"completed"` (if file is fully uploaded and merged).
731
- - **message**: Status message.
732
- - **details**:
733
- - `filename`: Original filename.
734
- - `uniqueID`: Unique identifier for the upload session.
735
- - `chunkIndex`: The current chunk index (if upload is still in progress).
736
- - `totalChunks`: Total number of chunks for the file (if upload is still in progress).
737
-
738
- ## Request Format
739
-
740
- ### **Endpoint:**
741
-
742
- ```http
743
- POST /upload
744
- ```
745
-
746
- ### **Headers:**
747
-
748
- ```http
749
- Content-Type: multipart/form-data
750
- ```
751
-
752
- ### **Form Data:**
753
-
754
- | Key | Type | Description |
755
- | ------------- | ------ | ------------------------------------------------- |
756
- | `file` | File | The chunk of the file being uploaded |
757
- | `filename` | String | The original filename |
758
- | `uniqueID` | String | A unique identifier for the file upload session |
759
- | `totalChunks` | Number | The total number of chunks the file is split into |
760
- | `chunkIndex` | Number | The index of the current chunk being uploaded |
761
-
762
- ## Response Format
763
-
764
- ### **If chunk upload is successful but not completed:**
765
-
766
- ```json
767
- {
768
- "status": "pending",
769
- "message": "Chunk uploaded successfully",
770
- "details": {
771
- "filename": "example.pdf",
772
- "uniqueID": "123456",
773
- "chunkIndex": 2,
774
- "totalChunks": 5
775
- }
776
- }
777
- ```
778
-
779
- ### **If all chunks are uploaded and merged successfully:**
780
-
781
- ```json
782
- {
783
- "status": "completed",
784
- "message": "File uploaded and merged successfully",
785
- "details": {
786
- "filename": "example.pdf",
787
- "uniqueID": "123456"
788
- }
789
- }
790
- ```
791
-
792
- ## Error Handling
793
-
794
- If an error occurs (e.g., missing fields, failed write operations), the middleware will return an error response with details.
795
-
796
- Example:
797
-
798
- ```json
799
- {
800
- "status": "failed",
801
- "message": "Missing required fields",
802
- "details": {
803
- "filename": null,
804
- "totalChunks": null,
805
- "chunkIndex": null,
806
- "uniqueID": null,
807
- "receivedChunk": false
808
- }
809
- }
810
- ```
811
-
812
- This middleware ensures smooth handling of large file uploads by splitting them into smaller chunks and merging them once all chunks are received. 🚀
813
-
814
- ---
815
-
816
- #### Check Permission Middleware
837
+ ### Check Permission Middleware
817
838
 
818
839
  /!\ **Must be used in combination with AuthType.JWT**
819
840
 
@@ -18,6 +18,8 @@ export declare class Endpoint<T extends EndpointAuthType> {
18
18
  private authParams?;
19
19
  /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
20
20
  private files?;
21
+ /** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
22
+ private multiPartFile?;
21
23
  /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
22
24
  private middleware?;
23
25
  /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
@@ -36,6 +36,8 @@ let Endpoint = exports.Endpoint = /*#__PURE__*/function () {
36
36
  (0, _defineProperty2.default)(this, "authParams", void 0);
37
37
  /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
38
38
  (0, _defineProperty2.default)(this, "files", void 0);
39
+ /** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
40
+ (0, _defineProperty2.default)(this, "multiPartFile", void 0);
39
41
  /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
40
42
  (0, _defineProperty2.default)(this, "middleware", void 0);
41
43
  /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
@@ -48,7 +50,9 @@ let Endpoint = exports.Endpoint = /*#__PURE__*/function () {
48
50
  path: config.path,
49
51
  authType: config.authType,
50
52
  authParams: config.authParams,
51
- file: config.file
53
+ file: config.file,
54
+ files: config.files,
55
+ multiPartFile: config.multiPartFile
52
56
  }
53
57
  });
54
58
  if (typeof config.path !== 'string') throw new _EngineError.EngineError({
@@ -92,10 +96,15 @@ let Endpoint = exports.Endpoint = /*#__PURE__*/function () {
92
96
  // Register file upload
93
97
  // Validation is included in the file upload process as this uses multipart/form-data
94
98
  middlewareChain.push((0, _middleware.fileUploader)(this.files, this.validator));
95
- } else {
99
+ }
100
+ if (this.multiPartFile) {
101
+ middlewareChain.push((0, _middleware.multiPartFileUploader)(this.multiPartFile, this.validator));
102
+ }
103
+ if (!this.files && !this.multiPartFile) {
96
104
  // Register validator for regular cases
97
105
  middlewareChain.push((0, _middleware.validate)(this.validator));
98
106
  }
107
+
99
108
  // Register additional middleware
100
109
  if (this.middleware) {
101
110
  middlewareChain.push(...this.middleware);
@@ -1 +1 @@
1
- {"version":3,"file":"Endpoint.js","names":["_EngineError","require","_Endpoint2","_const","_middleware","_report","namespace","Endpoint","exports","config","_classCallCheck2","default","_defineProperty2","reportDebug","message","method","path","data","authType","authParams","file","EngineError","EndpointMethods","includes","handler","EndpointAuthTypes","validator","files","middleware","Array","errorMiddleware","_createClass2","key","value","register","app","middlewareChain","requestMetrics","push","getAuthMiddleware","fileUploader","validate","safeMiddlewareChain","catchExceptionForExpress","flat","map","req","res","next","err","catch","error","reportError","type","EndpointAuthHandlers","reportInfo","severity","LogSeverity","WARNING","request","response","acceptInvalid"],"sources":["../../../src/entities/Endpoint/Endpoint.ts"],"sourcesContent":["import {\n RequestHandler,\n ErrorRequestHandler,\n Application,\n Request,\n Response,\n NextFunction\n} from 'express';\nimport { Schema } from 'express-validator';\nimport { EngineError } from '../EngineError';\nimport {\n EndpointOptions,\n EndpointAuthType,\n EndpointAuthTypes,\n EndpointMethod,\n EndpointMethods,\n EndpointAuthParams,\n Middleware,\n MiddlewareChainElement,\n SafeMiddleWareChain,\n EndpointAuthHandlers,\n EndpointAuthHandler,\n EndpointRequestType,\n EndpointHandler\n} from './Endpoint.types';\nimport { LogSeverity } from 'const';\nimport { validate, fileUploader, requestMetrics } from 'middleware';\nimport { FileUploaderConfig } from 'middleware/fileUploader';\nimport { reportDebug, reportError, reportInfo } from 'utils/report';\n\nconst namespace = 'engine:Endpoint';\n\n/**\n * Object representing a REST endpoint served by server\n */\nexport class Endpoint<T extends EndpointAuthType> {\n /** Path at which the endpoint is reachable */\n public readonly path: string;\n /** HTTP method of the endpoint */\n public readonly method: EndpointMethod;\n /** Authentication system required by this endpoint */\n public readonly authType: T;\n /** Function handling the endpoint's business logic */\n private handler: EndpointHandler<T>;\n /** Validation schema that the request must pass before reaching the handler */\n private validator: Schema;\n /** Authentication related options for this endpoint */\n private authParams?: EndpointAuthParams<T>;\n /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */\n private files?: Array<FileUploaderConfig>;\n /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */\n private middleware?: Array<Middleware<T>>;\n /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */\n private errorMiddleware?: Array<ErrorRequestHandler>;\n\n /** Create a REST endpoint */\n public constructor(config: EndpointOptions<T>) {\n reportDebug({\n namespace,\n message: `Creating Endpoint [${config.method} - ${config.path}]`,\n data: {\n method: config.method,\n path: config.path,\n authType: config.authType,\n authParams: config.authParams,\n file: config.file\n }\n });\n\n if (typeof config.path !== 'string')\n throw new EngineError({\n message: 'Endpoint path was not declared as a string'\n });\n this.path = config.path;\n\n if (!EndpointMethods.includes(config.method))\n throw new EngineError({\n message: 'Endpoint method is not a valid HTTP method'\n });\n this.method = config.method;\n\n if (typeof config.handler !== 'function')\n throw new EngineError({ message: 'Endpoint handler is not a function' });\n this.handler = config.handler;\n\n if (!EndpointAuthTypes.includes(config.authType))\n throw new EngineError({ message: 'Endpoint auth type is not valid' });\n this.authType = config.authType;\n\n this.validator = config.validator;\n this.authParams = config.authParams;\n this.files = config.file ? [config.file] : config.files;\n\n // Middleware can both be function or arrays\n if (typeof config.middleware === 'function')\n this.middleware = [config.middleware];\n if (config.middleware instanceof Array) this.middleware = config.middleware;\n if (typeof config.errorMiddleware === 'function')\n this.errorMiddleware = [config.errorMiddleware];\n if (config.errorMiddleware instanceof Array)\n this.errorMiddleware = config.errorMiddleware;\n }\n\n /**\n * Register the endpoint to a react app\n */\n public register(app: Application): void {\n // First initialize the handling calculation\n const middlewareChain: Array<MiddlewareChainElement<T>> = [requestMetrics];\n // Register auth middleware\n middlewareChain.push(...this.getAuthMiddleware(this.authType));\n if (this.files) {\n // Register file upload\n // Validation is included in the file upload process as this uses multipart/form-data\n middlewareChain.push(fileUploader(this.files, this.validator));\n } else {\n // Register validator for regular cases\n middlewareChain.push(validate(this.validator));\n }\n // Register additional middleware\n if (this.middleware) {\n middlewareChain.push(...this.middleware);\n }\n // Register handler\n middlewareChain.push(this.handler);\n // Wrap middleware to await any async execution and catch any errors thrown\n const safeMiddlewareChain: SafeMiddleWareChain =\n this.catchExceptionForExpress(middlewareChain);\n // Register error middleware\n if (this.errorMiddleware) {\n safeMiddlewareChain.push(...this.errorMiddleware);\n }\n app[this.method](\n this.path,\n ...(safeMiddlewareChain.flat() as Array<\n RequestHandler | ErrorRequestHandler\n >)\n );\n }\n\n /**\n * Catch exceptions thrown inside of middleware and pass them properly to express\n */\n private catchExceptionForExpress(\n middlewareChain: Array<MiddlewareChainElement<T>>\n ): SafeMiddleWareChain {\n return middlewareChain.map((middleware) => {\n if (middleware instanceof Array) {\n return this.catchExceptionForExpress(middleware);\n }\n if (typeof middleware === 'function') {\n return (req: Request, res: Response, next: NextFunction) => {\n (async (): Promise<void> => {\n try {\n await middleware(req as EndpointRequestType[T], res, next);\n } catch (err) {\n next(err);\n }\n })().catch((error) => {\n reportError(error);\n });\n };\n }\n throw new EngineError({\n message: 'Middleware is not a function nor an array',\n data: { type: typeof middleware }\n });\n });\n }\n\n /**\n * Get the authentication middleware for a given type of authentication\n */\n private getAuthMiddleware(authType: EndpointAuthType): Array<RequestHandler> {\n const middlewareChain: Array<RequestHandler> = [];\n\n const handler = EndpointAuthHandlers[authType] as EndpointAuthHandler<T>;\n if (!handler) {\n reportInfo({\n severity: LogSeverity.WARNING,\n message: `Endpoint \"${this.method} - ${this.path}\" was declared with no authentication method`\n });\n return [];\n }\n\n const middleware = handler(this.authParams);\n\n middlewareChain.push(\n async (request: Request, response: Response, next: NextFunction) => {\n try {\n await middleware(request, response, next);\n } catch (error) {\n if (!this.authParams?.acceptInvalid) throw error;\n reportError(error);\n next();\n }\n }\n );\n\n return middlewareChain;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Endpoint.js","names":["_EngineError","require","_Endpoint2","_const","_middleware","_report","namespace","Endpoint","exports","config","_classCallCheck2","default","_defineProperty2","reportDebug","message","method","path","data","authType","authParams","file","files","multiPartFile","EngineError","EndpointMethods","includes","handler","EndpointAuthTypes","validator","middleware","Array","errorMiddleware","_createClass2","key","value","register","app","middlewareChain","requestMetrics","push","getAuthMiddleware","fileUploader","multiPartFileUploader","validate","safeMiddlewareChain","catchExceptionForExpress","flat","map","req","res","next","err","catch","error","reportError","type","EndpointAuthHandlers","reportInfo","severity","LogSeverity","WARNING","request","response","acceptInvalid"],"sources":["../../../src/entities/Endpoint/Endpoint.ts"],"sourcesContent":["import {\n RequestHandler,\n ErrorRequestHandler,\n Application,\n Request,\n Response,\n NextFunction\n} from 'express';\nimport { Schema } from 'express-validator';\nimport { EngineError } from '../EngineError';\nimport {\n EndpointOptions,\n EndpointAuthType,\n EndpointAuthTypes,\n EndpointMethod,\n EndpointMethods,\n EndpointAuthParams,\n Middleware,\n MiddlewareChainElement,\n SafeMiddleWareChain,\n EndpointAuthHandlers,\n EndpointAuthHandler,\n EndpointRequestType,\n EndpointHandler\n} from './Endpoint.types';\nimport { LogSeverity } from 'const';\nimport {\n validate,\n fileUploader,\n requestMetrics,\n multiPartFileUploader\n} from 'middleware';\nimport { FileUploaderConfig } from 'middleware/fileUploader';\nimport { MultiPartFileUploaderConfig } from 'middleware/multiPartFileUploader';\nimport { reportDebug, reportError, reportInfo } from 'utils/report';\n\nconst namespace = 'engine:Endpoint';\n\n/**\n * Object representing a REST endpoint served by server\n */\nexport class Endpoint<T extends EndpointAuthType> {\n /** Path at which the endpoint is reachable */\n public readonly path: string;\n /** HTTP method of the endpoint */\n public readonly method: EndpointMethod;\n /** Authentication system required by this endpoint */\n public readonly authType: T;\n /** Function handling the endpoint's business logic */\n private handler: EndpointHandler<T>;\n /** Validation schema that the request must pass before reaching the handler */\n private validator: Schema;\n /** Authentication related options for this endpoint */\n private authParams?: EndpointAuthParams<T>;\n /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */\n private files?: Array<FileUploaderConfig>;\n /** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */\n private multiPartFile?: MultiPartFileUploaderConfig;\n /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */\n private middleware?: Array<Middleware<T>>;\n /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */\n private errorMiddleware?: Array<ErrorRequestHandler>;\n\n /** Create a REST endpoint */\n public constructor(config: EndpointOptions<T>) {\n reportDebug({\n namespace,\n message: `Creating Endpoint [${config.method} - ${config.path}]`,\n data: {\n method: config.method,\n path: config.path,\n authType: config.authType,\n authParams: config.authParams,\n file: config.file,\n files: config.files,\n multiPartFile: config.multiPartFile\n }\n });\n\n if (typeof config.path !== 'string')\n throw new EngineError({\n message: 'Endpoint path was not declared as a string'\n });\n this.path = config.path;\n\n if (!EndpointMethods.includes(config.method))\n throw new EngineError({\n message: 'Endpoint method is not a valid HTTP method'\n });\n this.method = config.method;\n\n if (typeof config.handler !== 'function')\n throw new EngineError({ message: 'Endpoint handler is not a function' });\n this.handler = config.handler;\n\n if (!EndpointAuthTypes.includes(config.authType))\n throw new EngineError({ message: 'Endpoint auth type is not valid' });\n this.authType = config.authType;\n\n this.validator = config.validator;\n this.authParams = config.authParams;\n this.files = config.file ? [config.file] : config.files;\n\n // Middleware can both be function or arrays\n if (typeof config.middleware === 'function')\n this.middleware = [config.middleware];\n if (config.middleware instanceof Array) this.middleware = config.middleware;\n if (typeof config.errorMiddleware === 'function')\n this.errorMiddleware = [config.errorMiddleware];\n if (config.errorMiddleware instanceof Array)\n this.errorMiddleware = config.errorMiddleware;\n }\n\n /**\n * Register the endpoint to a react app\n */\n public register(app: Application): void {\n // First initialize the handling calculation\n const middlewareChain: Array<MiddlewareChainElement<T>> = [requestMetrics];\n // Register auth middleware\n middlewareChain.push(...this.getAuthMiddleware(this.authType));\n if (this.files) {\n // Register file upload\n // Validation is included in the file upload process as this uses multipart/form-data\n middlewareChain.push(fileUploader(this.files, this.validator));\n }\n\n if (this.multiPartFile) {\n middlewareChain.push(\n multiPartFileUploader(this.multiPartFile, this.validator)\n );\n }\n\n if (!this.files && !this.multiPartFile) {\n // Register validator for regular cases\n middlewareChain.push(validate(this.validator));\n }\n\n // Register additional middleware\n if (this.middleware) {\n middlewareChain.push(...this.middleware);\n }\n // Register handler\n middlewareChain.push(this.handler);\n // Wrap middleware to await any async execution and catch any errors thrown\n const safeMiddlewareChain: SafeMiddleWareChain =\n this.catchExceptionForExpress(middlewareChain);\n // Register error middleware\n if (this.errorMiddleware) {\n safeMiddlewareChain.push(...this.errorMiddleware);\n }\n app[this.method](\n this.path,\n ...(safeMiddlewareChain.flat() as Array<\n RequestHandler | ErrorRequestHandler\n >)\n );\n }\n\n /**\n * Catch exceptions thrown inside of middleware and pass them properly to express\n */\n private catchExceptionForExpress(\n middlewareChain: Array<MiddlewareChainElement<T>>\n ): SafeMiddleWareChain {\n return middlewareChain.map((middleware) => {\n if (middleware instanceof Array) {\n return this.catchExceptionForExpress(middleware);\n }\n if (typeof middleware === 'function') {\n return (req: Request, res: Response, next: NextFunction) => {\n (async (): Promise<void> => {\n try {\n await middleware(req as EndpointRequestType[T], res, next);\n } catch (err) {\n next(err);\n }\n })().catch((error) => {\n reportError(error);\n });\n };\n }\n throw new EngineError({\n message: 'Middleware is not a function nor an array',\n data: { type: typeof middleware }\n });\n });\n }\n\n /**\n * Get the authentication middleware for a given type of authentication\n */\n private getAuthMiddleware(authType: EndpointAuthType): Array<RequestHandler> {\n const middlewareChain: Array<RequestHandler> = [];\n\n const handler = EndpointAuthHandlers[authType] as EndpointAuthHandler<T>;\n if (!handler) {\n reportInfo({\n severity: LogSeverity.WARNING,\n message: `Endpoint \"${this.method} - ${this.path}\" was declared with no authentication method`\n });\n return [];\n }\n\n const middleware = handler(this.authParams);\n\n middlewareChain.push(\n async (request: Request, response: Response, next: NextFunction) => {\n try {\n await middleware(request, response, next);\n } catch (error) {\n if (!this.authParams?.acceptInvalid) throw error;\n reportError(error);\n next();\n }\n }\n );\n\n return middlewareChain;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,6 +3,7 @@ import { ParamsDictionary } from 'express-serve-static-core';
3
3
  import { Schema } from 'express-validator';
4
4
  import { ParsedQs } from 'qs';
5
5
  import { authJwt, authHmac, authTls, authStatic, FileUploaderConfig } from '../../middleware';
6
+ import { MultiPartFileUploaderConfig } from '../../middleware/multiPartFileUploader/multiPartFileUploader.types';
6
7
  export declare enum EndpointMethod {
7
8
  GET = "get",
8
9
  POST = "post",
@@ -84,6 +85,8 @@ export interface EndpointOptions<T extends EndpointAuthType> {
84
85
  file?: FileUploaderConfig;
85
86
  /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */
86
87
  files?: Array<FileUploaderConfig>;
88
+ /** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */
89
+ multiPartFile?: MultiPartFileUploaderConfig;
87
90
  /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */
88
91
  middleware?: MiddlewareChainElement<T>;
89
92
  /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */
@@ -1 +1 @@
1
- {"version":3,"file":"Endpoint.types.js","names":["_middleware","require","EndpointMethod","exports","EndpointMethods","Object","values","EndpointAuthType","EndpointAuthTypes","EndpointAuthHandlers","NONE","undefined","JWT","authJwt","TLS","authTls","HMAC","authHmac","STATIC","authStatic"],"sources":["../../../src/entities/Endpoint/Endpoint.types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ErrorRequestHandler,\n Request,\n Response,\n NextFunction,\n RequestHandler\n} from 'express';\nimport { ParamsDictionary } from 'express-serve-static-core';\nimport { Schema } from 'express-validator';\nimport { ParsedQs } from 'qs';\n\nimport {\n authJwt,\n authHmac,\n authTls,\n authStatic,\n FileUploaderConfig\n} from 'middleware';\n\nexport enum EndpointMethod {\n GET = 'get',\n POST = 'post',\n PUT = 'put',\n PATCH = 'patch',\n DELETE = 'delete',\n HEAD = 'head',\n ALL = 'all'\n}\n\nexport const EndpointMethods = Object.values(EndpointMethod);\n\nexport enum EndpointAuthType {\n NONE = 'none',\n JWT = 'jwt',\n TLS = 'tls',\n HMAC = 'hmac',\n STATIC = 'static'\n}\n\nexport const EndpointAuthTypes = Object.values(EndpointAuthType);\n\nexport type Middleware<T extends EndpointAuthType> = (\n request: EndpointRequestType[T],\n response: Response,\n next: NextFunction\n) => unknown | Promise<unknown>;\n\nexport type MiddlewareChainElement<T extends EndpointAuthType> =\n | Array<Middleware<T>>\n | Middleware<T>\n | any;\n\n/** Auth related parameters used with HMAC authentication */\ninterface EndpointAuthHmacParams {\n /** [HMAC] Secret used for signature */\n secret?: string;\n /** [HMAC] For Github webhook, the standard differs slightly, so this option must be selected */\n isGithub?: boolean;\n}\n\n/** Auth related parameters used with mTLS authentication */\ninterface EndpointAuthTlsParams {\n /** [TLS] List oh hosts that are allowed to use the endpoint, this is compared to the claims in the certificate */\n whitelist?: Array<string>;\n}\n\n/** Mapping used to get auth specific parameters depending on the auth type used */\ninterface EndpointAuthSpecificParams {\n /** Auth parameters for no authentication */\n [EndpointAuthType.NONE]: any;\n /** Auth parameters for JWT authentication */\n [EndpointAuthType.JWT]: any;\n /** Auth parameters for mTLS authentication */\n [EndpointAuthType.TLS]: EndpointAuthTlsParams;\n /** Auth parameters for HMAC authentication */\n [EndpointAuthType.HMAC]: EndpointAuthHmacParams;\n /** Auth parameters for static authentication */\n [EndpointAuthType.STATIC]: any;\n}\n\nexport type EndpointAuthParams<T extends EndpointAuthType> =\n EndpointAuthSpecificParams[T] & {\n /** This will allow the business logic to run event if the authentication fails */\n acceptInvalid?: boolean;\n };\n\nexport type EndpointAuthHandler<T extends EndpointAuthType> = (\n options?: EndpointAuthParams<T>\n) => (\n request: Request,\n response: Response,\n next: NextFunction\n) => void | Promise<void>;\n\nexport const EndpointAuthHandlers = {\n /** Auth handler for no authentication */\n [EndpointAuthType.NONE]: undefined,\n /** Auth handler for JWT authentication */\n [EndpointAuthType.JWT]: authJwt,\n /** Auth handler for mTLS authentication */\n [EndpointAuthType.TLS]: authTls,\n /** Auth handler for HMAC authentication */\n [EndpointAuthType.HMAC]: authHmac,\n /** Auth handler for static authentication */\n [EndpointAuthType.STATIC]: authStatic\n};\n\nexport type EndpointHandler<T extends EndpointAuthType> = (\n request: EndpointRequestType[T],\n response: Response\n) => void | Promise<void>;\n\n/** Endpoint initialization options */\nexport interface EndpointOptions<T extends EndpointAuthType> {\n /** Path at which the endpoint is reachable */\n path: string;\n /** HTTP method of the endpoint */\n method: EndpointMethod;\n /** Function handling the endpoint's business logic */\n handler: EndpointHandler<T>;\n /** Validation schema that the request must pass before reaching the handler */\n validator: Schema;\n /** Authentication system required by this endpoint */\n authType: T;\n /** Authentication related options for this endpoint */\n authParams?: EndpointAuthParams<T>;\n /** @deprecated Setting to upload a file through this endpoint */\n file?: FileUploaderConfig;\n /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */\n files?: Array<FileUploaderConfig>;\n /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */\n middleware?: MiddlewareChainElement<T>;\n /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */\n errorMiddleware?: ErrorRequestHandler | Array<ErrorRequestHandler>;\n}\n\n/** Request type when using JWT authentication */\nexport interface JwtRequest<\n P = ParamsDictionary,\n ResBody = any,\n ReqBody = any,\n ReqQuery = ParsedQs,\n Locals extends Record<string, any> = Record<string, any>\n> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {\n /** User that identified using a JWT */\n user: Record<string, any> | any;\n}\n\n/** Request type when using mTLS authentication */\nexport interface TlsRequest<\n P = ParamsDictionary,\n ResBody = any,\n ReqBody = any,\n ReqQuery = ParsedQs,\n Locals extends Record<string, any> = Record<string, any>\n> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {\n /** Host names provided by the mTLS authenticated client */\n hosts: Array<string>;\n}\n\n/** Mapping of request types in endpoints based on auth type used */\nexport interface EndpointRequestType {\n /** Request type for no authentication */\n [EndpointAuthType.NONE]: Request;\n /** Request type when using JWT authentication */\n [EndpointAuthType.JWT]: JwtRequest;\n /** Request type when using mTLS authentication */\n [EndpointAuthType.TLS]: TlsRequest;\n /** Request type when using HMAC authentication */\n [EndpointAuthType.HMAC]: Request;\n /** Auth handler for static authentication */\n [EndpointAuthType.STATIC]: Request;\n}\n\nexport type SafeMiddleWareChain = Array<\n RequestHandler | ErrorRequestHandler | SafeMiddleWareChain\n>;\n"],"mappings":";;;;;;AAYA,IAAAA,WAAA,GAAAC,OAAA;AAZA;AAAA,IAoBYC,cAAc,GAAAC,OAAA,CAAAD,cAAA,0BAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA;AAUnB,MAAME,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAGC,MAAM,CAACC,MAAM,CAACJ,cAAc,CAAC;AAAC,IAEjDK,gBAAgB,GAAAJ,OAAA,CAAAI,gBAAA,0BAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAA,OAAhBA,gBAAgB;AAAA;AAQrB,MAAMC,iBAAiB,GAAAL,OAAA,CAAAK,iBAAA,GAAGH,MAAM,CAACC,MAAM,CAACC,gBAAgB,CAAC;;AAahE;;AAQA;;AAMA;;AA4BO,MAAME,oBAAoB,GAAAN,OAAA,CAAAM,oBAAA,GAAG;EAClC;EACA,CAACF,gBAAgB,CAACG,IAAI,GAAGC,SAAS;EAClC;EACA,CAACJ,gBAAgB,CAACK,GAAG,GAAGC,mBAAO;EAC/B;EACA,CAACN,gBAAgB,CAACO,GAAG,GAAGC,mBAAO;EAC/B;EACA,CAACR,gBAAgB,CAACS,IAAI,GAAGC,oBAAQ;EACjC;EACA,CAACV,gBAAgB,CAACW,MAAM,GAAGC;AAC7B,CAAC;;AAOD;;AAwBA;;AAYA;;AAYA","ignoreList":[]}
1
+ {"version":3,"file":"Endpoint.types.js","names":["_middleware","require","EndpointMethod","exports","EndpointMethods","Object","values","EndpointAuthType","EndpointAuthTypes","EndpointAuthHandlers","NONE","undefined","JWT","authJwt","TLS","authTls","HMAC","authHmac","STATIC","authStatic"],"sources":["../../../src/entities/Endpoint/Endpoint.types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n ErrorRequestHandler,\n Request,\n Response,\n NextFunction,\n RequestHandler\n} from 'express';\nimport { ParamsDictionary } from 'express-serve-static-core';\nimport { Schema } from 'express-validator';\nimport { ParsedQs } from 'qs';\n\nimport {\n authJwt,\n authHmac,\n authTls,\n authStatic,\n FileUploaderConfig\n} from 'middleware';\nimport { MultiPartFileUploaderConfig } from 'middleware/multiPartFileUploader/multiPartFileUploader.types';\n\nexport enum EndpointMethod {\n GET = 'get',\n POST = 'post',\n PUT = 'put',\n PATCH = 'patch',\n DELETE = 'delete',\n HEAD = 'head',\n ALL = 'all'\n}\n\nexport const EndpointMethods = Object.values(EndpointMethod);\n\nexport enum EndpointAuthType {\n NONE = 'none',\n JWT = 'jwt',\n TLS = 'tls',\n HMAC = 'hmac',\n STATIC = 'static'\n}\n\nexport const EndpointAuthTypes = Object.values(EndpointAuthType);\n\nexport type Middleware<T extends EndpointAuthType> = (\n request: EndpointRequestType[T],\n response: Response,\n next: NextFunction\n) => unknown | Promise<unknown>;\n\nexport type MiddlewareChainElement<T extends EndpointAuthType> =\n | Array<Middleware<T>>\n | Middleware<T>\n | any;\n\n/** Auth related parameters used with HMAC authentication */\ninterface EndpointAuthHmacParams {\n /** [HMAC] Secret used for signature */\n secret?: string;\n /** [HMAC] For Github webhook, the standard differs slightly, so this option must be selected */\n isGithub?: boolean;\n}\n\n/** Auth related parameters used with mTLS authentication */\ninterface EndpointAuthTlsParams {\n /** [TLS] List oh hosts that are allowed to use the endpoint, this is compared to the claims in the certificate */\n whitelist?: Array<string>;\n}\n\n/** Mapping used to get auth specific parameters depending on the auth type used */\ninterface EndpointAuthSpecificParams {\n /** Auth parameters for no authentication */\n [EndpointAuthType.NONE]: any;\n /** Auth parameters for JWT authentication */\n [EndpointAuthType.JWT]: any;\n /** Auth parameters for mTLS authentication */\n [EndpointAuthType.TLS]: EndpointAuthTlsParams;\n /** Auth parameters for HMAC authentication */\n [EndpointAuthType.HMAC]: EndpointAuthHmacParams;\n /** Auth parameters for static authentication */\n [EndpointAuthType.STATIC]: any;\n}\n\nexport type EndpointAuthParams<T extends EndpointAuthType> =\n EndpointAuthSpecificParams[T] & {\n /** This will allow the business logic to run event if the authentication fails */\n acceptInvalid?: boolean;\n };\n\nexport type EndpointAuthHandler<T extends EndpointAuthType> = (\n options?: EndpointAuthParams<T>\n) => (\n request: Request,\n response: Response,\n next: NextFunction\n) => void | Promise<void>;\n\nexport const EndpointAuthHandlers = {\n /** Auth handler for no authentication */\n [EndpointAuthType.NONE]: undefined,\n /** Auth handler for JWT authentication */\n [EndpointAuthType.JWT]: authJwt,\n /** Auth handler for mTLS authentication */\n [EndpointAuthType.TLS]: authTls,\n /** Auth handler for HMAC authentication */\n [EndpointAuthType.HMAC]: authHmac,\n /** Auth handler for static authentication */\n [EndpointAuthType.STATIC]: authStatic\n};\n\nexport type EndpointHandler<T extends EndpointAuthType> = (\n request: EndpointRequestType[T],\n response: Response\n) => void | Promise<void>;\n\n/** Endpoint initialization options */\nexport interface EndpointOptions<T extends EndpointAuthType> {\n /** Path at which the endpoint is reachable */\n path: string;\n /** HTTP method of the endpoint */\n method: EndpointMethod;\n /** Function handling the endpoint's business logic */\n handler: EndpointHandler<T>;\n /** Validation schema that the request must pass before reaching the handler */\n validator: Schema;\n /** Authentication system required by this endpoint */\n authType: T;\n /** Authentication related options for this endpoint */\n authParams?: EndpointAuthParams<T>;\n /** @deprecated Setting to upload a file through this endpoint */\n file?: FileUploaderConfig;\n /** Settings to upload files through this endpoint (this will automatically switch the expected request to be a multipart) */\n files?: Array<FileUploaderConfig>;\n /** Settings to upload file parts (Chunks) through this endpoint (this will automatically switch the expected request to be a multipart) */\n multiPartFile?: MultiPartFileUploaderConfig;\n /** Express request handlers that should run on this endpoint before the business logic, they will run after the global middleware */\n middleware?: MiddlewareChainElement<T>;\n /** Express error handlers that should be registered for this endpoint. they will run before the global error handler */\n errorMiddleware?: ErrorRequestHandler | Array<ErrorRequestHandler>;\n}\n\n/** Request type when using JWT authentication */\nexport interface JwtRequest<\n P = ParamsDictionary,\n ResBody = any,\n ReqBody = any,\n ReqQuery = ParsedQs,\n Locals extends Record<string, any> = Record<string, any>\n> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {\n /** User that identified using a JWT */\n user: Record<string, any> | any;\n}\n\n/** Request type when using mTLS authentication */\nexport interface TlsRequest<\n P = ParamsDictionary,\n ResBody = any,\n ReqBody = any,\n ReqQuery = ParsedQs,\n Locals extends Record<string, any> = Record<string, any>\n> extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {\n /** Host names provided by the mTLS authenticated client */\n hosts: Array<string>;\n}\n\n/** Mapping of request types in endpoints based on auth type used */\nexport interface EndpointRequestType {\n /** Request type for no authentication */\n [EndpointAuthType.NONE]: Request;\n /** Request type when using JWT authentication */\n [EndpointAuthType.JWT]: JwtRequest;\n /** Request type when using mTLS authentication */\n [EndpointAuthType.TLS]: TlsRequest;\n /** Request type when using HMAC authentication */\n [EndpointAuthType.HMAC]: Request;\n /** Auth handler for static authentication */\n [EndpointAuthType.STATIC]: Request;\n}\n\nexport type SafeMiddleWareChain = Array<\n RequestHandler | ErrorRequestHandler | SafeMiddleWareChain\n>;\n"],"mappings":";;;;;;AAYA,IAAAA,WAAA,GAAAC,OAAA;AAZA;AAAA,IAqBYC,cAAc,GAAAC,OAAA,CAAAD,cAAA,0BAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA;AAUnB,MAAME,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAGC,MAAM,CAACC,MAAM,CAACJ,cAAc,CAAC;AAAC,IAEjDK,gBAAgB,GAAAJ,OAAA,CAAAI,gBAAA,0BAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAhBA,gBAAgB;EAAA,OAAhBA,gBAAgB;AAAA;AAQrB,MAAMC,iBAAiB,GAAAL,OAAA,CAAAK,iBAAA,GAAGH,MAAM,CAACC,MAAM,CAACC,gBAAgB,CAAC;;AAahE;;AAQA;;AAMA;;AA4BO,MAAME,oBAAoB,GAAAN,OAAA,CAAAM,oBAAA,GAAG;EAClC;EACA,CAACF,gBAAgB,CAACG,IAAI,GAAGC,SAAS;EAClC;EACA,CAACJ,gBAAgB,CAACK,GAAG,GAAGC,mBAAO;EAC/B;EACA,CAACN,gBAAgB,CAACO,GAAG,GAAGC,mBAAO;EAC/B;EACA,CAACR,gBAAgB,CAACS,IAAI,GAAGC,oBAAQ;EACjC;EACA,CAACV,gBAAgB,CAACW,MAAM,GAAGC;AAC7B,CAAC;;AAOD;;AA0BA;;AAYA;;AAYA","ignoreList":[]}
@@ -9,6 +9,8 @@ var _WebError = require("../../entities/WebError");
9
9
  var _report = require("../../utils/report");
10
10
  var _multer = _interopRequireDefault(require("multer"));
11
11
  var _validate = require("./validate");
12
+ var _path = _interopRequireDefault(require("path"));
13
+ var _bytes = _interopRequireDefault(require("bytes"));
12
14
  const namespace = 'engine:middleware:fileUploader';
13
15
 
14
16
  /**
@@ -32,8 +34,8 @@ function fileUploader(filesOptions, validator) {
32
34
  const upload = (0, _multer.default)({
33
35
  storage,
34
36
  limits: {
35
- fileSize: 10 * 1024 * 1024
36
- } // Limit file size to 10MB
37
+ fileSize: 32 * 1024 * 1024
38
+ } // Default global limit (10MB)
37
39
  }).any();
38
40
  upload(request, response, async err => {
39
41
  if (err) {
@@ -102,7 +104,47 @@ function fileUploader(filesOptions, validator) {
102
104
  }
103
105
  }));
104
106
  }
105
- request.body.files = uploadedFiles;
107
+
108
+ // Validate each uploaded file
109
+ for (const file of uploadedFiles) {
110
+ const fileOption = filesOptions.find(option => option.key === file.fieldname);
111
+ if (!fileOption) continue;
112
+
113
+ // MIME Type Validation
114
+ if (fileOption.mimeTypes && !fileOption.mimeTypes.includes(file.mimetype)) {
115
+ return next(new _WebError.WebError({
116
+ statusCode: 400,
117
+ errorCode: 'invalid-mime-type',
118
+ message: `Invalid file type for ${file.fieldname}`,
119
+ data: {
120
+ expected: fileOption.mimeTypes,
121
+ received: file.mimetype
122
+ }
123
+ }));
124
+ }
125
+
126
+ // Max File Size Validation
127
+ if (fileOption.maxSize) {
128
+ const maxSizeInBytes = (0, _bytes.default)(fileOption.maxSize);
129
+ if (maxSizeInBytes && file.size > maxSizeInBytes) {
130
+ return next(new _WebError.WebError({
131
+ statusCode: 400,
132
+ errorCode: 'file-too-large',
133
+ message: `File ${file.originalname} exceeds the allowed size`,
134
+ data: {
135
+ maxSize: fileOption.maxSize,
136
+ receivedSize: file.size
137
+ }
138
+ }));
139
+ }
140
+ }
141
+
142
+ // No Extension Handling
143
+ if (fileOption.noExtension) {
144
+ file.originalname = _path.default.basename(file.originalname, _path.default.extname(file.originalname));
145
+ }
146
+ }
147
+ request.files = uploadedFiles;
106
148
  next();
107
149
  });
108
150
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fileUploader.js","names":["_WebError","require","_report","_multer","_interopRequireDefault","_validate","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","body"],"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';\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: 10 * 1024 * 1024 } // Limit file size to 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 request.body.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","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 +1,2 @@
1
1
  export * from './multiPartFileUploader';
2
+ export * from './multiPartFileUploader.types';
@@ -14,4 +14,15 @@ Object.keys(_multiPartFileUploader).forEach(function (key) {
14
14
  }
15
15
  });
16
16
  });
17
+ var _multiPartFileUploader2 = require("./multiPartFileUploader.types");
18
+ Object.keys(_multiPartFileUploader2).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _multiPartFileUploader2[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _multiPartFileUploader2[key];
25
+ }
26
+ });
27
+ });
17
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_multiPartFileUploader","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get"],"sources":["../../../src/middleware/multiPartFileUploader/index.ts"],"sourcesContent":["export * from './multiPartFileUploader';\n"],"mappings":";;;;;AAAA,IAAAA,sBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,sBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,sBAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,sBAAA,CAAAK,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_multiPartFileUploader","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_multiPartFileUploader2"],"sources":["../../../src/middleware/multiPartFileUploader/index.ts"],"sourcesContent":["export * from './multiPartFileUploader';\nexport * from './multiPartFileUploader.types';\n"],"mappings":";;;;;AAAA,IAAAA,sBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,sBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,sBAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,sBAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,uBAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,uBAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,uBAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,uBAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -1,3 +1,4 @@
1
- import express from 'express';
2
- declare function multiPartFileUploader(req: express.Request, res: express.Response, next: express.NextFunction): Promise<void>;
3
- export { multiPartFileUploader };
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { Schema } from 'express-validator';
3
+ import { MultiPartFileUploaderConfig } from './multiPartFileUploader.types';
4
+ export declare function multiPartFileUploader(filesOption: MultiPartFileUploaderConfig, validator: Schema): (req: Request, res: Response, next: NextFunction) => Promise<void>;