@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.
- package/build/src/constants/global.d.ts +1 -0
- package/build/src/constants/global.d.ts.map +1 -1
- package/build/src/constants/global.js +1 -1
- package/build/src/constants/global.js.map +1 -1
- package/build/src/middlewares/uploader.d.ts +39 -10
- package/build/src/middlewares/uploader.d.ts.map +1 -1
- package/build/src/middlewares/uploader.js +89 -22
- package/build/src/middlewares/uploader.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 {
|
|
2
|
-
|
|
3
|
-
export interface UploaderMiddlewareOptionsI {
|
|
1
|
+
import type { RequestHandler } from "express";
|
|
2
|
+
export interface UploadOptions {
|
|
4
3
|
fieldName?: string;
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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":"
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
56
|
+
req.uploaderError = new UploadError(`Unsupported file type: ${file.mimetype}`);
|
|
20
57
|
cb(null, false);
|
|
21
58
|
}
|
|
22
59
|
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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":"
|
|
1
|
+
{"version":3,"file":"uploader.js","sourceRoot":"","sources":["../../../src/middlewares/uploader.ts"],"names":[],"mappings":"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"}
|