@flusys/nestjs-storage 0.1.0-beta.2 → 1.0.0-beta
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/README.md +3 -7
- package/cjs/config/storage-config.service.js +31 -0
- package/cjs/controllers/file-manager.controller.js +8 -6
- package/cjs/controllers/folder.controller.js +3 -4
- package/cjs/controllers/storage-config.controller.js +3 -4
- package/cjs/controllers/upload.controller.js +22 -169
- package/cjs/dtos/file-manager.dto.js +36 -2
- package/cjs/dtos/upload.dto.js +16 -0
- package/cjs/middlewares/file-serve.middleware.js +204 -0
- package/cjs/middlewares/index.js +18 -0
- package/cjs/modules/storage.module.js +58 -14
- package/cjs/providers/azure-provider.optional.js +1 -2
- package/cjs/providers/local-provider.js +43 -11
- package/cjs/providers/storage-factory.service.js +49 -5
- package/cjs/services/file-manager.service.js +134 -9
- package/cjs/services/folder.service.js +17 -48
- package/cjs/services/storage-datasource.provider.js +10 -16
- package/cjs/services/storage-provider-config.service.js +26 -32
- package/cjs/services/upload.service.js +135 -24
- package/cjs/utils/image-compressor.util.js +43 -5
- package/config/storage-config.service.d.ts +2 -0
- package/controllers/file-manager.controller.d.ts +1 -1
- package/controllers/upload.controller.d.ts +5 -4
- package/dtos/file-manager.dto.d.ts +4 -0
- package/dtos/upload.dto.d.ts +2 -0
- package/fesm/config/storage-config.service.js +31 -0
- package/fesm/controllers/file-manager.controller.js +8 -6
- package/fesm/controllers/folder.controller.js +5 -6
- package/fesm/controllers/storage-config.controller.js +5 -6
- package/fesm/controllers/upload.controller.js +25 -131
- package/fesm/dtos/file-manager.dto.js +36 -2
- package/fesm/dtos/upload.dto.js +16 -0
- package/fesm/middlewares/file-serve.middleware.js +153 -0
- package/fesm/middlewares/index.js +1 -0
- package/fesm/modules/storage.module.js +60 -16
- package/fesm/providers/azure-provider.optional.js +1 -2
- package/fesm/providers/local-provider.js +43 -11
- package/fesm/providers/storage-factory.service.js +50 -6
- package/fesm/services/file-manager.service.js +134 -9
- package/fesm/services/folder.service.js +18 -49
- package/fesm/services/storage-datasource.provider.js +10 -16
- package/fesm/services/storage-provider-config.service.js +26 -32
- package/fesm/services/upload.service.js +135 -24
- package/fesm/utils/image-compressor.util.js +3 -1
- package/interfaces/file-manager.interface.d.ts +2 -0
- package/interfaces/storage-module-options.interface.d.ts +2 -0
- package/interfaces/storage-provider.interface.d.ts +2 -0
- package/middlewares/file-serve.middleware.d.ts +9 -0
- package/middlewares/index.d.ts +1 -0
- package/modules/storage.module.d.ts +3 -2
- package/package.json +26 -11
- package/providers/local-provider.d.ts +2 -1
- package/providers/storage-factory.service.d.ts +4 -0
- package/services/file-manager.service.d.ts +7 -1
- package/services/folder.service.d.ts +1 -2
- package/services/storage-provider-config.service.d.ts +2 -2
- package/services/upload.service.d.ts +6 -2
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "UploadService", {
|
|
|
10
10
|
});
|
|
11
11
|
const _common = require("@nestjs/common");
|
|
12
12
|
const _config = require("../config");
|
|
13
|
+
const _filelocationenum = require("../enums/file-location.enum");
|
|
13
14
|
const _storagefactoryservice = require("../providers/storage-factory.service");
|
|
14
15
|
const _storageproviderconfigservice = require("./storage-provider-config.service");
|
|
15
16
|
function _define_property(obj, key, value) {
|
|
@@ -55,19 +56,14 @@ let UploadService = class UploadService {
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
/**
|
|
58
|
-
* Get storage provider based on storage config ID
|
|
59
|
+
* Get storage provider and config info based on storage config ID
|
|
59
60
|
* Validates company ownership when company feature is enabled
|
|
60
|
-
*/ async
|
|
61
|
+
*/ async getStorageProviderWithConfig(storageConfigId, user) {
|
|
61
62
|
let storageConfig;
|
|
62
|
-
// Get storage config from database
|
|
63
|
+
// Get storage config from database
|
|
63
64
|
if (storageConfigId) {
|
|
64
|
-
//
|
|
65
|
-
const config = await this.storageProviderConfigService.
|
|
66
|
-
'name',
|
|
67
|
-
'storage',
|
|
68
|
-
'config',
|
|
69
|
-
'companyId'
|
|
70
|
-
]);
|
|
65
|
+
// Use direct lookup (bypasses company filtering, returns null instead of throwing)
|
|
66
|
+
const config = await this.storageProviderConfigService.findByIdDirect(storageConfigId);
|
|
71
67
|
if (!config) {
|
|
72
68
|
throw new _common.NotFoundException('Storage configuration not found');
|
|
73
69
|
}
|
|
@@ -93,17 +89,98 @@ let UploadService = class UploadService {
|
|
|
93
89
|
config: storageConfig.config
|
|
94
90
|
};
|
|
95
91
|
// Get or create provider instance
|
|
96
|
-
|
|
92
|
+
const provider = await this.storageFactory.createProvider(providerConfig);
|
|
93
|
+
return {
|
|
94
|
+
provider,
|
|
95
|
+
location: storageConfig.storage,
|
|
96
|
+
configId: storageConfig.id
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get storage provider based on storage config ID (convenience method)
|
|
101
|
+
*/ async getStorageProvider(storageConfigId, user) {
|
|
102
|
+
const { provider } = await this.getStorageProviderWithConfig(storageConfigId, user);
|
|
103
|
+
return provider;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get storage provider for delete operations with fallback
|
|
107
|
+
* If the original storage config doesn't exist, falls back based on locationHint
|
|
108
|
+
* This ensures files can still be deleted even if storage config was removed
|
|
109
|
+
* @param storageConfigId - The storage config ID to look up
|
|
110
|
+
* @param user - User context for company filtering
|
|
111
|
+
* @param locationHint - The file's original location type (used for fallback)
|
|
112
|
+
*/ async getStorageProviderForDelete(storageConfigId, user, locationHint) {
|
|
113
|
+
// If storageConfigId provided, try to find it
|
|
114
|
+
if (storageConfigId) {
|
|
115
|
+
const config = await this.storageProviderConfigService.findByIdDirect(storageConfigId);
|
|
116
|
+
if (config) {
|
|
117
|
+
const providerConfig = {
|
|
118
|
+
provider: config.storage,
|
|
119
|
+
config: config.config
|
|
120
|
+
};
|
|
121
|
+
return await this.storageFactory.createProvider(providerConfig);
|
|
122
|
+
}
|
|
123
|
+
// Config not found, log warning and try fallback
|
|
124
|
+
this.logger.warn(`Storage config ${storageConfigId} not found, trying fallback for delete`);
|
|
125
|
+
}
|
|
126
|
+
// Fallback: Use locationHint to find a matching config or create provider
|
|
127
|
+
if (locationHint) {
|
|
128
|
+
// Try to find a config matching the file's original location type
|
|
129
|
+
const matchingConfigs = await this.storageProviderConfigService.getConfigByType(locationHint, user);
|
|
130
|
+
if (matchingConfigs.length > 0) {
|
|
131
|
+
const providerConfig = {
|
|
132
|
+
provider: matchingConfigs[0].storage,
|
|
133
|
+
config: matchingConfigs[0].config
|
|
134
|
+
};
|
|
135
|
+
this.logger.debug(`Using matching ${locationHint} config for delete fallback`);
|
|
136
|
+
return await this.storageFactory.createProvider(providerConfig);
|
|
137
|
+
}
|
|
138
|
+
// No matching config found, create a basic provider based on locationHint
|
|
139
|
+
if (locationHint === _filelocationenum.FileLocationEnum.LOCAL) {
|
|
140
|
+
this.logger.warn('No local config found, using fallback local provider for delete');
|
|
141
|
+
const localProviderConfig = {
|
|
142
|
+
provider: _filelocationenum.FileLocationEnum.LOCAL,
|
|
143
|
+
config: {
|
|
144
|
+
basePath: this.storageConfigService.getDefaultLocalStoragePath()
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
return await this.storageFactory.createProvider(localProviderConfig);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Last resort: Try default config (might be different provider type)
|
|
151
|
+
const defaultConfig = await this.storageProviderConfigService.getDefaultConfig(user);
|
|
152
|
+
if (defaultConfig) {
|
|
153
|
+
const providerConfig = {
|
|
154
|
+
provider: defaultConfig.storage,
|
|
155
|
+
config: defaultConfig.config
|
|
156
|
+
};
|
|
157
|
+
return await this.storageFactory.createProvider(providerConfig);
|
|
158
|
+
}
|
|
159
|
+
// Final fallback: Create a basic local provider
|
|
160
|
+
this.logger.warn('No storage config found, using fallback local provider for delete');
|
|
161
|
+
const localProviderConfig = {
|
|
162
|
+
provider: _filelocationenum.FileLocationEnum.LOCAL,
|
|
163
|
+
config: {
|
|
164
|
+
basePath: this.storageConfigService.getDefaultLocalStoragePath()
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
return await this.storageFactory.createProvider(localProviderConfig);
|
|
97
168
|
}
|
|
98
169
|
async uploadSingleFile(file, options, user) {
|
|
99
170
|
try {
|
|
100
171
|
// Validate file before upload
|
|
101
172
|
this.validateFile(file);
|
|
102
|
-
const provider = await this.
|
|
103
|
-
|
|
173
|
+
const { provider, location, configId } = await this.getStorageProviderWithConfig(options.storageConfigId, user);
|
|
174
|
+
const result = await provider.uploadFile(file, options);
|
|
175
|
+
// Enrich result with storage info
|
|
176
|
+
return {
|
|
177
|
+
...result,
|
|
178
|
+
location,
|
|
179
|
+
storageConfigId: configId
|
|
180
|
+
};
|
|
104
181
|
} catch (err) {
|
|
105
182
|
this.logger.error('Single file upload failed', err);
|
|
106
|
-
throw new _common.InternalServerErrorException(err
|
|
183
|
+
throw new _common.InternalServerErrorException(err?.message || 'Single file upload failed');
|
|
107
184
|
}
|
|
108
185
|
}
|
|
109
186
|
async uploadMultipleFiles(files, options, user) {
|
|
@@ -112,39 +189,73 @@ let UploadService = class UploadService {
|
|
|
112
189
|
for (const file of files){
|
|
113
190
|
this.validateFile(file);
|
|
114
191
|
}
|
|
115
|
-
const provider = await this.
|
|
116
|
-
|
|
192
|
+
const { provider, location, configId } = await this.getStorageProviderWithConfig(options.storageConfigId, user);
|
|
193
|
+
const results = await provider.uploadMultipleFiles(files, options);
|
|
194
|
+
// Enrich results with storage info
|
|
195
|
+
return results.map((result)=>({
|
|
196
|
+
...result,
|
|
197
|
+
location,
|
|
198
|
+
storageConfigId: configId
|
|
199
|
+
}));
|
|
117
200
|
} catch (err) {
|
|
118
201
|
this.logger.error('Multiple files upload failed', err);
|
|
119
|
-
throw new _common.InternalServerErrorException(err
|
|
202
|
+
throw new _common.InternalServerErrorException(err?.message || 'Multiple files upload failed');
|
|
120
203
|
}
|
|
121
204
|
}
|
|
122
|
-
async deleteSingleFile(key, storageConfigId, user) {
|
|
205
|
+
async deleteSingleFile(key, storageConfigId, user, locationHint) {
|
|
123
206
|
try {
|
|
124
207
|
if (!key) throw new Error('No file path provided');
|
|
125
|
-
const provider = await this.
|
|
208
|
+
const provider = await this.getStorageProviderForDelete(storageConfigId, user, locationHint);
|
|
126
209
|
await provider.deleteFile(key);
|
|
127
210
|
return true;
|
|
128
211
|
} catch (err) {
|
|
129
212
|
this.logger.error('Delete single file failed', err);
|
|
130
|
-
throw new _common.InternalServerErrorException(err
|
|
213
|
+
throw new _common.InternalServerErrorException(err?.message || 'Delete single file failed');
|
|
131
214
|
}
|
|
132
215
|
}
|
|
133
|
-
async deleteMultipleFile(keys, storageConfigId, user) {
|
|
216
|
+
async deleteMultipleFile(keys, storageConfigId, user, locationHint) {
|
|
134
217
|
try {
|
|
135
218
|
if (!keys || !keys.length) throw new Error('No file paths provided');
|
|
136
|
-
const provider = await this.
|
|
219
|
+
const provider = await this.getStorageProviderForDelete(storageConfigId, user, locationHint);
|
|
137
220
|
await provider.deleteMultipleFiles(keys);
|
|
138
221
|
return true;
|
|
139
222
|
} catch (err) {
|
|
140
223
|
this.logger.error('Delete multiple files failed', err);
|
|
141
|
-
throw new _common.InternalServerErrorException(err
|
|
224
|
+
throw new _common.InternalServerErrorException(err?.message || 'Delete multiple files failed');
|
|
142
225
|
}
|
|
143
226
|
}
|
|
144
227
|
bytesToKb(bytes) {
|
|
145
228
|
return Number((bytes * 0.001).toFixed(2));
|
|
146
229
|
}
|
|
147
230
|
/**
|
|
231
|
+
* Get local storage basePath from DB config
|
|
232
|
+
* Initializes local provider if not cached, ensuring basePath is from DB
|
|
233
|
+
*/ async getLocalStorageBasePath() {
|
|
234
|
+
try {
|
|
235
|
+
// First check if already cached
|
|
236
|
+
const cachedPath = this.storageFactory.getLocalProviderBasePath();
|
|
237
|
+
if (cachedPath) {
|
|
238
|
+
return cachedPath;
|
|
239
|
+
}
|
|
240
|
+
// Get local config from DB (without user context for public access)
|
|
241
|
+
const localConfigs = await this.storageProviderConfigService.getConfigByType(_filelocationenum.FileLocationEnum.LOCAL);
|
|
242
|
+
if (localConfigs.length > 0) {
|
|
243
|
+
const localConfig = localConfigs[0];
|
|
244
|
+
// Initialize provider to cache it
|
|
245
|
+
await this.storageFactory.createProvider({
|
|
246
|
+
provider: _filelocationenum.FileLocationEnum.LOCAL,
|
|
247
|
+
config: localConfig.config
|
|
248
|
+
});
|
|
249
|
+
// Now get the cached basePath
|
|
250
|
+
return this.storageFactory.getLocalProviderBasePath();
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
this.logger.warn(`Failed to get local storage basePath: ${error.message}`);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
148
259
|
* Generate a URL for accessing a file
|
|
149
260
|
* For S3/Azure: generates presigned URL
|
|
150
261
|
* For Local/SFTP: returns direct path
|
|
@@ -159,7 +270,7 @@ let UploadService = class UploadService {
|
|
|
159
270
|
return key;
|
|
160
271
|
} catch (err) {
|
|
161
272
|
this.logger.error('Generate file URL failed', err);
|
|
162
|
-
throw new _common.InternalServerErrorException(err
|
|
273
|
+
throw new _common.InternalServerErrorException(err?.message || 'Generate file URL failed');
|
|
163
274
|
}
|
|
164
275
|
}
|
|
165
276
|
// NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
|
|
@@ -8,12 +8,50 @@ Object.defineProperty(exports, "ImageCompressor", {
|
|
|
8
8
|
return ImageCompressor;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _sharp = /*#__PURE__*/
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const _sharp = /*#__PURE__*/ _interop_require_wildcard(require("sharp"));
|
|
12
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
13
|
+
if (typeof WeakMap !== "function") return null;
|
|
14
|
+
var cacheBabelInterop = new WeakMap();
|
|
15
|
+
var cacheNodeInterop = new WeakMap();
|
|
16
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
17
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
18
|
+
})(nodeInterop);
|
|
19
|
+
}
|
|
20
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
21
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
25
|
+
return {
|
|
26
|
+
default: obj
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
30
|
+
if (cache && cache.has(obj)) {
|
|
31
|
+
return cache.get(obj);
|
|
32
|
+
}
|
|
33
|
+
var newObj = {
|
|
34
|
+
__proto__: null
|
|
15
35
|
};
|
|
36
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
37
|
+
for(var key in obj){
|
|
38
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
39
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
40
|
+
if (desc && (desc.get || desc.set)) {
|
|
41
|
+
Object.defineProperty(newObj, key, desc);
|
|
42
|
+
} else {
|
|
43
|
+
newObj[key] = obj[key];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
newObj.default = obj;
|
|
48
|
+
if (cache) {
|
|
49
|
+
cache.set(obj, newObj);
|
|
50
|
+
}
|
|
51
|
+
return newObj;
|
|
16
52
|
}
|
|
53
|
+
// Handle ESM/CJS interop - sharp exports differently in each module system
|
|
54
|
+
const sharp = _sharp.default || _sharp;
|
|
17
55
|
let ImageCompressor = class ImageCompressor {
|
|
18
56
|
/**
|
|
19
57
|
* Dynamically compresses an image based on its format and provided options.
|
|
@@ -29,7 +67,7 @@ let ImageCompressor = class ImageCompressor {
|
|
|
29
67
|
};
|
|
30
68
|
}
|
|
31
69
|
// Initialize sharp with improved error handling
|
|
32
|
-
const image = (
|
|
70
|
+
const image = sharp(buffer, {
|
|
33
71
|
failOnError: false,
|
|
34
72
|
density: 300
|
|
35
73
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
2
1
|
import { SingleResponseDto } from '@flusys/nestjs-shared/dtos';
|
|
2
|
+
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
3
3
|
import { CreateFileManagerDto, FileManagerResponseDto, FilesResponseDto, GetFilesRequestDto, UpdateFileManagerDto } from '../dtos';
|
|
4
4
|
import { Request } from 'express';
|
|
5
5
|
import { FileManagerService } from '../services/file-manager.service';
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { SingleResponseDto } from '@flusys/nestjs-shared/dtos';
|
|
2
2
|
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
3
3
|
import { DeleteMultipleFileDto, DeleteSingleFileDto, FileUploadResponsePayloadDto, UploadOptionsDto } from '../dtos';
|
|
4
|
-
import { Response } from 'express';
|
|
5
4
|
import { UploadService } from '../services/upload.service';
|
|
5
|
+
import { StorageConfigService } from '../config';
|
|
6
|
+
import { StorageFactoryService } from '../providers/storage-factory.service';
|
|
6
7
|
export declare class UploadController {
|
|
7
8
|
private uploadService;
|
|
8
|
-
private
|
|
9
|
-
|
|
9
|
+
private storageConfigService;
|
|
10
|
+
private storageFactoryService;
|
|
11
|
+
constructor(uploadService: UploadService, storageConfigService: StorageConfigService, storageFactoryService: StorageFactoryService);
|
|
10
12
|
uploadSingleFile(file: Express.Multer.File, options: UploadOptionsDto, user: ILoggedUserInfo): Promise<SingleResponseDto<FileUploadResponsePayloadDto>>;
|
|
11
13
|
uploadMultipleFiles(files: Express.Multer.File[], options: UploadOptionsDto, user: ILoggedUserInfo): Promise<SingleResponseDto<FileUploadResponsePayloadDto[]>>;
|
|
12
14
|
deleteSingleFile(dto: DeleteSingleFileDto, user: ILoggedUserInfo): Promise<SingleResponseDto<boolean>>;
|
|
13
15
|
deleteMultipleFile(dto: DeleteMultipleFileDto, user: ILoggedUserInfo): Promise<SingleResponseDto<boolean>>;
|
|
14
|
-
seeUploadedFile(filePath: string | string[], res: Response): Promise<void>;
|
|
15
16
|
}
|
|
@@ -16,6 +16,7 @@ export declare class UpdateFileManagerDto extends UpdateFileManagerDto_base impl
|
|
|
16
16
|
id: string;
|
|
17
17
|
}
|
|
18
18
|
export declare class FileManagerResponseDto extends UpdateFileManagerDto {
|
|
19
|
+
providerName?: string;
|
|
19
20
|
}
|
|
20
21
|
export declare class GetFilesRequestDto {
|
|
21
22
|
id: string;
|
|
@@ -25,5 +26,8 @@ export declare class FilesResponseDto {
|
|
|
25
26
|
name: string;
|
|
26
27
|
contentType: string;
|
|
27
28
|
url: string;
|
|
29
|
+
location?: string;
|
|
30
|
+
storageConfigId?: string;
|
|
31
|
+
providerName?: string;
|
|
28
32
|
}
|
|
29
33
|
export {};
|
package/dtos/upload.dto.d.ts
CHANGED
|
@@ -106,6 +106,37 @@ export class StorageConfigService {
|
|
|
106
106
|
*/ getOptions() {
|
|
107
107
|
return this.options;
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Get default local storage base path
|
|
111
|
+
* Used for serving local files without database lookup
|
|
112
|
+
* Falls back to './uploads' if not configured
|
|
113
|
+
*/ getDefaultLocalStoragePath() {
|
|
114
|
+
// Check if localStoragePath is configured in module options
|
|
115
|
+
const configuredPath = this.options.config?.localStoragePath;
|
|
116
|
+
if (configuredPath) {
|
|
117
|
+
return configuredPath;
|
|
118
|
+
}
|
|
119
|
+
// Default to ./uploads in the project root
|
|
120
|
+
return './uploads';
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get application base URL for generating file URLs
|
|
124
|
+
* - First tries module config
|
|
125
|
+
* - Falls back to APP_URL env var
|
|
126
|
+
* - Finally constructs from PORT env var
|
|
127
|
+
*/ getAppUrl() {
|
|
128
|
+
// Try from module config first
|
|
129
|
+
if (this.options.config?.appUrl) {
|
|
130
|
+
return this.options.config.appUrl;
|
|
131
|
+
}
|
|
132
|
+
// Fallback: read directly from environment
|
|
133
|
+
if (process.env.APP_URL) {
|
|
134
|
+
return process.env.APP_URL;
|
|
135
|
+
}
|
|
136
|
+
// Last resort: construct from PORT
|
|
137
|
+
const port = process.env.PORT || '3000';
|
|
138
|
+
return `http://localhost:${port}`;
|
|
139
|
+
}
|
|
109
140
|
constructor(options){
|
|
110
141
|
_define_property(this, "options", void 0);
|
|
111
142
|
this.options = options;
|
|
@@ -26,22 +26,24 @@ function _ts_param(paramIndex, decorator) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
import { BadRequestException, Body, Controller, HttpCode, Inject, Post, Req, UseGuards } from '@nestjs/common';
|
|
29
|
-
import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
|
|
30
29
|
import { createApiController } from '@flusys/nestjs-shared/classes';
|
|
31
30
|
import { CurrentUser } from '@flusys/nestjs-shared/decorators';
|
|
32
|
-
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
33
31
|
import { SingleResponseDto } from '@flusys/nestjs-shared/dtos';
|
|
32
|
+
import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
|
|
33
|
+
import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
34
34
|
import { CreateFileManagerDto, FileManagerResponseDto, GetFilesRequestDto, UpdateFileManagerDto } from '../dtos';
|
|
35
35
|
import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
|
36
36
|
import { Request } from 'express';
|
|
37
37
|
import { FileManagerService } from '../services/file-manager.service';
|
|
38
|
-
export class FileManagerController extends createApiController(CreateFileManagerDto, UpdateFileManagerDto, FileManagerResponseDto
|
|
38
|
+
export class FileManagerController extends createApiController(CreateFileManagerDto, UpdateFileManagerDto, FileManagerResponseDto, {
|
|
39
|
+
security: 'jwt'
|
|
40
|
+
}) {
|
|
39
41
|
async getFiles(dto, req, user) {
|
|
40
42
|
if (!dto || !dto.length) {
|
|
41
43
|
throw new BadRequestException('No files provided');
|
|
42
44
|
}
|
|
43
45
|
// Fetch files from service
|
|
44
|
-
const files = await this.fileService.getFiles(dto, req.protocol, req.host, user);
|
|
46
|
+
const files = await this.fileService.getFiles(dto, req.protocol, req.get('host') || req.hostname, user);
|
|
45
47
|
return {
|
|
46
48
|
success: true,
|
|
47
49
|
message: 'Files retrieved successfully',
|
|
@@ -54,6 +56,8 @@ export class FileManagerController extends createApiController(CreateFileManager
|
|
|
54
56
|
}
|
|
55
57
|
_ts_decorate([
|
|
56
58
|
Post('get-files'),
|
|
59
|
+
UseGuards(JwtAuthGuard),
|
|
60
|
+
ApiBearerAuth(),
|
|
57
61
|
HttpCode(200),
|
|
58
62
|
ApiBody({
|
|
59
63
|
type: GetFilesRequestDto,
|
|
@@ -80,9 +84,7 @@ _ts_decorate([
|
|
|
80
84
|
], FileManagerController.prototype, "getFiles", null);
|
|
81
85
|
FileManagerController = _ts_decorate([
|
|
82
86
|
ApiTags('Files'),
|
|
83
|
-
ApiBearerAuth(),
|
|
84
87
|
Controller('storage/file-manager'),
|
|
85
|
-
UseGuards(JwtAuthGuard),
|
|
86
88
|
_ts_param(0, Inject(FileManagerService)),
|
|
87
89
|
_ts_metadata("design:type", Function),
|
|
88
90
|
_ts_metadata("design:paramtypes", [
|
|
@@ -25,22 +25,21 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
|
|
29
28
|
import { createApiController } from '@flusys/nestjs-shared/classes';
|
|
30
29
|
import { CreateFolderDto, FolderResponseDto, UpdateFolderDto } from '../dtos';
|
|
31
|
-
import { Controller, Inject
|
|
32
|
-
import {
|
|
30
|
+
import { Controller, Inject } from '@nestjs/common';
|
|
31
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
33
32
|
import { FolderService } from '../services/folder.service';
|
|
34
|
-
export class FolderController extends createApiController(CreateFolderDto, UpdateFolderDto, FolderResponseDto
|
|
33
|
+
export class FolderController extends createApiController(CreateFolderDto, UpdateFolderDto, FolderResponseDto, {
|
|
34
|
+
security: 'jwt'
|
|
35
|
+
}) {
|
|
35
36
|
constructor(folderService){
|
|
36
37
|
super(folderService), _define_property(this, "folderService", void 0), this.folderService = folderService;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
FolderController = _ts_decorate([
|
|
40
41
|
ApiTags('Folders'),
|
|
41
|
-
ApiBearerAuth(),
|
|
42
42
|
Controller('storage/folder'),
|
|
43
|
-
UseGuards(JwtAuthGuard),
|
|
44
43
|
_ts_param(0, Inject(FolderService)),
|
|
45
44
|
_ts_metadata("design:type", Function),
|
|
46
45
|
_ts_metadata("design:paramtypes", [
|
|
@@ -25,22 +25,21 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import { JwtAuthGuard } from '@flusys/nestjs-shared/guards';
|
|
29
28
|
import { createApiController } from '@flusys/nestjs-shared/classes';
|
|
30
29
|
import { CreateStorageConfigDto, StorageConfigResponseDto, UpdateStorageConfigDto } from '../dtos';
|
|
31
|
-
import { Controller, Inject
|
|
32
|
-
import {
|
|
30
|
+
import { Controller, Inject } from '@nestjs/common';
|
|
31
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
33
32
|
import { StorageProviderConfigService } from '../services/storage-provider-config.service';
|
|
34
|
-
export class StorageConfigController extends createApiController(CreateStorageConfigDto, UpdateStorageConfigDto, StorageConfigResponseDto
|
|
33
|
+
export class StorageConfigController extends createApiController(CreateStorageConfigDto, UpdateStorageConfigDto, StorageConfigResponseDto, {
|
|
34
|
+
security: 'jwt'
|
|
35
|
+
}) {
|
|
35
36
|
constructor(storageConfigService){
|
|
36
37
|
super(storageConfigService), _define_property(this, "storageConfigService", void 0), this.storageConfigService = storageConfigService;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
StorageConfigController = _ts_decorate([
|
|
40
41
|
ApiTags('Storage Config'),
|
|
41
|
-
ApiBearerAuth(),
|
|
42
42
|
Controller('storage/storage-config'),
|
|
43
|
-
UseGuards(JwtAuthGuard),
|
|
44
43
|
_ts_param(0, Inject(StorageProviderConfigService)),
|
|
45
44
|
_ts_metadata("design:type", Function),
|
|
46
45
|
_ts_metadata("design:paramtypes", [
|