@flusys/nestjs-storage 0.1.0-beta.3 → 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 CHANGED
@@ -1279,10 +1279,4 @@ The `@flusys/nestjs-storage` package provides:
1279
1279
 
1280
1280
  ---
1281
1281
 
1282
- **Last Updated:** 2026-02-09
1283
-
1284
- **Recent Changes:**
1285
- - 2026-02-09: Added explicit `@Inject()` decorators to all services for esbuild bundling compatibility
1286
- - 2026-02-09: Fixed `instanceof` checks in FolderService and FileManagerService - replaced with `'id' in dto` pattern
1287
- - 2026-02-07: Condensed DataSource Provider pattern documentation
1288
- - 2026-02-07: Simplified provider registration section
1282
+ **Last Updated:** 2026-02-16
@@ -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,7 +45,9 @@ 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');
@@ -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", [
@@ -117,10 +117,8 @@ let StorageModule = class StorageModule {
117
117
  ]
118
118
  };
119
119
  }
120
- // ==================== Private Helper Methods ====================
121
- /**
122
- * Get controllers (all controllers always loaded)
123
- */ static getControllers(options) {
120
+ // Private Helper Methods
121
+ /** Get controllers (all controllers always loaded) */ static getControllers(options) {
124
122
  return [
125
123
  _controllers.FileManagerController,
126
124
  _controllers.FolderController,
@@ -42,46 +42,24 @@ function _ts_param(paramIndex, decorator) {
42
42
  };
43
43
  }
44
44
  let FolderService = class FolderService extends _classes.RequestScopedApiService {
45
- /**
46
- * Resolve entity class for this service
47
- * @returns Folder or FolderWithCompany based on configuration
48
- */ resolveEntity() {
49
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
50
- return enableCompanyFeature ? _entities.FolderWithCompany : _entities.Folder;
45
+ resolveEntity() {
46
+ return this.storageConfig.isCompanyFeatureEnabled() ? _entities.FolderWithCompany : _entities.Folder;
51
47
  }
52
- /**
53
- * Get DataSource provider for this service
54
- * @returns StorageDataSourceProvider instance
55
- */ getDataSourceProvider() {
48
+ getDataSourceProvider() {
56
49
  return this.dataSourceProvider;
57
50
  }
51
+ // Entity Conversion
58
52
  async convertSingleDtoToEntity(dto, user) {
59
- let folder = {};
60
- // NOTE: Using 'id' in dto check instead of instanceof - instanceof may not work after esbuild bundling
61
- if ('id' in dto && dto.id && typeof dto.id === 'string') {
62
- const dbData = await this.repository.findOne({
63
- where: {
64
- id: dto.id
65
- }
66
- });
67
- if (!dbData) {
68
- throw new _common.NotFoundException('No such entity data found for update! Please, Try Again.');
69
- }
70
- folder = dbData;
71
- }
72
- // Set company/branch IDs if company feature is enabled
73
- folder = {
74
- ...folder,
75
- ...dto
76
- };
77
- // Only set company fields if they exist on the entity (when company feature is enabled)
78
- if ('companyId' in folder) {
79
- folder.companyId = user?.companyId ?? null;
53
+ const entity = await super.convertSingleDtoToEntity(dto, user);
54
+ // Set companyId from user context if company feature enabled
55
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
56
+ entity.companyId = user?.companyId ?? null;
80
57
  }
81
- return folder;
58
+ return entity;
82
59
  }
60
+ // Query Customization
83
61
  async getSelectQuery(query, _user, select) {
84
- if (!select || !select.length) {
62
+ if (!select?.length) {
85
63
  select = [
86
64
  'id',
87
65
  'name',
@@ -89,35 +67,26 @@ let FolderService = class FolderService extends _classes.RequestScopedApiService
89
67
  'createdAt',
90
68
  'deletedAt'
91
69
  ];
70
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
71
+ select.push('companyId');
72
+ }
92
73
  }
93
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
94
- // Add company context fields if company feature is enabled
95
- // The entity will have these fields only if company feature is enabled
96
- if (this.storageConfig.isCompanyFeatureEnabled()) {
97
- selectFields.push('folder.companyId');
98
- }
99
- query.select(selectFields);
74
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
100
75
  return {
101
76
  query,
102
77
  isRaw: false
103
78
  };
104
79
  }
105
- /**
106
- * Override: Extra query manipulation - Auto-filter by user's company
107
- */ async getExtraManipulateQuery(query, filterDto, user) {
80
+ async getExtraManipulateQuery(query, filterDto, user) {
108
81
  const result = await super.getExtraManipulateQuery(query, filterDto, user);
109
- // If company feature enabled and user has companyId, filter by user's company
110
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
111
- if (enableCompanyFeature && user?.companyId) {
82
+ if (this.storageConfig.isCompanyFeatureEnabled() && user?.companyId) {
112
83
  query.andWhere('folder.companyId = :companyId', {
113
84
  companyId: user.companyId
114
85
  });
115
86
  }
116
87
  return result;
117
88
  }
118
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
119
89
  constructor(cacheManager, utilsService, storageConfig, dataSourceProvider){
120
- // Repository will be set asynchronously by RequestScopedApiService
121
90
  super('folder', null, cacheManager, utilsService, FolderService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "storageConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.storageConfig = storageConfig, this.dataSourceProvider = dataSourceProvider;
122
91
  }
123
92
  };
@@ -83,10 +83,8 @@ function _ts_param(paramIndex, decorator) {
83
83
  };
84
84
  }
85
85
  let StorageDataSourceProvider = class StorageDataSourceProvider extends _modules.MultiTenantDataSourceService {
86
- // ==================== Factory Methods ====================
87
- /**
88
- * Build parent options from StorageModuleOptions
89
- */ static buildParentOptions(options) {
86
+ // Factory Methods
87
+ /** Build parent options from StorageModuleOptions */ static buildParentOptions(options) {
90
88
  return {
91
89
  bootstrapAppConfig: options.bootstrapAppConfig,
92
90
  defaultDatabaseConfig: options.config?.defaultDatabaseConfig,
@@ -94,10 +92,8 @@ let StorageDataSourceProvider = class StorageDataSourceProvider extends _modules
94
92
  tenants: options.config?.tenants
95
93
  };
96
94
  }
97
- // ==================== Feature Flags ====================
98
- /**
99
- * Get global enable company feature flag
100
- */ getEnableCompanyFeature() {
95
+ // Feature Flags
96
+ /** Get global enable company feature flag */ getEnableCompanyFeature() {
101
97
  return this.storageOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
102
98
  }
103
99
  /**
@@ -111,11 +107,11 @@ let StorageDataSourceProvider = class StorageDataSourceProvider extends _modules
111
107
  */ getEnableCompanyFeatureForCurrentTenant() {
112
108
  return this.getEnableCompanyFeatureForTenant(this.getCurrentTenant() ?? undefined);
113
109
  }
114
- // ==================== Entity Management ====================
110
+ // Entity Management
115
111
  /**
116
- * Get storage entities for migrations based on company feature flag
117
- * Note: For TypeORM repositories, we always use the base entities (FileManager, etc.)
118
- * But for migrations, we need the correct entity based on the feature flag
112
+ * Get storage entities for migrations based on company feature flag.
113
+ * For TypeORM repositories, we always use the base entities (FileManager, etc.)
114
+ * but for migrations, we need the correct entity based on the feature flag.
119
115
  */ async getStorageEntities(enableCompanyFeature) {
120
116
  const enable = enableCompanyFeature ?? this.getEnableCompanyFeature();
121
117
  const { FileManager, Folder, StorageConfig } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../entities")));
@@ -135,10 +131,8 @@ let StorageDataSourceProvider = class StorageDataSourceProvider extends _modules
135
131
  StorageConfig
136
132
  ];
137
133
  }
138
- // ==================== Overrides ====================
139
- /**
140
- * Override to dynamically set entities based on tenant config
141
- */ async createDataSourceFromConfig(config) {
134
+ // Overrides
135
+ /** Override to dynamically set entities based on tenant config */ async createDataSourceFromConfig(config) {
142
136
  const currentTenant = this.getCurrentTenant();
143
137
  const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
144
138
  const entities = await this.getStorageEntities(enableCompanyFeature);
@@ -42,34 +42,24 @@ function _ts_param(paramIndex, decorator) {
42
42
  };
43
43
  }
44
44
  let StorageProviderConfigService = class StorageProviderConfigService extends _classes.RequestScopedApiService {
45
- /**
46
- * Resolve entity class for this service
47
- * @returns StorageConfig or StorageConfigWithCompany based on configuration
48
- */ resolveEntity() {
49
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
50
- return enableCompanyFeature ? _entities.StorageConfigWithCompany : _entities.StorageConfig;
45
+ resolveEntity() {
46
+ return this.storageConfig.isCompanyFeatureEnabled() ? _entities.StorageConfigWithCompany : _entities.StorageConfig;
51
47
  }
52
- /**
53
- * Get DataSource provider for this service
54
- * @returns StorageDataSourceProvider instance
55
- */ getDataSourceProvider() {
48
+ getDataSourceProvider() {
56
49
  return this.dataSourceProvider;
57
50
  }
51
+ // Entity Conversion
58
52
  async convertSingleDtoToEntity(dto, user) {
59
- let storageConfig = {};
60
- // Set basic fields
61
- storageConfig = {
62
- ...storageConfig,
63
- ...dto
64
- };
65
- // Only set company fields if they exist on the entity (when company feature is enabled)
66
- if ('companyId' in storageConfig) {
67
- storageConfig.companyId = user?.companyId ?? null;
53
+ const entity = await super.convertSingleDtoToEntity(dto, user);
54
+ // Set companyId from user context if company feature enabled
55
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
56
+ entity.companyId = user?.companyId ?? null;
68
57
  }
69
- return storageConfig;
58
+ return entity;
70
59
  }
60
+ // Query Customization
71
61
  async getSelectQuery(query, _user, select) {
72
- if (!select || !select.length) {
62
+ if (!select?.length) {
73
63
  select = [
74
64
  'id',
75
65
  'name',
@@ -78,25 +68,19 @@ let StorageProviderConfigService = class StorageProviderConfigService extends _c
78
68
  'createdAt',
79
69
  'updatedAt'
80
70
  ];
81
- // Add company fields if company feature is enabled
82
71
  if (this.storageConfig.isCompanyFeatureEnabled()) {
83
72
  select.push('companyId');
84
73
  }
85
74
  }
86
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
87
- query.select(selectFields);
75
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
88
76
  return {
89
77
  query,
90
78
  isRaw: false
91
79
  };
92
80
  }
93
- /**
94
- * Override: Extra query manipulation - Auto-filter by user's company
95
- */ async getExtraManipulateQuery(query, filterDto, user) {
81
+ async getExtraManipulateQuery(query, filterDto, user) {
96
82
  const result = await super.getExtraManipulateQuery(query, filterDto, user);
97
- // If company feature enabled and user has companyId, filter by user's company
98
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
99
- if (enableCompanyFeature && user?.companyId) {
83
+ if (this.storageConfig.isCompanyFeatureEnabled() && user?.companyId) {
100
84
  query.andWhere('storageConfig.companyId = :companyId', {
101
85
  companyId: user.companyId
102
86
  });
@@ -162,9 +146,7 @@ let StorageProviderConfigService = class StorageProviderConfigService extends _c
162
146
  where
163
147
  });
164
148
  }
165
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
166
149
  constructor(cacheManager, utilsService, storageConfig, dataSourceProvider){
167
- // Repository will be set asynchronously by RequestScopedApiService
168
150
  super('storageConfig', null, cacheManager, utilsService, StorageProviderConfigService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "storageConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.storageConfig = storageConfig, this.dataSourceProvider = dataSourceProvider;
169
151
  }
170
152
  };
@@ -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';
@@ -26,16 +26,18 @@ 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');
@@ -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, UseGuards } from '@nestjs/common';
32
- import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
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, UseGuards } from '@nestjs/common';
32
- import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
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", [
@@ -107,10 +107,8 @@ export class StorageModule {
107
107
  ]
108
108
  };
109
109
  }
110
- // ==================== Private Helper Methods ====================
111
- /**
112
- * Get controllers (all controllers always loaded)
113
- */ static getControllers(options) {
110
+ // Private Helper Methods
111
+ /** Get controllers (all controllers always loaded) */ static getControllers(options) {
114
112
  return [
115
113
  FileManagerController,
116
114
  FolderController,
@@ -27,51 +27,29 @@ function _ts_param(paramIndex, decorator) {
27
27
  }
28
28
  import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
29
29
  import { UtilsService } from '@flusys/nestjs-shared/modules';
30
- import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
30
+ import { Inject, Injectable, Scope } from '@nestjs/common';
31
31
  import { StorageConfigService } from '../config';
32
32
  import { Folder, FolderWithCompany } from '../entities';
33
33
  import { StorageDataSourceProvider } from './storage-datasource.provider';
34
34
  export class FolderService extends RequestScopedApiService {
35
- /**
36
- * Resolve entity class for this service
37
- * @returns Folder or FolderWithCompany based on configuration
38
- */ resolveEntity() {
39
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
40
- return enableCompanyFeature ? FolderWithCompany : Folder;
35
+ resolveEntity() {
36
+ return this.storageConfig.isCompanyFeatureEnabled() ? FolderWithCompany : Folder;
41
37
  }
42
- /**
43
- * Get DataSource provider for this service
44
- * @returns StorageDataSourceProvider instance
45
- */ getDataSourceProvider() {
38
+ getDataSourceProvider() {
46
39
  return this.dataSourceProvider;
47
40
  }
41
+ // Entity Conversion
48
42
  async convertSingleDtoToEntity(dto, user) {
49
- let folder = {};
50
- // NOTE: Using 'id' in dto check instead of instanceof - instanceof may not work after esbuild bundling
51
- if ('id' in dto && dto.id && typeof dto.id === 'string') {
52
- const dbData = await this.repository.findOne({
53
- where: {
54
- id: dto.id
55
- }
56
- });
57
- if (!dbData) {
58
- throw new NotFoundException('No such entity data found for update! Please, Try Again.');
59
- }
60
- folder = dbData;
61
- }
62
- // Set company/branch IDs if company feature is enabled
63
- folder = {
64
- ...folder,
65
- ...dto
66
- };
67
- // Only set company fields if they exist on the entity (when company feature is enabled)
68
- if ('companyId' in folder) {
69
- folder.companyId = user?.companyId ?? null;
43
+ const entity = await super.convertSingleDtoToEntity(dto, user);
44
+ // Set companyId from user context if company feature enabled
45
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
46
+ entity.companyId = user?.companyId ?? null;
70
47
  }
71
- return folder;
48
+ return entity;
72
49
  }
50
+ // Query Customization
73
51
  async getSelectQuery(query, _user, select) {
74
- if (!select || !select.length) {
52
+ if (!select?.length) {
75
53
  select = [
76
54
  'id',
77
55
  'name',
@@ -79,35 +57,26 @@ export class FolderService extends RequestScopedApiService {
79
57
  'createdAt',
80
58
  'deletedAt'
81
59
  ];
60
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
61
+ select.push('companyId');
62
+ }
82
63
  }
83
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
84
- // Add company context fields if company feature is enabled
85
- // The entity will have these fields only if company feature is enabled
86
- if (this.storageConfig.isCompanyFeatureEnabled()) {
87
- selectFields.push('folder.companyId');
88
- }
89
- query.select(selectFields);
64
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
90
65
  return {
91
66
  query,
92
67
  isRaw: false
93
68
  };
94
69
  }
95
- /**
96
- * Override: Extra query manipulation - Auto-filter by user's company
97
- */ async getExtraManipulateQuery(query, filterDto, user) {
70
+ async getExtraManipulateQuery(query, filterDto, user) {
98
71
  const result = await super.getExtraManipulateQuery(query, filterDto, user);
99
- // If company feature enabled and user has companyId, filter by user's company
100
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
101
- if (enableCompanyFeature && user?.companyId) {
72
+ if (this.storageConfig.isCompanyFeatureEnabled() && user?.companyId) {
102
73
  query.andWhere('folder.companyId = :companyId', {
103
74
  companyId: user.companyId
104
75
  });
105
76
  }
106
77
  return result;
107
78
  }
108
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
109
79
  constructor(cacheManager, utilsService, storageConfig, dataSourceProvider){
110
- // Repository will be set asynchronously by RequestScopedApiService
111
80
  super('folder', null, cacheManager, utilsService, FolderService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "storageConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.storageConfig = storageConfig, this.dataSourceProvider = dataSourceProvider;
112
81
  }
113
82
  }
@@ -32,10 +32,8 @@ import { Request } from 'express';
32
32
  import { StorageModuleOptions } from '../interfaces';
33
33
  import { STORAGE_MODULE_OPTIONS } from '../config/storage.constants';
34
34
  export class StorageDataSourceProvider extends MultiTenantDataSourceService {
35
- // ==================== Factory Methods ====================
36
- /**
37
- * Build parent options from StorageModuleOptions
38
- */ static buildParentOptions(options) {
35
+ // Factory Methods
36
+ /** Build parent options from StorageModuleOptions */ static buildParentOptions(options) {
39
37
  return {
40
38
  bootstrapAppConfig: options.bootstrapAppConfig,
41
39
  defaultDatabaseConfig: options.config?.defaultDatabaseConfig,
@@ -43,10 +41,8 @@ export class StorageDataSourceProvider extends MultiTenantDataSourceService {
43
41
  tenants: options.config?.tenants
44
42
  };
45
43
  }
46
- // ==================== Feature Flags ====================
47
- /**
48
- * Get global enable company feature flag
49
- */ getEnableCompanyFeature() {
44
+ // Feature Flags
45
+ /** Get global enable company feature flag */ getEnableCompanyFeature() {
50
46
  return this.storageOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
51
47
  }
52
48
  /**
@@ -60,11 +56,11 @@ export class StorageDataSourceProvider extends MultiTenantDataSourceService {
60
56
  */ getEnableCompanyFeatureForCurrentTenant() {
61
57
  return this.getEnableCompanyFeatureForTenant(this.getCurrentTenant() ?? undefined);
62
58
  }
63
- // ==================== Entity Management ====================
59
+ // Entity Management
64
60
  /**
65
- * Get storage entities for migrations based on company feature flag
66
- * Note: For TypeORM repositories, we always use the base entities (FileManager, etc.)
67
- * But for migrations, we need the correct entity based on the feature flag
61
+ * Get storage entities for migrations based on company feature flag.
62
+ * For TypeORM repositories, we always use the base entities (FileManager, etc.)
63
+ * but for migrations, we need the correct entity based on the feature flag.
68
64
  */ async getStorageEntities(enableCompanyFeature) {
69
65
  const enable = enableCompanyFeature ?? this.getEnableCompanyFeature();
70
66
  const { FileManager, Folder, StorageConfig } = await import('../entities');
@@ -84,10 +80,8 @@ export class StorageDataSourceProvider extends MultiTenantDataSourceService {
84
80
  StorageConfig
85
81
  ];
86
82
  }
87
- // ==================== Overrides ====================
88
- /**
89
- * Override to dynamically set entities based on tenant config
90
- */ async createDataSourceFromConfig(config) {
83
+ // Overrides
84
+ /** Override to dynamically set entities based on tenant config */ async createDataSourceFromConfig(config) {
91
85
  const currentTenant = this.getCurrentTenant();
92
86
  const enableCompanyFeature = this.getEnableCompanyFeatureForTenant(currentTenant ?? undefined);
93
87
  const entities = await this.getStorageEntities(enableCompanyFeature);
@@ -32,34 +32,24 @@ import { StorageConfigService } from '../config';
32
32
  import { StorageConfig, StorageConfigWithCompany } from '../entities';
33
33
  import { StorageDataSourceProvider } from './storage-datasource.provider';
34
34
  export class StorageProviderConfigService extends RequestScopedApiService {
35
- /**
36
- * Resolve entity class for this service
37
- * @returns StorageConfig or StorageConfigWithCompany based on configuration
38
- */ resolveEntity() {
39
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
40
- return enableCompanyFeature ? StorageConfigWithCompany : StorageConfig;
35
+ resolveEntity() {
36
+ return this.storageConfig.isCompanyFeatureEnabled() ? StorageConfigWithCompany : StorageConfig;
41
37
  }
42
- /**
43
- * Get DataSource provider for this service
44
- * @returns StorageDataSourceProvider instance
45
- */ getDataSourceProvider() {
38
+ getDataSourceProvider() {
46
39
  return this.dataSourceProvider;
47
40
  }
41
+ // Entity Conversion
48
42
  async convertSingleDtoToEntity(dto, user) {
49
- let storageConfig = {};
50
- // Set basic fields
51
- storageConfig = {
52
- ...storageConfig,
53
- ...dto
54
- };
55
- // Only set company fields if they exist on the entity (when company feature is enabled)
56
- if ('companyId' in storageConfig) {
57
- storageConfig.companyId = user?.companyId ?? null;
43
+ const entity = await super.convertSingleDtoToEntity(dto, user);
44
+ // Set companyId from user context if company feature enabled
45
+ if (this.storageConfig.isCompanyFeatureEnabled()) {
46
+ entity.companyId = user?.companyId ?? null;
58
47
  }
59
- return storageConfig;
48
+ return entity;
60
49
  }
50
+ // Query Customization
61
51
  async getSelectQuery(query, _user, select) {
62
- if (!select || !select.length) {
52
+ if (!select?.length) {
63
53
  select = [
64
54
  'id',
65
55
  'name',
@@ -68,25 +58,19 @@ export class StorageProviderConfigService extends RequestScopedApiService {
68
58
  'createdAt',
69
59
  'updatedAt'
70
60
  ];
71
- // Add company fields if company feature is enabled
72
61
  if (this.storageConfig.isCompanyFeatureEnabled()) {
73
62
  select.push('companyId');
74
63
  }
75
64
  }
76
- const selectFields = select.map((field)=>`${this.entityName}.${field}`);
77
- query.select(selectFields);
65
+ query.select(select.map((f)=>`${this.entityName}.${f}`));
78
66
  return {
79
67
  query,
80
68
  isRaw: false
81
69
  };
82
70
  }
83
- /**
84
- * Override: Extra query manipulation - Auto-filter by user's company
85
- */ async getExtraManipulateQuery(query, filterDto, user) {
71
+ async getExtraManipulateQuery(query, filterDto, user) {
86
72
  const result = await super.getExtraManipulateQuery(query, filterDto, user);
87
- // If company feature enabled and user has companyId, filter by user's company
88
- const enableCompanyFeature = this.storageConfig.isCompanyFeatureEnabled();
89
- if (enableCompanyFeature && user?.companyId) {
73
+ if (this.storageConfig.isCompanyFeatureEnabled() && user?.companyId) {
90
74
  query.andWhere('storageConfig.companyId = :companyId', {
91
75
  companyId: user.companyId
92
76
  });
@@ -152,9 +136,7 @@ export class StorageProviderConfigService extends RequestScopedApiService {
152
136
  where
153
137
  });
154
138
  }
155
- // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
156
139
  constructor(cacheManager, utilsService, storageConfig, dataSourceProvider){
157
- // Repository will be set asynchronously by RequestScopedApiService
158
140
  super('storageConfig', null, cacheManager, utilsService, StorageProviderConfigService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "storageConfig", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.storageConfig = storageConfig, this.dataSourceProvider = dataSourceProvider;
159
141
  }
160
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-storage",
3
- "version": "0.1.0-beta.3",
3
+ "version": "1.0.0-beta",
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": "0.1.0-beta.3",
132
- "@flusys/nestjs-shared": "0.1.0-beta.3"
131
+ "@flusys/nestjs-core": "1.0.0-beta",
132
+ "@flusys/nestjs-shared": "1.0.0-beta"
133
133
  }
134
134
  }
@@ -1,5 +1,4 @@
1
1
  import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
- import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
2
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
3
  import { UtilsService } from '@flusys/nestjs-shared/modules';
5
4
  import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
@@ -21,7 +20,7 @@ export declare class FolderService extends RequestScopedApiService<CreateFolderD
21
20
  query: SelectQueryBuilder<FolderBase>;
22
21
  isRaw: boolean;
23
22
  }>;
24
- protected getExtraManipulateQuery(query: SelectQueryBuilder<FolderBase>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
23
+ protected getExtraManipulateQuery(query: SelectQueryBuilder<FolderBase>, filterDto: any, user: ILoggedUserInfo | null): Promise<{
25
24
  query: SelectQueryBuilder<FolderBase>;
26
25
  isRaw: boolean;
27
26
  }>;
@@ -1,5 +1,4 @@
1
1
  import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
2
- import { FilterAndPaginationDto } from '@flusys/nestjs-shared/dtos';
3
2
  import { ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
4
3
  import { UtilsService } from '@flusys/nestjs-shared/modules';
5
4
  import { EntityTarget, Repository, SelectQueryBuilder } from 'typeorm';
@@ -22,7 +21,7 @@ export declare class StorageProviderConfigService extends RequestScopedApiServic
22
21
  query: SelectQueryBuilder<StorageConfigBase>;
23
22
  isRaw: boolean;
24
23
  }>;
25
- protected getExtraManipulateQuery(query: SelectQueryBuilder<StorageConfigBase>, filterDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
24
+ protected getExtraManipulateQuery(query: SelectQueryBuilder<StorageConfigBase>, filterDto: any, user: ILoggedUserInfo | null): Promise<{
26
25
  query: SelectQueryBuilder<StorageConfigBase>;
27
26
  isRaw: boolean;
28
27
  }>;