@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
package/README.md
CHANGED
|
@@ -161,6 +161,8 @@ import { StorageModule } from '@flusys/nestjs-storage';
|
|
|
161
161
|
// File validation
|
|
162
162
|
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
163
163
|
allowedFileTypes: ['image/*', 'application/pdf', 'text/*'],
|
|
164
|
+
// URL generation (optional - falls back to APP_URL env or PORT)
|
|
165
|
+
appUrl: process.env.APP_URL || `http://localhost:${process.env.PORT || 3000}`,
|
|
164
166
|
},
|
|
165
167
|
}),
|
|
166
168
|
],
|
|
@@ -1277,10 +1279,4 @@ The `@flusys/nestjs-storage` package provides:
|
|
|
1277
1279
|
|
|
1278
1280
|
---
|
|
1279
1281
|
|
|
1280
|
-
**Last Updated:** 2026-02-
|
|
1281
|
-
|
|
1282
|
-
**Recent Changes:**
|
|
1283
|
-
- 2026-02-09: Added explicit `@Inject()` decorators to all services for esbuild bundling compatibility
|
|
1284
|
-
- 2026-02-09: Fixed `instanceof` checks in FolderService and FileManagerService - replaced with `'id' in dto` pattern
|
|
1285
|
-
- 2026-02-07: Condensed DataSource Provider pattern documentation
|
|
1286
|
-
- 2026-02-07: Simplified provider registration section
|
|
1282
|
+
**Last Updated:** 2026-02-16
|
|
@@ -116,6 +116,37 @@ let StorageConfigService = class StorageConfigService {
|
|
|
116
116
|
*/ getOptions() {
|
|
117
117
|
return this.options;
|
|
118
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Get default local storage base path
|
|
121
|
+
* Used for serving local files without database lookup
|
|
122
|
+
* Falls back to './uploads' if not configured
|
|
123
|
+
*/ getDefaultLocalStoragePath() {
|
|
124
|
+
// Check if localStoragePath is configured in module options
|
|
125
|
+
const configuredPath = this.options.config?.localStoragePath;
|
|
126
|
+
if (configuredPath) {
|
|
127
|
+
return configuredPath;
|
|
128
|
+
}
|
|
129
|
+
// Default to ./uploads in the project root
|
|
130
|
+
return './uploads';
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get application base URL for generating file URLs
|
|
134
|
+
* - First tries module config
|
|
135
|
+
* - Falls back to APP_URL env var
|
|
136
|
+
* - Finally constructs from PORT env var
|
|
137
|
+
*/ getAppUrl() {
|
|
138
|
+
// Try from module config first
|
|
139
|
+
if (this.options.config?.appUrl) {
|
|
140
|
+
return this.options.config.appUrl;
|
|
141
|
+
}
|
|
142
|
+
// Fallback: read directly from environment
|
|
143
|
+
if (process.env.APP_URL) {
|
|
144
|
+
return process.env.APP_URL;
|
|
145
|
+
}
|
|
146
|
+
// Last resort: construct from PORT
|
|
147
|
+
const port = process.env.PORT || '3000';
|
|
148
|
+
return `http://localhost:${port}`;
|
|
149
|
+
}
|
|
119
150
|
constructor(options){
|
|
120
151
|
_define_property(this, "options", void 0);
|
|
121
152
|
this.options = options;
|
|
@@ -9,11 +9,11 @@ Object.defineProperty(exports, "FileManagerController", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _common = require("@nestjs/common");
|
|
12
|
-
const _guards = require("@flusys/nestjs-shared/guards");
|
|
13
12
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
14
13
|
const _decorators = require("@flusys/nestjs-shared/decorators");
|
|
15
|
-
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
16
14
|
const _dtos = require("@flusys/nestjs-shared/dtos");
|
|
15
|
+
const _guards = require("@flusys/nestjs-shared/guards");
|
|
16
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
17
17
|
const _dtos1 = require("../dtos");
|
|
18
18
|
const _swagger = require("@nestjs/swagger");
|
|
19
19
|
const _express = require("express");
|
|
@@ -45,13 +45,15 @@ function _ts_param(paramIndex, decorator) {
|
|
|
45
45
|
decorator(target, key, paramIndex);
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
let FileManagerController = class FileManagerController extends (0, _classes.createApiController)(_dtos1.CreateFileManagerDto, _dtos1.UpdateFileManagerDto, _dtos1.FileManagerResponseDto
|
|
48
|
+
let FileManagerController = class FileManagerController extends (0, _classes.createApiController)(_dtos1.CreateFileManagerDto, _dtos1.UpdateFileManagerDto, _dtos1.FileManagerResponseDto, {
|
|
49
|
+
security: 'jwt'
|
|
50
|
+
}) {
|
|
49
51
|
async getFiles(dto, req, user) {
|
|
50
52
|
if (!dto || !dto.length) {
|
|
51
53
|
throw new _common.BadRequestException('No files provided');
|
|
52
54
|
}
|
|
53
55
|
// Fetch files from service
|
|
54
|
-
const files = await this.fileService.getFiles(dto, req.protocol, req.host, user);
|
|
56
|
+
const files = await this.fileService.getFiles(dto, req.protocol, req.get('host') || req.hostname, user);
|
|
55
57
|
return {
|
|
56
58
|
success: true,
|
|
57
59
|
message: 'Files retrieved successfully',
|
|
@@ -64,6 +66,8 @@ let FileManagerController = class FileManagerController extends (0, _classes.cre
|
|
|
64
66
|
};
|
|
65
67
|
_ts_decorate([
|
|
66
68
|
(0, _common.Post)('get-files'),
|
|
69
|
+
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
70
|
+
(0, _swagger.ApiBearerAuth)(),
|
|
67
71
|
(0, _common.HttpCode)(200),
|
|
68
72
|
(0, _swagger.ApiBody)({
|
|
69
73
|
type: _dtos1.GetFilesRequestDto,
|
|
@@ -90,9 +94,7 @@ _ts_decorate([
|
|
|
90
94
|
], FileManagerController.prototype, "getFiles", null);
|
|
91
95
|
FileManagerController = _ts_decorate([
|
|
92
96
|
(0, _swagger.ApiTags)('Files'),
|
|
93
|
-
(0, _swagger.ApiBearerAuth)(),
|
|
94
97
|
(0, _common.Controller)('storage/file-manager'),
|
|
95
|
-
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
96
98
|
_ts_param(0, (0, _common.Inject)(_filemanagerservice.FileManagerService)),
|
|
97
99
|
_ts_metadata("design:type", Function),
|
|
98
100
|
_ts_metadata("design:paramtypes", [
|
|
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "FolderController", {
|
|
|
8
8
|
return FolderController;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _guards = require("@flusys/nestjs-shared/guards");
|
|
12
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
13
12
|
const _dtos = require("../dtos");
|
|
14
13
|
const _common = require("@nestjs/common");
|
|
@@ -41,16 +40,16 @@ function _ts_param(paramIndex, decorator) {
|
|
|
41
40
|
decorator(target, key, paramIndex);
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
|
-
let FolderController = class FolderController extends (0, _classes.createApiController)(_dtos.CreateFolderDto, _dtos.UpdateFolderDto, _dtos.FolderResponseDto
|
|
43
|
+
let FolderController = class FolderController extends (0, _classes.createApiController)(_dtos.CreateFolderDto, _dtos.UpdateFolderDto, _dtos.FolderResponseDto, {
|
|
44
|
+
security: 'jwt'
|
|
45
|
+
}) {
|
|
45
46
|
constructor(folderService){
|
|
46
47
|
super(folderService), _define_property(this, "folderService", void 0), this.folderService = folderService;
|
|
47
48
|
}
|
|
48
49
|
};
|
|
49
50
|
FolderController = _ts_decorate([
|
|
50
51
|
(0, _swagger.ApiTags)('Folders'),
|
|
51
|
-
(0, _swagger.ApiBearerAuth)(),
|
|
52
52
|
(0, _common.Controller)('storage/folder'),
|
|
53
|
-
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
54
53
|
_ts_param(0, (0, _common.Inject)(_folderservice.FolderService)),
|
|
55
54
|
_ts_metadata("design:type", Function),
|
|
56
55
|
_ts_metadata("design:paramtypes", [
|
|
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "StorageConfigController", {
|
|
|
8
8
|
return StorageConfigController;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _guards = require("@flusys/nestjs-shared/guards");
|
|
12
11
|
const _classes = require("@flusys/nestjs-shared/classes");
|
|
13
12
|
const _dtos = require("../dtos");
|
|
14
13
|
const _common = require("@nestjs/common");
|
|
@@ -41,16 +40,16 @@ function _ts_param(paramIndex, decorator) {
|
|
|
41
40
|
decorator(target, key, paramIndex);
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
|
-
let StorageConfigController = class StorageConfigController extends (0, _classes.createApiController)(_dtos.CreateStorageConfigDto, _dtos.UpdateStorageConfigDto, _dtos.StorageConfigResponseDto
|
|
43
|
+
let StorageConfigController = class StorageConfigController extends (0, _classes.createApiController)(_dtos.CreateStorageConfigDto, _dtos.UpdateStorageConfigDto, _dtos.StorageConfigResponseDto, {
|
|
44
|
+
security: 'jwt'
|
|
45
|
+
}) {
|
|
45
46
|
constructor(storageConfigService){
|
|
46
47
|
super(storageConfigService), _define_property(this, "storageConfigService", void 0), this.storageConfigService = storageConfigService;
|
|
47
48
|
}
|
|
48
49
|
};
|
|
49
50
|
StorageConfigController = _ts_decorate([
|
|
50
51
|
(0, _swagger.ApiTags)('Storage Config'),
|
|
51
|
-
(0, _swagger.ApiBearerAuth)(),
|
|
52
52
|
(0, _common.Controller)('storage/storage-config'),
|
|
53
|
-
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
54
53
|
_ts_param(0, (0, _common.Inject)(_storageproviderconfigservice.StorageProviderConfigService)),
|
|
55
54
|
_ts_metadata("design:type", Function),
|
|
56
55
|
_ts_metadata("design:paramtypes", [
|
|
@@ -15,11 +15,9 @@ const _dtos = require("../dtos");
|
|
|
15
15
|
const _common = require("@nestjs/common");
|
|
16
16
|
const _platformexpress = require("@nestjs/platform-express");
|
|
17
17
|
const _swagger = require("@nestjs/swagger");
|
|
18
|
-
const _express = require("express");
|
|
19
|
-
const _fs = require("fs");
|
|
20
|
-
const _mimetypes = /*#__PURE__*/ _interop_require_wildcard(require("mime-types"));
|
|
21
|
-
const _path = require("path");
|
|
22
18
|
const _uploadservice = require("../services/upload.service");
|
|
19
|
+
const _config = require("../config");
|
|
20
|
+
const _storagefactoryservice = require("../providers/storage-factory.service");
|
|
23
21
|
function _define_property(obj, key, value) {
|
|
24
22
|
if (key in obj) {
|
|
25
23
|
Object.defineProperty(obj, key, {
|
|
@@ -33,47 +31,6 @@ function _define_property(obj, key, value) {
|
|
|
33
31
|
}
|
|
34
32
|
return obj;
|
|
35
33
|
}
|
|
36
|
-
function _getRequireWildcardCache(nodeInterop) {
|
|
37
|
-
if (typeof WeakMap !== "function") return null;
|
|
38
|
-
var cacheBabelInterop = new WeakMap();
|
|
39
|
-
var cacheNodeInterop = new WeakMap();
|
|
40
|
-
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
41
|
-
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
42
|
-
})(nodeInterop);
|
|
43
|
-
}
|
|
44
|
-
function _interop_require_wildcard(obj, nodeInterop) {
|
|
45
|
-
if (!nodeInterop && obj && obj.__esModule) {
|
|
46
|
-
return obj;
|
|
47
|
-
}
|
|
48
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
49
|
-
return {
|
|
50
|
-
default: obj
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
var cache = _getRequireWildcardCache(nodeInterop);
|
|
54
|
-
if (cache && cache.has(obj)) {
|
|
55
|
-
return cache.get(obj);
|
|
56
|
-
}
|
|
57
|
-
var newObj = {
|
|
58
|
-
__proto__: null
|
|
59
|
-
};
|
|
60
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
61
|
-
for(var key in obj){
|
|
62
|
-
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
63
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
64
|
-
if (desc && (desc.get || desc.set)) {
|
|
65
|
-
Object.defineProperty(newObj, key, desc);
|
|
66
|
-
} else {
|
|
67
|
-
newObj[key] = obj[key];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
newObj.default = obj;
|
|
72
|
-
if (cache) {
|
|
73
|
-
cache.set(obj, newObj);
|
|
74
|
-
}
|
|
75
|
-
return newObj;
|
|
76
|
-
}
|
|
77
34
|
function _ts_decorate(decorators, target, key, desc) {
|
|
78
35
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
79
36
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -90,15 +47,17 @@ function _ts_param(paramIndex, decorator) {
|
|
|
90
47
|
}
|
|
91
48
|
let UploadController = class UploadController {
|
|
92
49
|
async uploadSingleFile(file, options, user) {
|
|
93
|
-
const
|
|
50
|
+
const result = await this.uploadService.uploadSingleFile(file, options, user);
|
|
94
51
|
return {
|
|
95
52
|
success: true,
|
|
96
53
|
message: 'File uploaded successfully',
|
|
97
54
|
data: {
|
|
98
|
-
size: this.uploadService.bytesToKb(
|
|
99
|
-
name:
|
|
100
|
-
key:
|
|
101
|
-
contentType:
|
|
55
|
+
size: this.uploadService.bytesToKb(result.size),
|
|
56
|
+
name: result.name,
|
|
57
|
+
key: result.key,
|
|
58
|
+
contentType: result.contentType,
|
|
59
|
+
location: result.location || 'local',
|
|
60
|
+
storageConfigId: result.storageConfigId || ''
|
|
102
61
|
}
|
|
103
62
|
};
|
|
104
63
|
}
|
|
@@ -108,7 +67,9 @@ let UploadController = class UploadController {
|
|
|
108
67
|
size: this.uploadService.bytesToKb(file.size),
|
|
109
68
|
name: file.name,
|
|
110
69
|
key: file.key,
|
|
111
|
-
contentType: file.contentType
|
|
70
|
+
contentType: file.contentType,
|
|
71
|
+
location: file.location || 'local',
|
|
72
|
+
storageConfigId: file.storageConfigId || ''
|
|
112
73
|
}));
|
|
113
74
|
return {
|
|
114
75
|
success: true,
|
|
@@ -132,82 +93,13 @@ let UploadController = class UploadController {
|
|
|
132
93
|
data
|
|
133
94
|
};
|
|
134
95
|
}
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
const uploadDir = (0, _path.join)(process.cwd(), 'uploads');
|
|
138
|
-
const normalizedPath = Array.isArray(filePath) ? filePath.join('/') : filePath;
|
|
139
|
-
const fullPath = (0, _path.join)(uploadDir, normalizedPath);
|
|
140
|
-
this.logger.debug(`Attempting to serve file from: ${fullPath}`);
|
|
141
|
-
// Validate path is inside uploads directory
|
|
142
|
-
if (!fullPath.startsWith(uploadDir)) {
|
|
143
|
-
throw new _common.NotFoundException('Invalid file path');
|
|
144
|
-
}
|
|
145
|
-
// Check if file exists
|
|
146
|
-
if (!(0, _fs.existsSync)(fullPath)) {
|
|
147
|
-
throw new _common.NotFoundException(`File not found: ${normalizedPath}`);
|
|
148
|
-
}
|
|
149
|
-
const stats = (0, _fs.statSync)(fullPath);
|
|
150
|
-
if (!stats.isFile()) {
|
|
151
|
-
throw new _common.NotFoundException(`Not a file: ${normalizedPath}`);
|
|
152
|
-
}
|
|
153
|
-
// Enhanced MIME type detection
|
|
154
|
-
let mimeType = _mimetypes.lookup(fullPath) || 'application/octet-stream';
|
|
155
|
-
// Special handling for SVG files
|
|
156
|
-
if (fullPath.toLowerCase().endsWith('.svg')) {
|
|
157
|
-
mimeType = 'image/svg+xml';
|
|
158
|
-
}
|
|
159
|
-
// Determine if file should be displayed inline or downloaded
|
|
160
|
-
// Inline: PDFs, images, videos, audio, text files
|
|
161
|
-
// Download: Office docs, archives, executables, etc.
|
|
162
|
-
const viewableTypes = [
|
|
163
|
-
'image/',
|
|
164
|
-
'video/',
|
|
165
|
-
'audio/',
|
|
166
|
-
'text/',
|
|
167
|
-
'application/pdf',
|
|
168
|
-
'application/json',
|
|
169
|
-
'application/xml'
|
|
170
|
-
];
|
|
171
|
-
const isViewable = viewableTypes.some((type)=>mimeType.startsWith(type));
|
|
172
|
-
const contentDisposition = isViewable ? 'inline' : `attachment; filename="${encodeURIComponent(normalizedPath.split('/').pop() || 'download')}"`;
|
|
173
|
-
// Set headers optimized for different file types
|
|
174
|
-
res.set({
|
|
175
|
-
'Content-Type': mimeType,
|
|
176
|
-
'Content-Length': stats.size,
|
|
177
|
-
'Content-Disposition': contentDisposition,
|
|
178
|
-
'Cache-Control': 'public, max-age=3600',
|
|
179
|
-
'Accept-Ranges': 'bytes',
|
|
180
|
-
'Cross-Origin-Resource-Policy': 'cross-origin',
|
|
181
|
-
'Access-Control-Allow-Origin': '*',
|
|
182
|
-
'X-Content-Type-Options': 'nosniff'
|
|
183
|
-
});
|
|
184
|
-
// Stream the file
|
|
185
|
-
const stream = (0, _fs.createReadStream)(fullPath);
|
|
186
|
-
stream.pipe(res);
|
|
187
|
-
return new Promise((resolve, reject)=>{
|
|
188
|
-
stream.on('end', ()=>{
|
|
189
|
-
res.end();
|
|
190
|
-
resolve();
|
|
191
|
-
});
|
|
192
|
-
stream.on('error', (err)=>{
|
|
193
|
-
this.logger.error('File stream error', err);
|
|
194
|
-
reject(new _common.NotFoundException(`Failed to serve file: ${normalizedPath}`));
|
|
195
|
-
});
|
|
196
|
-
// Handle client disconnection
|
|
197
|
-
res.on('close', ()=>{
|
|
198
|
-
stream.destroy();
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
} catch (error) {
|
|
202
|
-
this.logger.error('File retrieval error:', error);
|
|
203
|
-
throw new _common.NotFoundException(`File not found: ${filePath}`);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
constructor(uploadService){
|
|
96
|
+
constructor(uploadService, storageConfigService, storageFactoryService){
|
|
207
97
|
_define_property(this, "uploadService", void 0);
|
|
208
|
-
_define_property(this, "
|
|
98
|
+
_define_property(this, "storageConfigService", void 0);
|
|
99
|
+
_define_property(this, "storageFactoryService", void 0);
|
|
209
100
|
this.uploadService = uploadService;
|
|
210
|
-
this.
|
|
101
|
+
this.storageConfigService = storageConfigService;
|
|
102
|
+
this.storageFactoryService = storageFactoryService;
|
|
211
103
|
}
|
|
212
104
|
};
|
|
213
105
|
_ts_decorate([
|
|
@@ -329,57 +221,18 @@ _ts_decorate([
|
|
|
329
221
|
]),
|
|
330
222
|
_ts_metadata("design:returntype", Promise)
|
|
331
223
|
], UploadController.prototype, "deleteMultipleFile", null);
|
|
332
|
-
_ts_decorate([
|
|
333
|
-
(0, _decorators.Public)(),
|
|
334
|
-
(0, _common.Get)('file/*filePath'),
|
|
335
|
-
(0, _swagger.ApiOperation)({
|
|
336
|
-
summary: 'Serve uploaded file by relative path (Public endpoint)',
|
|
337
|
-
description: `
|
|
338
|
-
This endpoint returns a stored file from the server.
|
|
339
|
-
|
|
340
|
-
- The \`filePath\` is a **wildcard path parameter** that supports nested folders.
|
|
341
|
-
- Example:
|
|
342
|
-
\`GET /uploads/file/profile/user123/avatar.png\`
|
|
343
|
-
→ Will serve the file from \`./profile/user123/avatar.png\`
|
|
344
|
-
|
|
345
|
-
**Use case:**
|
|
346
|
-
Access uploaded files publicly through a structured path.
|
|
347
|
-
|
|
348
|
-
**Note:** This endpoint is public and does not require authentication.
|
|
349
|
-
`
|
|
350
|
-
}),
|
|
351
|
-
(0, _swagger.ApiParam)({
|
|
352
|
-
name: 'filePath',
|
|
353
|
-
required: true,
|
|
354
|
-
description: 'Relative path to the uploaded file (supports nested directories, e.g. "profile/user123/avatar.png")',
|
|
355
|
-
example: 'profile/user123/avatar.png'
|
|
356
|
-
}),
|
|
357
|
-
(0, _swagger.ApiProduces)('image/jpeg'),
|
|
358
|
-
(0, _swagger.ApiResponse)({
|
|
359
|
-
status: 200,
|
|
360
|
-
description: 'Uploaded file successfully returned',
|
|
361
|
-
schema: {
|
|
362
|
-
type: 'string',
|
|
363
|
-
format: 'binary'
|
|
364
|
-
}
|
|
365
|
-
}),
|
|
366
|
-
_ts_param(0, (0, _common.Param)('filePath')),
|
|
367
|
-
_ts_param(1, (0, _common.Res)()),
|
|
368
|
-
_ts_metadata("design:type", Function),
|
|
369
|
-
_ts_metadata("design:paramtypes", [
|
|
370
|
-
Object,
|
|
371
|
-
typeof _express.Response === "undefined" ? Object : _express.Response
|
|
372
|
-
]),
|
|
373
|
-
_ts_metadata("design:returntype", Promise)
|
|
374
|
-
], UploadController.prototype, "seeUploadedFile", null);
|
|
375
224
|
UploadController = _ts_decorate([
|
|
376
225
|
(0, _swagger.ApiTags)('Upload'),
|
|
377
226
|
(0, _swagger.ApiBearerAuth)(),
|
|
378
227
|
(0, _common.Controller)('storage/upload'),
|
|
379
228
|
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
380
229
|
_ts_param(0, (0, _common.Inject)(_uploadservice.UploadService)),
|
|
230
|
+
_ts_param(1, (0, _common.Inject)(_config.StorageConfigService)),
|
|
231
|
+
_ts_param(2, (0, _common.Inject)(_storagefactoryservice.StorageFactoryService)),
|
|
381
232
|
_ts_metadata("design:type", Function),
|
|
382
233
|
_ts_metadata("design:paramtypes", [
|
|
383
|
-
typeof _uploadservice.UploadService === "undefined" ? Object : _uploadservice.UploadService
|
|
234
|
+
typeof _uploadservice.UploadService === "undefined" ? Object : _uploadservice.UploadService,
|
|
235
|
+
typeof _config.StorageConfigService === "undefined" ? Object : _config.StorageConfigService,
|
|
236
|
+
typeof _storagefactoryservice.StorageFactoryService === "undefined" ? Object : _storagefactoryservice.StorageFactoryService
|
|
384
237
|
])
|
|
385
238
|
], UploadController);
|
|
@@ -149,7 +149,17 @@ _ts_decorate([
|
|
|
149
149
|
_ts_metadata("design:type", String)
|
|
150
150
|
], UpdateFileManagerDto.prototype, "id", void 0);
|
|
151
151
|
let FileManagerResponseDto = class FileManagerResponseDto extends UpdateFileManagerDto {
|
|
152
|
+
constructor(...args){
|
|
153
|
+
super(...args), _define_property(this, "providerName", void 0);
|
|
154
|
+
}
|
|
152
155
|
};
|
|
156
|
+
_ts_decorate([
|
|
157
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
158
|
+
example: 'My S3 Storage',
|
|
159
|
+
description: 'Name of the storage configuration/provider'
|
|
160
|
+
}),
|
|
161
|
+
_ts_metadata("design:type", String)
|
|
162
|
+
], FileManagerResponseDto.prototype, "providerName", void 0);
|
|
153
163
|
let GetFilesRequestDto = class GetFilesRequestDto {
|
|
154
164
|
constructor(){
|
|
155
165
|
_define_property(this, "id", void 0);
|
|
@@ -167,6 +177,9 @@ let FilesResponseDto = class FilesResponseDto {
|
|
|
167
177
|
_define_property(this, "name", void 0);
|
|
168
178
|
_define_property(this, "contentType", void 0);
|
|
169
179
|
_define_property(this, "url", void 0);
|
|
180
|
+
_define_property(this, "location", void 0);
|
|
181
|
+
_define_property(this, "storageConfigId", void 0);
|
|
182
|
+
_define_property(this, "providerName", void 0);
|
|
170
183
|
}
|
|
171
184
|
};
|
|
172
185
|
_ts_decorate([
|
|
@@ -183,13 +196,34 @@ _ts_decorate([
|
|
|
183
196
|
], FilesResponseDto.prototype, "name", void 0);
|
|
184
197
|
_ts_decorate([
|
|
185
198
|
(0, _swagger.ApiProperty)({
|
|
186
|
-
example: '
|
|
199
|
+
example: 'image/jpeg'
|
|
187
200
|
}),
|
|
188
201
|
_ts_metadata("design:type", String)
|
|
189
202
|
], FilesResponseDto.prototype, "contentType", void 0);
|
|
190
203
|
_ts_decorate([
|
|
191
204
|
(0, _swagger.ApiProperty)({
|
|
192
|
-
example: 'file123.jpg'
|
|
205
|
+
example: 'https://example.com/file123.jpg'
|
|
193
206
|
}),
|
|
194
207
|
_ts_metadata("design:type", String)
|
|
195
208
|
], FilesResponseDto.prototype, "url", void 0);
|
|
209
|
+
_ts_decorate([
|
|
210
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
211
|
+
example: 'local',
|
|
212
|
+
description: 'Storage provider type (local, aws, azure, sftp)'
|
|
213
|
+
}),
|
|
214
|
+
_ts_metadata("design:type", String)
|
|
215
|
+
], FilesResponseDto.prototype, "location", void 0);
|
|
216
|
+
_ts_decorate([
|
|
217
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
218
|
+
example: '123e4567-e89b-12d3-a456-426614174000',
|
|
219
|
+
description: 'Storage configuration ID'
|
|
220
|
+
}),
|
|
221
|
+
_ts_metadata("design:type", String)
|
|
222
|
+
], FilesResponseDto.prototype, "storageConfigId", void 0);
|
|
223
|
+
_ts_decorate([
|
|
224
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
225
|
+
example: 'My S3 Storage',
|
|
226
|
+
description: 'Name of the storage configuration/provider'
|
|
227
|
+
}),
|
|
228
|
+
_ts_metadata("design:type", String)
|
|
229
|
+
], FilesResponseDto.prototype, "providerName", void 0);
|
package/cjs/dtos/upload.dto.js
CHANGED
|
@@ -210,6 +210,8 @@ let FileUploadResponsePayloadDto = class FileUploadResponsePayloadDto {
|
|
|
210
210
|
_define_property(this, "contentType", void 0);
|
|
211
211
|
_define_property(this, "size", void 0);
|
|
212
212
|
_define_property(this, "key", void 0);
|
|
213
|
+
_define_property(this, "location", void 0);
|
|
214
|
+
_define_property(this, "storageConfigId", void 0);
|
|
213
215
|
}
|
|
214
216
|
};
|
|
215
217
|
_ts_decorate([
|
|
@@ -236,3 +238,17 @@ _ts_decorate([
|
|
|
236
238
|
}),
|
|
237
239
|
_ts_metadata("design:type", String)
|
|
238
240
|
], FileUploadResponsePayloadDto.prototype, "key", void 0);
|
|
241
|
+
_ts_decorate([
|
|
242
|
+
(0, _swagger.ApiProperty)({
|
|
243
|
+
example: 'local',
|
|
244
|
+
description: 'Storage provider type (local, aws, azure, sftp)'
|
|
245
|
+
}),
|
|
246
|
+
_ts_metadata("design:type", String)
|
|
247
|
+
], FileUploadResponsePayloadDto.prototype, "location", void 0);
|
|
248
|
+
_ts_decorate([
|
|
249
|
+
(0, _swagger.ApiProperty)({
|
|
250
|
+
example: '123e4567-e89b-12d3-a456-426614174000',
|
|
251
|
+
description: 'Storage configuration ID used for this upload'
|
|
252
|
+
}),
|
|
253
|
+
_ts_metadata("design:type", String)
|
|
254
|
+
], FileUploadResponsePayloadDto.prototype, "storageConfigId", void 0);
|