@flusys/nestjs-storage 3.0.1 → 4.0.0-rc
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/cjs/config/index.js +1 -0
- package/cjs/config/message-keys.js +90 -0
- package/cjs/controllers/file-manager.controller.js +7 -1
- package/cjs/controllers/folder.controller.js +1 -0
- package/cjs/controllers/storage-config.controller.js +1 -0
- package/cjs/controllers/upload.controller.js +9 -4
- package/cjs/middlewares/file-serve.middleware.js +39 -15
- package/cjs/modules/storage.module.js +2 -2
- package/cjs/providers/azure-provider.optional.js +8 -5
- package/cjs/providers/local-provider.js +16 -14
- package/cjs/providers/s3-provider.optional.js +8 -5
- package/cjs/providers/sftp-provider.optional.js +13 -11
- package/cjs/providers/storage-factory.service.js +19 -10
- package/cjs/services/file-manager.service.js +30 -23
- package/cjs/services/folder.service.js +2 -1
- package/cjs/services/storage-datasource.provider.js +6 -2
- package/cjs/services/storage-provider-config.service.js +2 -1
- package/cjs/services/upload.service.js +129 -79
- package/cjs/utils/file-validator.util.js +4 -22
- package/config/index.d.ts +1 -0
- package/config/message-keys.d.ts +114 -0
- package/controllers/folder.controller.d.ts +7 -7
- package/controllers/storage-config.controller.d.ts +7 -7
- package/controllers/upload.controller.d.ts +1 -1
- package/fesm/config/index.js +1 -0
- package/fesm/config/message-keys.js +64 -0
- package/fesm/controllers/file-manager.controller.js +7 -1
- package/fesm/controllers/folder.controller.js +1 -0
- package/fesm/controllers/storage-config.controller.js +1 -0
- package/fesm/controllers/upload.controller.js +9 -4
- package/fesm/middlewares/file-serve.middleware.js +40 -16
- package/fesm/modules/storage.module.js +2 -2
- package/fesm/providers/azure-provider.optional.js +9 -6
- package/fesm/providers/local-provider.js +28 -26
- package/fesm/providers/s3-provider.optional.js +9 -6
- package/fesm/providers/sftp-provider.optional.js +26 -24
- package/fesm/providers/storage-factory.service.js +20 -11
- package/fesm/services/file-manager.service.js +31 -24
- package/fesm/services/folder.service.js +2 -1
- package/fesm/services/storage-datasource.provider.js +7 -3
- package/fesm/services/storage-provider-config.service.js +2 -1
- package/fesm/services/upload.service.js +131 -81
- package/fesm/utils/file-validator.util.js +3 -21
- package/middlewares/file-serve.middleware.d.ts +0 -1
- package/package.json +3 -3
- package/providers/azure-provider.optional.d.ts +0 -1
- package/providers/local-provider.d.ts +0 -1
- package/providers/s3-provider.optional.d.ts +0 -1
- package/providers/sftp-provider.optional.d.ts +0 -1
- package/providers/storage-factory.service.d.ts +0 -1
- package/services/file-manager.service.d.ts +2 -2
- package/services/storage-datasource.provider.d.ts +0 -2
- package/services/upload.service.d.ts +0 -1
- package/utils/file-validator.util.d.ts +0 -1
|
@@ -25,9 +25,13 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
28
|
+
import { LogAction } from '@flusys/nestjs-shared';
|
|
29
|
+
import { UPLOAD_MESSAGES } from '../config';
|
|
30
|
+
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
31
|
+
import { validateCompanyOwnership } from '@flusys/nestjs-shared/utils';
|
|
32
|
+
import { BadRequestException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
|
|
30
33
|
import { StorageConfigService } from './storage-config.service';
|
|
34
|
+
import { UploadOptionsDto } from '../dtos/upload.dto';
|
|
31
35
|
import { FileLocationEnum } from '../enums/file-location.enum';
|
|
32
36
|
import { StorageFactoryService } from '../providers/storage-factory.service';
|
|
33
37
|
import { StorageProviderConfigService } from './storage-provider-config.service';
|
|
@@ -40,23 +44,28 @@ export class UploadService {
|
|
|
40
44
|
// Validate file size
|
|
41
45
|
const sizeValidation = this.storageConfigService.validateFileSize(file.size);
|
|
42
46
|
if (!sizeValidation.valid) {
|
|
43
|
-
throw new BadRequestException(
|
|
47
|
+
throw new BadRequestException({
|
|
48
|
+
message: sizeValidation.message,
|
|
49
|
+
messageKey: UPLOAD_MESSAGES.FILE_TOO_LARGE
|
|
50
|
+
});
|
|
44
51
|
}
|
|
45
52
|
// Validate declared file type (MIME)
|
|
46
53
|
const typeValidation = this.storageConfigService.validateFileType(file.mimetype);
|
|
47
54
|
if (!typeValidation.valid) {
|
|
48
|
-
throw new BadRequestException(
|
|
55
|
+
throw new BadRequestException({
|
|
56
|
+
message: typeValidation.message,
|
|
57
|
+
messageKey: UPLOAD_MESSAGES.INVALID_TYPE
|
|
58
|
+
});
|
|
49
59
|
}
|
|
50
60
|
// Validate file content matches declared type (magic bytes check)
|
|
51
61
|
// This prevents MIME type spoofing attacks
|
|
52
62
|
const allowedTypes = this.storageConfigService.getAllowedFileTypes();
|
|
53
63
|
const contentValidation = FileValidator.validateFileContent(file.buffer, file.mimetype, allowedTypes);
|
|
54
64
|
if (!contentValidation.valid) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
throw new BadRequestException({
|
|
66
|
+
message: contentValidation.message || 'File content validation failed',
|
|
67
|
+
messageKey: UPLOAD_MESSAGES.INVALID_TYPE
|
|
58
68
|
});
|
|
59
|
-
throw new BadRequestException(contentValidation.message || 'File content validation failed');
|
|
60
69
|
}
|
|
61
70
|
// Sanitize filename to prevent path traversal attacks
|
|
62
71
|
file.originalname = FileValidator.sanitizeFilename(file.originalname);
|
|
@@ -72,7 +81,6 @@ export class UploadService {
|
|
|
72
81
|
/**
|
|
73
82
|
* Create fallback local provider
|
|
74
83
|
*/ async createFallbackLocalProvider() {
|
|
75
|
-
this.logger.warn('No storage config found, using fallback local provider');
|
|
76
84
|
return this.storageFactory.createProvider({
|
|
77
85
|
provider: FileLocationEnum.LOCAL,
|
|
78
86
|
config: {
|
|
@@ -90,7 +98,10 @@ export class UploadService {
|
|
|
90
98
|
// Use direct lookup (bypasses company filtering, returns null instead of throwing)
|
|
91
99
|
const config = await this.storageProviderConfigService.findByIdDirect(storageConfigId);
|
|
92
100
|
if (!config) {
|
|
93
|
-
throw new NotFoundException(
|
|
101
|
+
throw new NotFoundException({
|
|
102
|
+
message: 'Storage configuration not found',
|
|
103
|
+
messageKey: UPLOAD_MESSAGES.CONFIG_NOT_FOUND
|
|
104
|
+
});
|
|
94
105
|
}
|
|
95
106
|
// Validate company ownership using shared utility
|
|
96
107
|
validateCompanyOwnership(config, user, this.storageConfigService.isCompanyFeatureEnabled(), 'Storage configuration');
|
|
@@ -99,7 +110,10 @@ export class UploadService {
|
|
|
99
110
|
// Use default config (scoped to user's company/branch)
|
|
100
111
|
const defaultConfig = await this.storageProviderConfigService.getDefaultConfig(user);
|
|
101
112
|
if (!defaultConfig) {
|
|
102
|
-
throw new NotFoundException(
|
|
113
|
+
throw new NotFoundException({
|
|
114
|
+
message: 'No default storage configuration found for your company/branch. Please create one.',
|
|
115
|
+
messageKey: UPLOAD_MESSAGES.CONFIG_NOT_FOUND
|
|
116
|
+
});
|
|
103
117
|
}
|
|
104
118
|
storageConfig = defaultConfig;
|
|
105
119
|
}
|
|
@@ -120,7 +134,6 @@ export class UploadService {
|
|
|
120
134
|
if (config) {
|
|
121
135
|
return this.createProviderFromConfig(config);
|
|
122
136
|
}
|
|
123
|
-
this.logger.warn(`Storage config ${storageConfigId} not found, trying fallback`);
|
|
124
137
|
}
|
|
125
138
|
// Fallback: Use locationHint to find a matching config
|
|
126
139
|
if (locationHint) {
|
|
@@ -140,62 +153,44 @@ export class UploadService {
|
|
|
140
153
|
return this.createFallbackLocalProvider();
|
|
141
154
|
}
|
|
142
155
|
async uploadSingleFile(file, options, user) {
|
|
143
|
-
|
|
144
|
-
|
|
156
|
+
this.validateFile(file);
|
|
157
|
+
const { provider, location, configId } = await this.getStorageProviderWithConfig(options.storageConfigId, user);
|
|
158
|
+
const result = await provider.uploadFile(file, options);
|
|
159
|
+
return {
|
|
160
|
+
...result,
|
|
161
|
+
location,
|
|
162
|
+
storageConfigId: configId
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async uploadMultipleFiles(files, options, user) {
|
|
166
|
+
for (const file of files){
|
|
145
167
|
this.validateFile(file);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
168
|
+
}
|
|
169
|
+
const { provider, location, configId } = await this.getStorageProviderWithConfig(options.storageConfigId, user);
|
|
170
|
+
const results = await provider.uploadMultipleFiles(files, options);
|
|
171
|
+
return results.map((result)=>({
|
|
150
172
|
...result,
|
|
151
173
|
location,
|
|
152
174
|
storageConfigId: configId
|
|
153
|
-
};
|
|
154
|
-
} catch (error) {
|
|
155
|
-
ErrorHandler.logError(this.logger, error, 'uploadSingleFile');
|
|
156
|
-
ErrorHandler.rethrowError(error);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
async uploadMultipleFiles(files, options, user) {
|
|
160
|
-
try {
|
|
161
|
-
// Validate each file before upload
|
|
162
|
-
for (const file of files){
|
|
163
|
-
this.validateFile(file);
|
|
164
|
-
}
|
|
165
|
-
const { provider, location, configId } = await this.getStorageProviderWithConfig(options.storageConfigId, user);
|
|
166
|
-
const results = await provider.uploadMultipleFiles(files, options);
|
|
167
|
-
// Enrich results with storage info
|
|
168
|
-
return results.map((result)=>({
|
|
169
|
-
...result,
|
|
170
|
-
location,
|
|
171
|
-
storageConfigId: configId
|
|
172
|
-
}));
|
|
173
|
-
} catch (error) {
|
|
174
|
-
ErrorHandler.logError(this.logger, error, 'uploadMultipleFiles');
|
|
175
|
-
ErrorHandler.rethrowError(error);
|
|
176
|
-
}
|
|
175
|
+
}));
|
|
177
176
|
}
|
|
178
177
|
async deleteSingleFile(key, storageConfigId, user, locationHint) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
ErrorHandler.rethrowError(error);
|
|
187
|
-
}
|
|
178
|
+
if (!key) throw new BadRequestException({
|
|
179
|
+
message: 'No file path provided',
|
|
180
|
+
messageKey: UPLOAD_MESSAGES.NO_FILE_PATH
|
|
181
|
+
});
|
|
182
|
+
const provider = await this.getStorageProviderForDelete(storageConfigId, user, locationHint);
|
|
183
|
+
await provider.deleteFile(key);
|
|
184
|
+
return true;
|
|
188
185
|
}
|
|
189
186
|
async deleteMultipleFile(keys, storageConfigId, user, locationHint) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
ErrorHandler.rethrowError(error);
|
|
198
|
-
}
|
|
187
|
+
if (!keys || !keys.length) throw new BadRequestException({
|
|
188
|
+
message: 'No file paths provided',
|
|
189
|
+
messageKey: UPLOAD_MESSAGES.NO_FILE_PATH
|
|
190
|
+
});
|
|
191
|
+
const provider = await this.getStorageProviderForDelete(storageConfigId, user, locationHint);
|
|
192
|
+
await provider.deleteMultipleFiles(keys);
|
|
193
|
+
return true;
|
|
199
194
|
}
|
|
200
195
|
bytesToKb(bytes) {
|
|
201
196
|
return Number((bytes * 0.001).toFixed(2));
|
|
@@ -223,42 +218,97 @@ export class UploadService {
|
|
|
223
218
|
return this.storageFactory.getLocalProviderBasePath();
|
|
224
219
|
}
|
|
225
220
|
return null;
|
|
226
|
-
} catch
|
|
227
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
228
|
-
this.logger.warn(`Failed to get local storage basePath: ${errorMessage}`);
|
|
221
|
+
} catch {
|
|
229
222
|
return null;
|
|
230
223
|
}
|
|
231
224
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
try {
|
|
238
|
-
const { provider } = await this.getStorageProviderWithConfig(storageConfigId, user);
|
|
239
|
-
// Check if provider supports presigned URLs
|
|
240
|
-
if (provider.generatePresignedUrl) {
|
|
241
|
-
return await provider.generatePresignedUrl(key, expiresIn);
|
|
242
|
-
}
|
|
243
|
-
// For SFTP or other providers without presigned URLs
|
|
244
|
-
return key;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
ErrorHandler.logError(this.logger, error, 'makeFileUrl');
|
|
247
|
-
ErrorHandler.rethrowError(error);
|
|
225
|
+
async makeFileUrl(key, storageConfigId, expiresIn = 3600, user) {
|
|
226
|
+
const { provider } = await this.getStorageProviderWithConfig(storageConfigId, user);
|
|
227
|
+
// Check if provider supports presigned URLs
|
|
228
|
+
if (provider.generatePresignedUrl) {
|
|
229
|
+
return await provider.generatePresignedUrl(key, expiresIn);
|
|
248
230
|
}
|
|
231
|
+
// For SFTP or other providers without presigned URLs
|
|
232
|
+
return key;
|
|
249
233
|
}
|
|
250
234
|
// NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
|
|
251
235
|
constructor(storageFactory, storageConfigService, storageProviderConfigService){
|
|
252
236
|
_define_property(this, "storageFactory", void 0);
|
|
253
237
|
_define_property(this, "storageConfigService", void 0);
|
|
254
238
|
_define_property(this, "storageProviderConfigService", void 0);
|
|
255
|
-
_define_property(this, "logger", void 0);
|
|
256
239
|
this.storageFactory = storageFactory;
|
|
257
240
|
this.storageConfigService = storageConfigService;
|
|
258
241
|
this.storageProviderConfigService = storageProviderConfigService;
|
|
259
|
-
this.logger = new Logger(UploadService.name);
|
|
260
242
|
}
|
|
261
243
|
}
|
|
244
|
+
_ts_decorate([
|
|
245
|
+
LogAction({
|
|
246
|
+
action: 'storage.uploadSingle',
|
|
247
|
+
module: 'storage'
|
|
248
|
+
}),
|
|
249
|
+
_ts_metadata("design:type", Function),
|
|
250
|
+
_ts_metadata("design:paramtypes", [
|
|
251
|
+
typeof Express === "undefined" || typeof Express.Multer === "undefined" || typeof Express.Multer.File === "undefined" ? Object : Express.Multer.File,
|
|
252
|
+
typeof UploadOptionsDto === "undefined" ? Object : UploadOptionsDto,
|
|
253
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
254
|
+
]),
|
|
255
|
+
_ts_metadata("design:returntype", Promise)
|
|
256
|
+
], UploadService.prototype, "uploadSingleFile", null);
|
|
257
|
+
_ts_decorate([
|
|
258
|
+
LogAction({
|
|
259
|
+
action: 'storage.uploadMultiple',
|
|
260
|
+
module: 'storage'
|
|
261
|
+
}),
|
|
262
|
+
_ts_metadata("design:type", Function),
|
|
263
|
+
_ts_metadata("design:paramtypes", [
|
|
264
|
+
Array,
|
|
265
|
+
typeof UploadOptionsDto === "undefined" ? Object : UploadOptionsDto,
|
|
266
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
267
|
+
]),
|
|
268
|
+
_ts_metadata("design:returntype", Promise)
|
|
269
|
+
], UploadService.prototype, "uploadMultipleFiles", null);
|
|
270
|
+
_ts_decorate([
|
|
271
|
+
LogAction({
|
|
272
|
+
action: 'storage.deleteSingle',
|
|
273
|
+
module: 'storage'
|
|
274
|
+
}),
|
|
275
|
+
_ts_metadata("design:type", Function),
|
|
276
|
+
_ts_metadata("design:paramtypes", [
|
|
277
|
+
String,
|
|
278
|
+
String,
|
|
279
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo,
|
|
280
|
+
String
|
|
281
|
+
]),
|
|
282
|
+
_ts_metadata("design:returntype", Promise)
|
|
283
|
+
], UploadService.prototype, "deleteSingleFile", null);
|
|
284
|
+
_ts_decorate([
|
|
285
|
+
LogAction({
|
|
286
|
+
action: 'storage.deleteMultiple',
|
|
287
|
+
module: 'storage'
|
|
288
|
+
}),
|
|
289
|
+
_ts_metadata("design:type", Function),
|
|
290
|
+
_ts_metadata("design:paramtypes", [
|
|
291
|
+
Array,
|
|
292
|
+
String,
|
|
293
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo,
|
|
294
|
+
String
|
|
295
|
+
]),
|
|
296
|
+
_ts_metadata("design:returntype", Promise)
|
|
297
|
+
], UploadService.prototype, "deleteMultipleFile", null);
|
|
298
|
+
_ts_decorate([
|
|
299
|
+
LogAction({
|
|
300
|
+
action: 'storage.makeFileUrl',
|
|
301
|
+
module: 'storage'
|
|
302
|
+
}),
|
|
303
|
+
_ts_metadata("design:type", Function),
|
|
304
|
+
_ts_metadata("design:paramtypes", [
|
|
305
|
+
String,
|
|
306
|
+
String,
|
|
307
|
+
Number,
|
|
308
|
+
typeof ILoggedUserInfo === "undefined" ? Object : ILoggedUserInfo
|
|
309
|
+
]),
|
|
310
|
+
_ts_metadata("design:returntype", Promise)
|
|
311
|
+
], UploadService.prototype, "makeFileUrl", null);
|
|
262
312
|
UploadService = _ts_decorate([
|
|
263
313
|
Injectable({
|
|
264
314
|
scope: Scope.REQUEST
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
import { Logger } from '@nestjs/common';
|
|
15
1
|
/**
|
|
2
|
+
* Result of file content validation.
|
|
3
|
+
*/ /**
|
|
16
4
|
* Magic byte signatures for common file types.
|
|
17
5
|
* Each entry maps a hex signature pattern to its MIME type.
|
|
18
6
|
*/ const MAGIC_BYTES = [
|
|
@@ -401,7 +389,6 @@ import { Logger } from '@nestjs/common';
|
|
|
401
389
|
}
|
|
402
390
|
// Verify detected type matches declared type
|
|
403
391
|
if (!this.mimeTypesMatch(detectedType, declaredMimeType)) {
|
|
404
|
-
this.logger.warn(`MIME type mismatch: declared=${declaredMimeType}, detected=${detectedType}`);
|
|
405
392
|
return this.failureResult(`File content does not match declared type. Detected: ${detectedType}, Declared: ${declaredMimeType}`, detectedType, declaredMimeType);
|
|
406
393
|
}
|
|
407
394
|
// Verify type is in allowed list
|
|
@@ -409,8 +396,7 @@ import { Logger } from '@nestjs/common';
|
|
|
409
396
|
return this.failureResult(`File type "${detectedType}" is not allowed`, detectedType, declaredMimeType);
|
|
410
397
|
}
|
|
411
398
|
return this.successResult(detectedType, declaredMimeType);
|
|
412
|
-
} catch
|
|
413
|
-
this.logger.error('File validation error:', error);
|
|
399
|
+
} catch {
|
|
414
400
|
return this.failureResult('File validation failed');
|
|
415
401
|
}
|
|
416
402
|
}
|
|
@@ -421,10 +407,8 @@ import { Logger } from '@nestjs/common';
|
|
|
421
407
|
if (this.isDangerousTextType(declaredMimeType)) {
|
|
422
408
|
const explicitlyAllowed = allowedTypes.some((t)=>t === declaredMimeType && t !== '*/*' && !t.endsWith('/*'));
|
|
423
409
|
if (!explicitlyAllowed) {
|
|
424
|
-
this.logger.warn(`Blocked dangerous file type: ${declaredMimeType} - requires explicit allowlisting`);
|
|
425
410
|
return this.failureResult(`File type "${declaredMimeType}" is potentially dangerous and not explicitly allowed`, declaredMimeType, declaredMimeType);
|
|
426
411
|
}
|
|
427
|
-
this.logger.warn(`Allowing explicitly permitted dangerous file type: ${declaredMimeType}`);
|
|
428
412
|
}
|
|
429
413
|
// Safe text-based files don't have magic bytes, trust declared type
|
|
430
414
|
if (this.isTextBasedType(declaredMimeType)) {
|
|
@@ -432,7 +416,6 @@ import { Logger } from '@nestjs/common';
|
|
|
432
416
|
return isAllowed ? this.successResult(declaredMimeType, declaredMimeType) : this.failureResult(`File type "${declaredMimeType}" is not allowed`, declaredMimeType, declaredMimeType);
|
|
433
417
|
}
|
|
434
418
|
// Binary files without recognized signatures - be cautious
|
|
435
|
-
this.logger.warn(`Unable to detect file type for declared type: ${declaredMimeType}`);
|
|
436
419
|
return this.failureResult('Unable to verify file type. File may be corrupted or unsupported.', undefined, declaredMimeType);
|
|
437
420
|
}
|
|
438
421
|
/**
|
|
@@ -448,4 +431,3 @@ import { Logger } from '@nestjs/common';
|
|
|
448
431
|
.substring(0, 255);
|
|
449
432
|
}
|
|
450
433
|
}
|
|
451
|
-
_define_property(FileValidator, "logger", new Logger(FileValidator.name));
|
|
@@ -3,7 +3,6 @@ import { Request, Response, NextFunction } from 'express';
|
|
|
3
3
|
import { UploadService } from '../services/upload.service';
|
|
4
4
|
export declare class FileServeMiddleware implements NestMiddleware {
|
|
5
5
|
private uploadService;
|
|
6
|
-
private readonly logger;
|
|
7
6
|
private readonly uploadDir;
|
|
8
7
|
constructor(uploadService: UploadService);
|
|
9
8
|
use(req: Request, res: Response, next: NextFunction): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/nestjs-storage",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc",
|
|
4
4
|
"description": "Modular storage package with optional AWS S3, Azure Blob, and SFTP providers",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "fesm/index.js",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
}
|
|
129
129
|
},
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"@flusys/nestjs-core": "
|
|
132
|
-
"@flusys/nestjs-shared": "
|
|
131
|
+
"@flusys/nestjs-core": "4.0.0-rc",
|
|
132
|
+
"@flusys/nestjs-shared": "4.0.0-rc"
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { UploadOptionsDto } from '../dtos/upload.dto';
|
|
2
2
|
import { IStorageProvider, IUploadedFileInfo } from '../interfaces/storage-provider.interface';
|
|
3
3
|
export declare class LocalProvider implements IStorageProvider {
|
|
4
|
-
private logger;
|
|
5
4
|
private basePath;
|
|
6
5
|
private baseUrl;
|
|
7
6
|
private relativeBasePath;
|
|
@@ -3,7 +3,6 @@ import { IStorageProvider, IStorageProviderConfig } from '../interfaces/storage-
|
|
|
3
3
|
import { StorageConfigService } from '../services';
|
|
4
4
|
export declare class StorageFactoryService implements OnModuleDestroy {
|
|
5
5
|
private readonly configService;
|
|
6
|
-
private readonly logger;
|
|
7
6
|
private readonly cache;
|
|
8
7
|
constructor(configService: StorageConfigService);
|
|
9
8
|
createProvider(config: IStorageProviderConfig): Promise<IStorageProvider>;
|
|
@@ -23,7 +23,7 @@ export declare class FileManagerService extends RequestScopedApiService<CreateFi
|
|
|
23
23
|
query: SelectQueryBuilder<FileManager>;
|
|
24
24
|
isRaw: boolean;
|
|
25
25
|
}>;
|
|
26
|
-
protected getFilterQuery(query: SelectQueryBuilder<FileManagerBase>, filter: Record<string,
|
|
26
|
+
protected getFilterQuery(query: SelectQueryBuilder<FileManagerBase>, filter: Record<string, unknown>, _user: ILoggedUserInfo | null): Promise<{
|
|
27
27
|
query: SelectQueryBuilder<FileManagerBase>;
|
|
28
28
|
isRaw: boolean;
|
|
29
29
|
}>;
|
|
@@ -38,8 +38,8 @@ export declare class FileManagerService extends RequestScopedApiService<CreateFi
|
|
|
38
38
|
providerName?: string;
|
|
39
39
|
})[]>;
|
|
40
40
|
getFiles(dtos: GetFilesRequestDto[], protocol: string, host: string, user?: ILoggedUserInfo): Promise<FilesResponseDto[]>;
|
|
41
|
-
private getStorageConfigRepository;
|
|
42
41
|
private buildWhereWithCompany;
|
|
42
|
+
private getStorageConfigRepository;
|
|
43
43
|
private getStorageConfigBasePath;
|
|
44
44
|
private validateFolder;
|
|
45
45
|
private resolveStorageLocation;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
2
2
|
import { IDatabaseConfig, ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
3
|
-
import { Logger } from '@nestjs/common';
|
|
4
3
|
import { Request } from 'express';
|
|
5
4
|
import { DataSource } from 'typeorm';
|
|
6
5
|
import { StorageConfigService } from './storage-config.service';
|
|
7
6
|
export declare class StorageDataSourceProvider extends MultiTenantDataSourceService {
|
|
8
7
|
private readonly configService;
|
|
9
|
-
protected readonly logger: Logger;
|
|
10
8
|
protected static readonly tenantConnections: Map<string, DataSource>;
|
|
11
9
|
protected static singleDataSource: DataSource | null;
|
|
12
10
|
protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
|
|
@@ -8,7 +8,6 @@ export declare class UploadService {
|
|
|
8
8
|
private readonly storageFactory;
|
|
9
9
|
private readonly storageConfigService;
|
|
10
10
|
private readonly storageProviderConfigService;
|
|
11
|
-
private logger;
|
|
12
11
|
constructor(storageFactory: StorageFactoryService, storageConfigService: StorageConfigService, storageProviderConfigService: StorageProviderConfigService);
|
|
13
12
|
private validateFile;
|
|
14
13
|
private createProviderFromConfig;
|