@devshopapp/common 1.0.15 → 1.0.17

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.
@@ -1,3 +1,4 @@
1
+ export declare const UPLOADS_DIRECTORY = "uploads/";
1
2
  export interface JwtPayload {
2
3
  email: string;
3
4
  userId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../../src/constants/global.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../../src/constants/global.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB"}
@@ -1,2 +1,2 @@
1
- export {};
1
+ export const UPLOADS_DIRECTORY = "uploads/";
2
2
  //# sourceMappingURL=global.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/constants/global.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/constants/global.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC"}
@@ -1,16 +1,45 @@
1
- import type { Request } from "express";
2
- import multer, { type FileFilterCallback } from "multer";
3
- export interface UploaderMiddlewareOptionsI {
1
+ import type { RequestHandler } from "express";
2
+ export interface UploadOptions {
4
3
  fieldName?: string;
5
- types?: Array<string>;
4
+ allowedMimeTypes?: string[];
5
+ maxFileSize?: number;
6
+ maxFiles?: number;
7
+ uploadDirectory?: string;
8
+ preserveExtension?: boolean;
9
+ }
10
+ export declare class UploadError extends Error {
11
+ statusCode: number;
12
+ constructor(message: string);
6
13
  }
7
14
  export declare class Uploader {
8
- uploadDirectory?: string | undefined;
9
- defaultUploadDirectory: string;
15
+ private readonly uploadDirectory?;
16
+ private readonly DEFAULT_UPLOAD_DIR;
17
+ private readonly DEFAULT_MAX_FILE_SIZE;
18
+ private readonly DEFAULT_MAX_FILES;
10
19
  constructor(uploadDirectory?: string | undefined);
11
- fileFilter: (types?: Array<string>) => (req: Request, file: Express.Multer.File, cb: FileFilterCallback) => void;
12
- storage: multer.StorageEngine;
13
- uploadMultipleFiles(options?: UploaderMiddlewareOptionsI): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
14
- uploadSingleFile(options?: UploaderMiddlewareOptionsI): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
20
+ /**
21
+ * Ensure upload directory exists
22
+ */
23
+ private ensureDirectoryExists;
24
+ /**
25
+ * Generate cryptographically secure filename
26
+ */
27
+ private generateFilename;
28
+ /**
29
+ * Validate mime type
30
+ */
31
+ private buildFileFilter;
32
+ /**
33
+ * Build storage engine
34
+ */
35
+ private buildStorage;
36
+ /**
37
+ * Upload multiple files
38
+ */
39
+ uploadMultipleFiles(options?: UploadOptions): RequestHandler;
40
+ /**
41
+ * Upload single file
42
+ */
43
+ uploadSingleFile(options?: UploadOptions): RequestHandler;
15
44
  }
16
45
  //# sourceMappingURL=uploader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../../src/middlewares/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,MAAM,EAAE,EAAE,KAAK,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,qBAAa,QAAQ;IAGE,eAAe,CAAC,EAAE,MAAM;IAFpC,sBAAsB,SAAc;gBAExB,eAAe,CAAC,EAAE,MAAM,YAAA;IAEpC,UAAU,GAAI,QAAQ,KAAK,CAAC,MAAM,CAAC,MAC9B,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,kBAAkB,UAa1E;IAEM,OAAO,uBAQZ;IAEF,mBAAmB,CAAC,OAAO,CAAC,EAAE,0BAA0B;IAKxD,gBAAgB,CAAC,OAAO,CAAC,EAAE,0BAA0B;CAIxD"}
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../../src/middlewares/uploader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,qBAAa,WAAY,SAAQ,KAAK;IAClC,UAAU,SAAO;gBAEL,OAAO,EAAE,MAAM;CAQ9B;AAED,qBAAa,QAAQ;IAML,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAJ7C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAmB;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAK;gBAEV,eAAe,CAAC,EAAE,MAAM,YAAA;IAErD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmBvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACI,mBAAmB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc;IAenE;;OAEG;IACI,gBAAgB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc;CAcnE"}
@@ -1,42 +1,109 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import crypto from "crypto";
1
4
  import multer, {} from "multer";
5
+ export class UploadError extends Error {
6
+ statusCode = 400;
7
+ constructor(message) {
8
+ super(message);
9
+ Object.setPrototypeOf(this, UploadError.prototype);
10
+ }
11
+ }
2
12
  export class Uploader {
3
13
  uploadDirectory;
4
- defaultUploadDirectory = '/uploads';
14
+ DEFAULT_UPLOAD_DIR = path.resolve("uploads");
15
+ DEFAULT_MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB
16
+ DEFAULT_MAX_FILES = 5;
5
17
  constructor(uploadDirectory) {
6
18
  this.uploadDirectory = uploadDirectory;
7
19
  }
8
- fileFilter = (types) => {
20
+ /**
21
+ * Ensure upload directory exists
22
+ */
23
+ ensureDirectoryExists(directory) {
24
+ if (!fs.existsSync(directory)) {
25
+ fs.mkdirSync(directory, {
26
+ recursive: true
27
+ });
28
+ }
29
+ }
30
+ /**
31
+ * Generate cryptographically secure filename
32
+ */
33
+ generateFilename(originalName, preserveExtension = true) {
34
+ const randomName = crypto.randomBytes(32).toString("hex");
35
+ if (!preserveExtension) {
36
+ return randomName;
37
+ }
38
+ const extension = path.extname(originalName);
39
+ return `${randomName}${extension}`;
40
+ }
41
+ /**
42
+ * Validate mime type
43
+ */
44
+ buildFileFilter(allowedMimeTypes) {
9
45
  return (req, file, cb) => {
10
- const type = file.mimetype;
11
- if (!types)
12
- return cb(null, true);
13
- if (types.length <= 0)
46
+ if (!allowedMimeTypes || allowedMimeTypes.length === 0) {
14
47
  return cb(null, true);
15
- if (types.some((accepted) => accepted === type)) {
48
+ }
49
+ const isAllowed = allowedMimeTypes.includes(file.mimetype);
50
+ // if (!isAllowed) { return cb(new UploadError(`Unsupported file type: ${file.mimetype}`));}
51
+ // cb(null, true);
52
+ if (isAllowed) {
16
53
  cb(null, true);
17
54
  }
18
55
  else {
19
- req.uploaderError = new Error(`we only accept the following types: ${types.join(', ')}`);
56
+ req.uploaderError = new UploadError(`Unsupported file type: ${file.mimetype}`);
20
57
  cb(null, false);
21
58
  }
22
59
  };
23
- };
24
- storage = multer.diskStorage({
25
- destination: (req, file, cb) => {
26
- cb(null, this.uploadDirectory || this.defaultUploadDirectory);
27
- },
28
- filename: (req, file, cb) => {
29
- const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
30
- cb(null, `${file.fieldname}${uniqueSuffix}`);
31
- }
32
- });
60
+ }
61
+ /**
62
+ * Build storage engine
63
+ */
64
+ buildStorage(directory, preserveExtension) {
65
+ this.ensureDirectoryExists(directory);
66
+ return multer.diskStorage({
67
+ destination: (req, file, cb) => {
68
+ cb(null, directory);
69
+ },
70
+ filename: (req, file, cb) => {
71
+ try {
72
+ const filename = this.generateFilename(file.originalname, preserveExtension);
73
+ cb(null, filename);
74
+ }
75
+ catch (err) {
76
+ cb(err, "");
77
+ }
78
+ }
79
+ });
80
+ }
81
+ /**
82
+ * Upload multiple files
83
+ */
33
84
  uploadMultipleFiles(options) {
34
- return multer({ storage: this.storage, fileFilter: this.fileFilter(options?.types) })
35
- .array(options?.fieldName || 'file');
85
+ const uploadDir = options?.uploadDirectory || this.uploadDirectory || this.DEFAULT_UPLOAD_DIR;
86
+ return multer({
87
+ storage: this.buildStorage(uploadDir, options?.preserveExtension ?? true),
88
+ fileFilter: this.buildFileFilter(options?.allowedMimeTypes),
89
+ limits: {
90
+ fileSize: options?.maxFileSize || this.DEFAULT_MAX_FILE_SIZE,
91
+ files: options?.maxFiles || this.DEFAULT_MAX_FILES
92
+ }
93
+ }).array(options?.fieldName || "files");
36
94
  }
95
+ /**
96
+ * Upload single file
97
+ */
37
98
  uploadSingleFile(options) {
38
- return multer({ storage: this.storage, fileFilter: this.fileFilter(options?.types) })
39
- .single(options?.fieldName || 'file');
99
+ const uploadDir = options?.uploadDirectory || this.uploadDirectory || this.DEFAULT_UPLOAD_DIR;
100
+ return multer({
101
+ storage: this.buildStorage(uploadDir, options?.preserveExtension ?? true),
102
+ fileFilter: this.buildFileFilter(options?.allowedMimeTypes),
103
+ limits: {
104
+ fileSize: options?.maxFileSize || this.DEFAULT_MAX_FILE_SIZE
105
+ }
106
+ }).single(options?.fieldName || "file");
40
107
  }
41
108
  }
42
109
  //# sourceMappingURL=uploader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../../../src/middlewares/uploader.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,EAAE,EAA2B,MAAM,QAAQ,CAAC;AAOzD,MAAM,OAAO,QAAQ;IAGE;IAFZ,sBAAsB,GAAG,UAAU,CAAC;IAE3C,YAAmB,eAAwB;QAAxB,oBAAe,GAAf,eAAe,CAAS;IAAG,CAAC;IAExC,UAAU,GAAG,CAAC,KAAqB,EAAE,EAAE;QAC1C,OAAO,CAAC,GAAY,EAAE,IAAyB,EAAE,EAAsB,EAAE,EAAE;YACvE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;YAE3B,IAAI,CAAC,KAAK;gBAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;gBAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAE7C,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,QAAgB,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI,CAAC,EAAE,CAAC;gBACtD,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,aAAa,GAAG,IAAI,KAAK,CAAC,uCAAuC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACzF,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACpB,CAAC;QACL,CAAC,CAAA;IACL,CAAC,CAAA;IAEM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;YAC3B,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,IAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChE,CAAC;QACD,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;YACxB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;YACxE,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC,CAAC;QACjD,CAAC;KACJ,CAAC,CAAA;IAEF,mBAAmB,CAAC,OAAoC;QACpD,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;aAChF,KAAK,CAAC,OAAO,EAAE,SAAS,IAAI,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,gBAAgB,CAAC,OAAoC;QACjD,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;aAChF,MAAM,CAAC,OAAO,EAAE,SAAS,IAAI,MAAM,CAAC,CAAC;IAC9C,CAAC;CACJ"}
1
+ {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../../../src/middlewares/uploader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devshopapp/common",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "A common utils package for the different services in the shopping application",
5
5
  "type": "module",
6
6
  "types": "./build/src/index.d.ts",