@ackplus/nest-file-storage 0.0.2
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/LICENSE +21 -0
- package/README.md +409 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +5 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/file-storage.service.d.ts +8 -0
- package/dist/lib/file-storage.service.d.ts.map +1 -0
- package/dist/lib/file-storage.service.js +30 -0
- package/dist/lib/file-storage.service.js.map +1 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +22 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/interceptor/file-storage.interceptor.d.ts +25 -0
- package/dist/lib/interceptor/file-storage.interceptor.d.ts.map +1 -0
- package/dist/lib/interceptor/file-storage.interceptor.js +141 -0
- package/dist/lib/interceptor/file-storage.interceptor.js.map +1 -0
- package/dist/lib/nest-file-storage.module.d.ts +9 -0
- package/dist/lib/nest-file-storage.module.d.ts.map +1 -0
- package/dist/lib/nest-file-storage.module.js +80 -0
- package/dist/lib/nest-file-storage.module.js.map +1 -0
- package/dist/lib/storage/azure.storage.d.ts +19 -0
- package/dist/lib/storage/azure.storage.d.ts.map +1 -0
- package/dist/lib/storage/azure.storage.js +189 -0
- package/dist/lib/storage/azure.storage.js.map +1 -0
- package/dist/lib/storage/local.storage.d.ts +35 -0
- package/dist/lib/storage/local.storage.d.ts.map +1 -0
- package/dist/lib/storage/local.storage.js +219 -0
- package/dist/lib/storage/local.storage.js.map +1 -0
- package/dist/lib/storage/s3.storage.d.ts +20 -0
- package/dist/lib/storage/s3.storage.d.ts.map +1 -0
- package/dist/lib/storage/s3.storage.js +231 -0
- package/dist/lib/storage/s3.storage.js.map +1 -0
- package/dist/lib/storage.factory.d.ts +9 -0
- package/dist/lib/storage.factory.d.ts.map +1 -0
- package/dist/lib/storage.factory.js +82 -0
- package/dist/lib/storage.factory.js.map +1 -0
- package/dist/lib/types.d.ts +91 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +10 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.LocalStorage = void 0;
|
|
40
|
+
const concat_stream_1 = __importDefault(require("concat-stream"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const moment_1 = __importDefault(require("moment"));
|
|
43
|
+
const path_1 = require("path");
|
|
44
|
+
const uuid_1 = require("uuid");
|
|
45
|
+
class LocalStorage {
|
|
46
|
+
/**
|
|
47
|
+
* Convert OS-specific file path to URL-friendly key
|
|
48
|
+
* This ensures keys are consistent across all platforms
|
|
49
|
+
* Windows: C:\uploads\2024\01\file.jpg -> 2024/01/file.jpg
|
|
50
|
+
* Unix: /uploads/2024/01/file.jpg -> 2024/01/file.jpg
|
|
51
|
+
*/
|
|
52
|
+
pathToUrl(filePath) {
|
|
53
|
+
if (!filePath)
|
|
54
|
+
return '';
|
|
55
|
+
// Remove rootPath if present
|
|
56
|
+
let relativePath = filePath;
|
|
57
|
+
if (filePath.startsWith(this.rootPath)) {
|
|
58
|
+
relativePath = filePath.substring(this.rootPath.length);
|
|
59
|
+
}
|
|
60
|
+
// Convert backslashes to forward slashes and remove leading slash
|
|
61
|
+
return relativePath.replace(/\\/g, '/').replace(/^\/+/, '');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Convert URL-friendly key to OS-specific file path
|
|
65
|
+
* This converts stored keys back to valid file system paths
|
|
66
|
+
* 2024/01/file.jpg -> Windows: 2024\01\file.jpg, Unix: 2024/01/file.jpg
|
|
67
|
+
*/
|
|
68
|
+
urlToPath(urlKey) {
|
|
69
|
+
if (!urlKey)
|
|
70
|
+
return '';
|
|
71
|
+
// Split by forward slashes and rejoin with OS-specific separator
|
|
72
|
+
const parts = urlKey.split('/').filter(part => part.length > 0);
|
|
73
|
+
return parts.join(path_1.sep);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get full file system path from URL-friendly key
|
|
77
|
+
*/
|
|
78
|
+
getFullPath(urlKey) {
|
|
79
|
+
const osPath = this.urlToPath(urlKey);
|
|
80
|
+
return (0, path_1.join)(this.rootPath, osPath);
|
|
81
|
+
}
|
|
82
|
+
constructor(options) {
|
|
83
|
+
this.options = options;
|
|
84
|
+
// Normalize path for the current OS
|
|
85
|
+
this.rootPath = (0, path_1.normalize)(options.rootPath || (0, path_1.join)(process.cwd(), 'public'));
|
|
86
|
+
this.fileNameFunction = options.fileName || ((file, _req) => {
|
|
87
|
+
return `${(0, uuid_1.v4)()}-${file.originalname}`;
|
|
88
|
+
});
|
|
89
|
+
this.fileDistFunction = options.fileDist || ((_file, _req) => {
|
|
90
|
+
return (0, path_1.join)(this.rootPath, (0, moment_1.default)().format('YYYY'), (0, moment_1.default)().format('MM'), (0, moment_1.default)().format('DD'));
|
|
91
|
+
});
|
|
92
|
+
// Ensure the rootPath directory exists
|
|
93
|
+
if (!fs.existsSync(this.rootPath)) {
|
|
94
|
+
fs.mkdirSync(this.rootPath, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async _handleFile(req, file, cb) {
|
|
98
|
+
try {
|
|
99
|
+
const dist = await this.fileDistFunction(file, req);
|
|
100
|
+
const fileName = await this.fileNameFunction(file, req);
|
|
101
|
+
const filePath = (0, path_1.join)(dist, fileName);
|
|
102
|
+
// Convert to URL-friendly key for storage
|
|
103
|
+
const urlKey = this.pathToUrl(filePath);
|
|
104
|
+
file.stream.pipe((0, concat_stream_1.default)({ encoding: 'buffer' }, async (buffer) => {
|
|
105
|
+
const uploadedFile = await this.putFile(buffer, urlKey);
|
|
106
|
+
const fileInfo = {
|
|
107
|
+
...uploadedFile,
|
|
108
|
+
fieldName: file.fieldname,
|
|
109
|
+
originalName: file.originalname,
|
|
110
|
+
mimetype: file.mimetype,
|
|
111
|
+
};
|
|
112
|
+
let transformData = fileInfo;
|
|
113
|
+
if (this.options?.transformUploadedFileObject) {
|
|
114
|
+
transformData = await this.options.transformUploadedFileObject(fileInfo);
|
|
115
|
+
}
|
|
116
|
+
cb(null, transformData);
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error('error', error);
|
|
121
|
+
cb(error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
_removeFile(_req, file, cb) {
|
|
125
|
+
const filePath = file.path;
|
|
126
|
+
fs.unlink(filePath, (err) => {
|
|
127
|
+
if (err) {
|
|
128
|
+
cb(err);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
cb(null);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
getUrl(urlKey) {
|
|
136
|
+
if (urlKey && urlKey.startsWith('http')) {
|
|
137
|
+
return urlKey;
|
|
138
|
+
}
|
|
139
|
+
if (!urlKey) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
// Key is already in URL format (forward slashes)
|
|
143
|
+
// Ensure baseUrl doesn't end with slash and key doesn't start with slash
|
|
144
|
+
const baseUrl = this.options.baseUrl.replace(/\/$/, '');
|
|
145
|
+
const cleanKey = urlKey.replace(/^\//, '');
|
|
146
|
+
return `${baseUrl}/${cleanKey}`;
|
|
147
|
+
}
|
|
148
|
+
async getFile(urlKey) {
|
|
149
|
+
// Convert URL key to OS-specific path
|
|
150
|
+
const fullPath = this.getFullPath(urlKey);
|
|
151
|
+
return fs.promises.readFile(fullPath);
|
|
152
|
+
}
|
|
153
|
+
async deleteFile(urlKey) {
|
|
154
|
+
// Convert URL key to OS-specific path
|
|
155
|
+
const fullPath = this.getFullPath(urlKey);
|
|
156
|
+
return fs.promises.unlink(fullPath);
|
|
157
|
+
}
|
|
158
|
+
async putFile(fileContent, urlKey) {
|
|
159
|
+
return new Promise((putFileResolve, reject) => {
|
|
160
|
+
// Convert URL key to OS-specific path
|
|
161
|
+
const filePath = this.getFullPath(urlKey);
|
|
162
|
+
const directoryPath = (0, path_1.dirname)(filePath);
|
|
163
|
+
// Create the directory if it doesn't exist
|
|
164
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
165
|
+
fs.writeFile(filePath, fileContent, (err) => {
|
|
166
|
+
if (err) {
|
|
167
|
+
reject(err);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const stats = fs.statSync(filePath);
|
|
171
|
+
const fileName = urlKey.split('/').pop() || urlKey;
|
|
172
|
+
const fileInfo = {
|
|
173
|
+
originalName: fileName,
|
|
174
|
+
size: stats.size,
|
|
175
|
+
fileName: fileName,
|
|
176
|
+
key: urlKey,
|
|
177
|
+
url: this.getUrl(urlKey),
|
|
178
|
+
fullPath: filePath,
|
|
179
|
+
};
|
|
180
|
+
putFileResolve(fileInfo);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
path(urlKey) {
|
|
185
|
+
if (!urlKey) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
// Convert URL key to full OS-specific path
|
|
189
|
+
return this.getFullPath(urlKey);
|
|
190
|
+
}
|
|
191
|
+
async copyFile(oldUrlKey, newUrlKey) {
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
// Convert URL keys to OS-specific paths
|
|
194
|
+
const oldPath = this.getFullPath(oldUrlKey);
|
|
195
|
+
const newPath = this.getFullPath(newUrlKey);
|
|
196
|
+
const directoryPath = (0, path_1.dirname)(newPath);
|
|
197
|
+
fs.mkdirSync(directoryPath, { recursive: true });
|
|
198
|
+
fs.copyFile(oldPath, newPath, (err) => {
|
|
199
|
+
if (err) {
|
|
200
|
+
reject(err);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const stats = fs.statSync(newPath);
|
|
204
|
+
const fileName = newUrlKey.split('/').pop() || newUrlKey;
|
|
205
|
+
const fileInfo = {
|
|
206
|
+
originalName: fileName,
|
|
207
|
+
size: stats.size,
|
|
208
|
+
fileName: fileName,
|
|
209
|
+
key: newUrlKey,
|
|
210
|
+
fullPath: newPath,
|
|
211
|
+
url: this.getUrl(newUrlKey),
|
|
212
|
+
};
|
|
213
|
+
resolve(fileInfo);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.LocalStorage = LocalStorage;
|
|
219
|
+
//# sourceMappingURL=local.storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.storage.js","sourceRoot":"","sources":["../../../src/lib/storage/local.storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GetObjectCommandInput } from '@aws-sdk/client-s3';
|
|
2
|
+
import { StorageEngine } from 'multer';
|
|
3
|
+
import { S3StorageOptions, Storage, UploadedFile } from '../types';
|
|
4
|
+
export declare class S3Storage implements StorageEngine, Storage {
|
|
5
|
+
private options;
|
|
6
|
+
private s3;
|
|
7
|
+
private fileNameFunction;
|
|
8
|
+
private fileDistFunction;
|
|
9
|
+
constructor(options: S3StorageOptions);
|
|
10
|
+
_handleFile(req: any, file: Express.Multer.File, cb: (error?: any, info?: any) => void): Promise<void>;
|
|
11
|
+
_removeFile(_req: any, file: any, cb: (error: Error | null) => void): void;
|
|
12
|
+
getUrl(key: string): string;
|
|
13
|
+
getSignedUrl(key: string, objectConfig?: Partial<GetObjectCommandInput>): Promise<string>;
|
|
14
|
+
getFile(key: string): Promise<Buffer>;
|
|
15
|
+
putFile(fileContent: Buffer, key: string): Promise<any>;
|
|
16
|
+
deleteFile(key: string): Promise<void>;
|
|
17
|
+
private streamToBuffer;
|
|
18
|
+
copyFile(oldKey: string, newKey: string): Promise<UploadedFile>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=s3.storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.storage.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/s3.storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,qBAAqB,EAAM,MAAM,oBAAoB,CAAC;AAIlF,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMvC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGnE,qBAAa,SAAU,YAAW,aAAa,EAAE,OAAO;IAMxC,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,gBAAgB,CAAqE;IAC7F,OAAO,CAAC,gBAAgB,CAAqE;gBAEzE,OAAO,EAAE,gBAAgB;IAmBvC,WAAW,CACb,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EACzB,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IAkChB,WAAW,CACP,IAAI,EAAE,GAAG,EACT,IAAI,KAAA,EACJ,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAClC,IAAI;IAYP,MAAM,CAAC,GAAG,EAAE,MAAM;IAOZ,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAevE,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BrC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA0CvD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAmB9B,cAAc;IAQtB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CA4BxE"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.S3Storage = void 0;
|
|
40
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
41
|
+
const client_s3_2 = require("@aws-sdk/client-s3");
|
|
42
|
+
const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
|
|
43
|
+
const moment_1 = __importDefault(require("moment"));
|
|
44
|
+
const path_1 = __importStar(require("path"));
|
|
45
|
+
const stream_1 = require("stream");
|
|
46
|
+
const uuid_1 = require("uuid");
|
|
47
|
+
class S3Storage {
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.options = options;
|
|
50
|
+
this.fileNameFunction = options.fileName || ((file, _req) => {
|
|
51
|
+
return `${(0, uuid_1.v4)()}-${file.originalname}`;
|
|
52
|
+
});
|
|
53
|
+
this.fileDistFunction = options.fileDist || ((_file, _req) => {
|
|
54
|
+
return path_1.default.join('uploads', (0, moment_1.default)().format('YYYY'), (0, moment_1.default)().format('MM'), (0, moment_1.default)().format('DD'));
|
|
55
|
+
});
|
|
56
|
+
this.s3 = new client_s3_1.S3({
|
|
57
|
+
endpoint: this.options.endpoint || null,
|
|
58
|
+
region: this.options.region,
|
|
59
|
+
credentials: {
|
|
60
|
+
accessKeyId: this.options.accessKeyId,
|
|
61
|
+
secretAccessKey: this.options.secretAccessKey,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async _handleFile(req, file, cb) {
|
|
66
|
+
// Collect file chunks to determine size
|
|
67
|
+
const chunks = [];
|
|
68
|
+
file.stream.on('data', (chunk) => chunks.push(chunk));
|
|
69
|
+
file.stream.on('end', async () => {
|
|
70
|
+
const buffer = Buffer.concat(chunks);
|
|
71
|
+
try {
|
|
72
|
+
const dist = await this.fileDistFunction(file, req);
|
|
73
|
+
const key = await this.fileNameFunction(file, req);
|
|
74
|
+
const filePath = (0, path_1.join)(dist, key);
|
|
75
|
+
const uploadedFile = await this.putFile(buffer, filePath);
|
|
76
|
+
const fileInfo = {
|
|
77
|
+
...uploadedFile,
|
|
78
|
+
fieldName: file.fieldname,
|
|
79
|
+
originalName: file.originalname,
|
|
80
|
+
mimetype: file.mimetype,
|
|
81
|
+
};
|
|
82
|
+
let transformData = fileInfo;
|
|
83
|
+
if (this.options?.transformUploadedFileObject) {
|
|
84
|
+
transformData = await this.options.transformUploadedFileObject(fileInfo);
|
|
85
|
+
}
|
|
86
|
+
cb(null, transformData);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
cb(err);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
file.stream.on('error', (err) => cb(err));
|
|
93
|
+
}
|
|
94
|
+
_removeFile(_req, file, cb) {
|
|
95
|
+
const params = {
|
|
96
|
+
Bucket: this.options.bucket,
|
|
97
|
+
Key: file.key,
|
|
98
|
+
};
|
|
99
|
+
this.s3
|
|
100
|
+
.deleteObject(params)
|
|
101
|
+
.then(() => cb(null))
|
|
102
|
+
.catch((err) => cb(err));
|
|
103
|
+
}
|
|
104
|
+
getUrl(key) {
|
|
105
|
+
if (this.options?.cloudFrontUrl) {
|
|
106
|
+
return `${this.options.cloudFrontUrl}/${key}`;
|
|
107
|
+
}
|
|
108
|
+
return `https://${this.options.bucket}.s3.amazonaws.com/${key}`;
|
|
109
|
+
}
|
|
110
|
+
async getSignedUrl(key, objectConfig) {
|
|
111
|
+
if (key) {
|
|
112
|
+
const url = await (0, s3_request_presigner_1.getSignedUrl)(this.s3, new client_s3_2.GetObjectCommand({
|
|
113
|
+
Bucket: this.options.bucket,
|
|
114
|
+
Key: key,
|
|
115
|
+
...(objectConfig && { ...objectConfig }),
|
|
116
|
+
}));
|
|
117
|
+
return url;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
async getFile(key) {
|
|
122
|
+
if (!key) {
|
|
123
|
+
throw new Error('Key is required to fetch the file from S3.');
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const command = new client_s3_2.GetObjectCommand({
|
|
127
|
+
Bucket: this.options.bucket,
|
|
128
|
+
Key: key,
|
|
129
|
+
});
|
|
130
|
+
const data = await this.s3.send(command);
|
|
131
|
+
if (!data.Body) {
|
|
132
|
+
throw new Error('Empty response received from S3.');
|
|
133
|
+
}
|
|
134
|
+
// Handle both Buffer and Readable Stream responses
|
|
135
|
+
if (data.Body instanceof stream_1.Readable) {
|
|
136
|
+
return await this.streamToBuffer(data.Body);
|
|
137
|
+
}
|
|
138
|
+
throw new Error('Unexpected data.Body type received from S3.');
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(`Error fetching file (${key}) from S3:`, error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async putFile(fileContent, key) {
|
|
146
|
+
try {
|
|
147
|
+
const fileName = (0, path_1.basename)(key);
|
|
148
|
+
const fileKey = key || (Math.random() + 1).toString(36).substring(12);
|
|
149
|
+
// Upload the file
|
|
150
|
+
const putParams = {
|
|
151
|
+
Bucket: this.options.bucket,
|
|
152
|
+
Key: fileKey,
|
|
153
|
+
Body: fileContent,
|
|
154
|
+
ContentDisposition: `inline; ${fileName}`,
|
|
155
|
+
};
|
|
156
|
+
await this.s3.send(new client_s3_2.PutObjectCommand(putParams));
|
|
157
|
+
// Fetch file metadata to get size
|
|
158
|
+
const headParams = {
|
|
159
|
+
Bucket: this.options.bucket,
|
|
160
|
+
Key: fileKey,
|
|
161
|
+
};
|
|
162
|
+
const headObject = await this.s3.send(new client_s3_2.HeadObjectCommand(headParams));
|
|
163
|
+
const fileSize = headObject.ContentLength || 0;
|
|
164
|
+
// Construct response object
|
|
165
|
+
const fileData = {
|
|
166
|
+
originalName: fileName,
|
|
167
|
+
fileName: fileName,
|
|
168
|
+
size: fileSize,
|
|
169
|
+
buffer: fileContent,
|
|
170
|
+
fullPath: fileKey,
|
|
171
|
+
key: fileKey,
|
|
172
|
+
url: this.getUrl(fileKey),
|
|
173
|
+
};
|
|
174
|
+
return fileData;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
console.error('Error uploading file to S3:', error);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async deleteFile(key) {
|
|
182
|
+
if (!key) {
|
|
183
|
+
throw new Error('File key is required for deletion.');
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
const deleteParams = {
|
|
187
|
+
Bucket: this.options.bucket,
|
|
188
|
+
Key: key,
|
|
189
|
+
};
|
|
190
|
+
await this.s3.send(new client_s3_2.DeleteObjectCommand(deleteParams));
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.error(`Error deleting file (${key}) from S3:`, error);
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async streamToBuffer(stream) {
|
|
198
|
+
const chunks = [];
|
|
199
|
+
for await (const chunk of stream) {
|
|
200
|
+
chunks.push(chunk);
|
|
201
|
+
}
|
|
202
|
+
return Buffer.concat(chunks);
|
|
203
|
+
}
|
|
204
|
+
async copyFile(oldKey, newKey) {
|
|
205
|
+
try {
|
|
206
|
+
await this.s3.send(new client_s3_1.CopyObjectCommand({
|
|
207
|
+
Bucket: this.options.bucket,
|
|
208
|
+
CopySource: `/${this.options.bucket}/${oldKey}`,
|
|
209
|
+
Key: newKey,
|
|
210
|
+
}));
|
|
211
|
+
const headObject = await this.s3.send(new client_s3_2.HeadObjectCommand({
|
|
212
|
+
Bucket: this.options.bucket,
|
|
213
|
+
Key: newKey,
|
|
214
|
+
}));
|
|
215
|
+
return {
|
|
216
|
+
originalName: (0, path_1.basename)(newKey),
|
|
217
|
+
size: headObject.ContentLength || 0,
|
|
218
|
+
fileName: (0, path_1.basename)(newKey),
|
|
219
|
+
key: newKey,
|
|
220
|
+
fullPath: newKey,
|
|
221
|
+
url: this.getUrl(newKey),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
console.error('Error copying file in S3:', error);
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
exports.S3Storage = S3Storage;
|
|
231
|
+
//# sourceMappingURL=s3.storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.storage.js","sourceRoot":"","sources":["../../../src/lib/storage/s3.storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FileStorageEnum, StorageOptions } from './types';
|
|
2
|
+
import { StorageEngine } from 'multer';
|
|
3
|
+
import { Storage } from './types';
|
|
4
|
+
export declare class StorageFactory {
|
|
5
|
+
private static storageInstances;
|
|
6
|
+
static createStorage(storageType: FileStorageEnum, options: StorageOptions): Promise<StorageEngine & Storage>;
|
|
7
|
+
static clearCache(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=storage.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.factory.d.ts","sourceRoot":"","sources":["../../src/lib/storage.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,eAAe,EAAyC,cAAc,EAAE,MAAM,SAAS,CAAC;AACtH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAA8C;WAEhE,aAAa,CAAC,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC;IA+CnH,MAAM,CAAC,UAAU;CAGpB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.StorageFactory = void 0;
|
|
37
|
+
const types_1 = require("./types");
|
|
38
|
+
class StorageFactory {
|
|
39
|
+
static async createStorage(storageType, options) {
|
|
40
|
+
const cacheKey = `${storageType}-${JSON.stringify(options)}`;
|
|
41
|
+
// if (this.storageInstances.has(cacheKey)) {
|
|
42
|
+
// return this.storageInstances.get(cacheKey)!;
|
|
43
|
+
// }
|
|
44
|
+
let storageInstance;
|
|
45
|
+
switch (storageType) {
|
|
46
|
+
case types_1.FileStorageEnum.LOCAL:
|
|
47
|
+
const { LocalStorage } = await Promise.resolve().then(() => __importStar(require('./storage/local.storage')));
|
|
48
|
+
storageInstance = new LocalStorage(options);
|
|
49
|
+
break;
|
|
50
|
+
case types_1.FileStorageEnum.AZURE:
|
|
51
|
+
try {
|
|
52
|
+
const { AzureStorage } = await Promise.resolve().then(() => __importStar(require('./storage/azure.storage')));
|
|
53
|
+
storageInstance = new AzureStorage(options);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
throw new Error('Azure Storage SDK (@azure/storage-blob) is required when using AzureStorage. ' +
|
|
57
|
+
'Please install it: npm install @azure/storage-blob');
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case types_1.FileStorageEnum.S3:
|
|
61
|
+
try {
|
|
62
|
+
const { S3Storage } = await Promise.resolve().then(() => __importStar(require('./storage/s3.storage')));
|
|
63
|
+
storageInstance = new S3Storage(options);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error('AWS SDK (@aws-sdk/client-s3 and @aws-sdk/s3-request-presigner) is required when using S3Storage. ' +
|
|
67
|
+
'Please install them: npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner');
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unsupported storage type: ${storageType}`);
|
|
72
|
+
}
|
|
73
|
+
this.storageInstances.set(cacheKey, storageInstance);
|
|
74
|
+
return storageInstance;
|
|
75
|
+
}
|
|
76
|
+
static clearCache() {
|
|
77
|
+
this.storageInstances.clear();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.StorageFactory = StorageFactory;
|
|
81
|
+
StorageFactory.storageInstances = new Map();
|
|
82
|
+
//# sourceMappingURL=storage.factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.factory.js","sourceRoot":"","sources":["../../src/lib/storage.factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mCAAsH;AAItH,MAAa,cAAc;IAGvB,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,WAA4B,EAAE,OAAuB;QAC5E,MAAM,QAAQ,GAAG,GAAG,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAE7D,6CAA6C;QAC7C,mDAAmD;QACnD,IAAI;QAEJ,IAAI,eAAwC,CAAC;QAE7C,QAAQ,WAAW,EAAE,CAAC;YAClB,KAAK,uBAAe,CAAC,KAAK;gBACtB,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,yBAAyB,GAAC,CAAC;gBACjE,eAAe,GAAG,IAAI,YAAY,CAAC,OAA8B,CAAC,CAAC;gBACnE,MAAM;YAEV,KAAK,uBAAe,CAAC,KAAK;gBACtB,IAAI,CAAC;oBACD,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,yBAAyB,GAAC,CAAC;oBACjE,eAAe,GAAG,IAAI,YAAY,CAAC,OAA8B,CAAC,CAAC;gBACvE,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CACX,+EAA+E;wBAC/E,oDAAoD,CACvD,CAAC;gBACN,CAAC;gBACD,MAAM;YAEV,KAAK,uBAAe,CAAC,EAAE;gBACnB,IAAI,CAAC;oBACD,MAAM,EAAE,SAAS,EAAE,GAAG,wDAAa,sBAAsB,GAAC,CAAC;oBAC3D,eAAe,GAAG,IAAI,SAAS,CAAC,OAA2B,CAAC,CAAC;gBACjE,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CACX,mGAAmG;wBACnG,mFAAmF,CACtF,CAAC;gBACN,CAAC;gBACD,MAAM;YAEV;gBACI,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QACrD,OAAO,eAAe,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,UAAU;QACb,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;;AApDL,wCAqDC;AApDkB,+BAAgB,GAAG,IAAI,GAAG,EAAmC,CAAC"}
|