@flusys/nestjs-iam 0.1.0-beta.1 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +665 -0
  2. package/cjs/config/iam.constants.js +11 -0
  3. package/cjs/config/index.js +18 -0
  4. package/cjs/controllers/action.controller.js +117 -0
  5. package/cjs/controllers/company-action-permission.controller.js +110 -0
  6. package/cjs/controllers/index.js +23 -0
  7. package/cjs/controllers/my-permission.controller.js +90 -0
  8. package/cjs/controllers/role-permission.controller.js +160 -0
  9. package/cjs/controllers/role.controller.js +58 -0
  10. package/cjs/controllers/user-action-permission.controller.js +110 -0
  11. package/cjs/docs/iam-swagger.config.js +202 -0
  12. package/cjs/docs/index.js +18 -0
  13. package/cjs/dtos/action.dto.js +347 -0
  14. package/cjs/dtos/index.js +21 -0
  15. package/cjs/dtos/permission.dto.js +554 -0
  16. package/cjs/dtos/role.dto.js +238 -0
  17. package/cjs/entities/action-base.entity.js +135 -0
  18. package/cjs/entities/action.entity.js +28 -0
  19. package/cjs/entities/index.js +81 -0
  20. package/cjs/entities/permission-base.entity.js +156 -0
  21. package/cjs/entities/permission-with-company.entity.js +99 -0
  22. package/cjs/entities/role-base.entity.js +86 -0
  23. package/cjs/entities/role-with-company.entity.js +55 -0
  24. package/cjs/entities/role.entity.js +25 -0
  25. package/cjs/entities/user-iam-permission.entity.js +57 -0
  26. package/cjs/enums/action-type.enum.js +22 -0
  27. package/cjs/enums/index.js +19 -0
  28. package/cjs/enums/permission-type.enum.js +16 -0
  29. package/cjs/helpers/index.js +19 -0
  30. package/cjs/helpers/permission-evaluator.helper.js +175 -0
  31. package/cjs/helpers/permission-mode.helper.js +49 -0
  32. package/cjs/index.js +28 -79
  33. package/cjs/interfaces/action.interface.js +4 -0
  34. package/cjs/interfaces/iam-module-async-options.interface.js +4 -0
  35. package/cjs/interfaces/iam-module-options.interface.js +18 -0
  36. package/cjs/interfaces/index.js +21 -0
  37. package/cjs/interfaces/role.interface.js +7 -0
  38. package/cjs/modules/iam.module.js +237 -0
  39. package/cjs/modules/index.js +18 -0
  40. package/cjs/services/action.service.js +253 -0
  41. package/cjs/services/iam-config.service.js +107 -0
  42. package/cjs/services/iam-datasource.provider.js +205 -0
  43. package/cjs/services/index.js +23 -0
  44. package/cjs/services/permission-cache.service.js +308 -0
  45. package/cjs/services/permission.service.js +1020 -0
  46. package/cjs/services/role.service.js +181 -0
  47. package/cjs/types/index.js +18 -0
  48. package/cjs/types/logic-node.type.js +54 -0
  49. package/fesm/config/iam.constants.js +1 -0
  50. package/fesm/config/index.js +1 -0
  51. package/fesm/controllers/action.controller.js +107 -0
  52. package/fesm/controllers/company-action-permission.controller.js +100 -0
  53. package/fesm/controllers/index.js +7 -0
  54. package/fesm/controllers/my-permission.controller.js +80 -0
  55. package/fesm/controllers/role-permission.controller.js +150 -0
  56. package/fesm/controllers/role.controller.js +48 -0
  57. package/fesm/controllers/user-action-permission.controller.js +100 -0
  58. package/fesm/docs/iam-swagger.config.js +192 -0
  59. package/fesm/docs/index.js +1 -0
  60. package/fesm/dtos/action.dto.js +317 -0
  61. package/fesm/dtos/index.js +4 -0
  62. package/fesm/dtos/permission.dto.js +490 -0
  63. package/fesm/dtos/role.dto.js +214 -0
  64. package/fesm/entities/action-base.entity.js +128 -0
  65. package/fesm/entities/action.entity.js +18 -0
  66. package/fesm/entities/index.js +56 -0
  67. package/fesm/entities/permission-base.entity.js +138 -0
  68. package/fesm/entities/permission-with-company.entity.js +89 -0
  69. package/fesm/entities/role-base.entity.js +79 -0
  70. package/fesm/entities/role-with-company.entity.js +45 -0
  71. package/fesm/entities/role.entity.js +15 -0
  72. package/fesm/entities/user-iam-permission.entity.js +38 -0
  73. package/fesm/enums/action-type.enum.js +12 -0
  74. package/fesm/enums/index.js +2 -0
  75. package/fesm/enums/permission-type.enum.js +6 -0
  76. package/fesm/helpers/index.js +2 -0
  77. package/fesm/helpers/permission-evaluator.helper.js +165 -0
  78. package/fesm/helpers/permission-mode.helper.js +49 -0
  79. package/fesm/index.js +11 -79
  80. package/fesm/interfaces/action.interface.js +3 -0
  81. package/fesm/interfaces/iam-module-async-options.interface.js +3 -0
  82. package/fesm/interfaces/iam-module-options.interface.js +1 -0
  83. package/fesm/interfaces/index.js +4 -0
  84. package/fesm/interfaces/role.interface.js +4 -0
  85. package/fesm/modules/iam.module.js +227 -0
  86. package/fesm/modules/index.js +1 -0
  87. package/fesm/services/action.service.js +243 -0
  88. package/fesm/services/iam-config.service.js +97 -0
  89. package/fesm/services/iam-datasource.provider.js +154 -0
  90. package/fesm/services/index.js +6 -0
  91. package/fesm/services/permission-cache.service.js +298 -0
  92. package/fesm/services/permission.service.js +1010 -0
  93. package/fesm/services/role.service.js +171 -0
  94. package/fesm/types/index.js +1 -0
  95. package/fesm/types/logic-node.type.js +36 -0
  96. package/package.json +25 -25
  97. package/cjs/config-index.js +0 -1
  98. package/cjs/controllers-index.js +0 -1
  99. package/cjs/docs-index.js +0 -79
  100. package/cjs/dtos-index.js +0 -1
  101. package/cjs/entities-index.js +0 -1
  102. package/cjs/enums-index.js +0 -1
  103. package/cjs/helpers-index.js +0 -1
  104. package/cjs/interfaces-index.js +0 -1
  105. package/cjs/modules-index.js +0 -1
  106. package/cjs/services-index.js +0 -1
  107. package/cjs/types-index.js +0 -1
  108. package/fesm/config-index.js +0 -1
  109. package/fesm/controllers-index.js +0 -1
  110. package/fesm/docs-index.js +0 -79
  111. package/fesm/dtos-index.js +0 -1
  112. package/fesm/entities-index.js +0 -1
  113. package/fesm/enums-index.js +0 -1
  114. package/fesm/helpers-index.js +0 -1
  115. package/fesm/interfaces-index.js +0 -0
  116. package/fesm/modules-index.js +0 -1
  117. package/fesm/services-index.js +0 -1
  118. package/fesm/types-index.js +0 -1
@@ -0,0 +1,227 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ import { CacheModule, UtilsModule } from '@flusys/nestjs-shared/modules';
8
+ import { Module, Scope } from '@nestjs/common';
9
+ import { getRepositoryToken } from '@nestjs/typeorm';
10
+ import { IAM_MODULE_OPTIONS } from '../config/iam.constants';
11
+ import { ActionController, CompanyActionPermissionController, MyPermissionController, RoleController, RolePermissionController, UserActionPermissionController } from '../controllers';
12
+ import { Action, Role, RoleWithCompany, UserIamPermission, UserIamPermissionWithCompany } from '../entities';
13
+ import { IAMPermissionMode } from '../enums/permission-type.enum';
14
+ import { PermissionEvaluatorHelper, PermissionModeHelper } from '../helpers';
15
+ import { ActionService, PermissionService, RoleService } from '../services';
16
+ import { IAMConfigService } from '../services/iam-config.service';
17
+ import { IAMDataSourceProvider } from '../services/iam-datasource.provider';
18
+ import { PermissionCacheService } from '../services/permission-cache.service';
19
+ export class IAMModule {
20
+ static getControllers(permissionMode, enableCompanyFeature) {
21
+ const baseControllers = [
22
+ ActionController,
23
+ MyPermissionController
24
+ ];
25
+ // Direct permission mode - user actions only
26
+ if (permissionMode === IAMPermissionMode.DIRECT) {
27
+ baseControllers.push(UserActionPermissionController);
28
+ }
29
+ // RBAC mode - role actions and user roles only
30
+ if (permissionMode === IAMPermissionMode.RBAC) {
31
+ baseControllers.push(RoleController);
32
+ baseControllers.push(RolePermissionController);
33
+ }
34
+ // FULL mode - all permission controllers
35
+ if (permissionMode === IAMPermissionMode.FULL) {
36
+ baseControllers.push(RoleController);
37
+ baseControllers.push(UserActionPermissionController);
38
+ baseControllers.push(RolePermissionController);
39
+ }
40
+ // Company action permissions - only if company feature enabled
41
+ if (enableCompanyFeature) {
42
+ baseControllers.push(CompanyActionPermissionController);
43
+ }
44
+ return baseControllers;
45
+ }
46
+ static getEntities(permissionMode, enableCompanyFeature) {
47
+ // Core entities
48
+ const entities = [];
49
+ // Action entity - always included
50
+ entities.push(Action);
51
+ // Permission entity is always needed
52
+ if (enableCompanyFeature) {
53
+ entities.push(UserIamPermissionWithCompany);
54
+ } else {
55
+ entities.push(UserIamPermission);
56
+ }
57
+ // Role entity - Only for RBAC or FULL mode
58
+ if (permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL) {
59
+ if (enableCompanyFeature) {
60
+ entities.push(RoleWithCompany);
61
+ } else {
62
+ entities.push(Role);
63
+ }
64
+ }
65
+ return entities;
66
+ }
67
+ static getServices(permissionMode) {
68
+ const services = [
69
+ ActionService,
70
+ PermissionService,
71
+ PermissionCacheService,
72
+ PermissionEvaluatorHelper
73
+ ];
74
+ // RoleService - Only for RBAC or FULL mode
75
+ if (permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL) {
76
+ services.push(RoleService);
77
+ }
78
+ return services;
79
+ }
80
+ /**
81
+ * Create repository providers that use IAMDataSourceProvider
82
+ * This replaces TypeOrmModule.forFeature() functionality
83
+ */ static getRepositoryProviders(permissionMode, enableCompanyFeature) {
84
+ const entities = this.getEntities(permissionMode, enableCompanyFeature);
85
+ return entities.map((entity)=>({
86
+ provide: getRepositoryToken(entity),
87
+ scope: Scope.REQUEST,
88
+ useFactory: async (dataSourceProvider)=>{
89
+ return await dataSourceProvider.getRepository(entity);
90
+ },
91
+ inject: [
92
+ IAMDataSourceProvider
93
+ ]
94
+ }));
95
+ }
96
+ static forRoot(options = {}) {
97
+ const { global = false, includeController = false } = options;
98
+ const databaseMode = options.bootstrapAppConfig?.databaseMode;
99
+ const enableCompanyFeature = options.bootstrapAppConfig?.enableCompanyFeature ?? false;
100
+ // Read permissionMode from bootstrap config using helper
101
+ const permissionMode = PermissionModeHelper.fromString(options.bootstrapAppConfig?.permissionMode);
102
+ const isMultiTenant = databaseMode === 'multi-tenant';
103
+ const entities = this.getEntities(permissionMode, enableCompanyFeature);
104
+ const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
105
+ const providers = [
106
+ {
107
+ provide: IAM_MODULE_OPTIONS,
108
+ useValue: options
109
+ },
110
+ IAMConfigService,
111
+ IAMDataSourceProvider,
112
+ ...this.getServices(permissionMode)
113
+ ];
114
+ const imports = [
115
+ CacheModule,
116
+ UtilsModule
117
+ ];
118
+ const module = {
119
+ module: IAMModule,
120
+ imports,
121
+ controllers,
122
+ providers,
123
+ exports: [
124
+ IAMConfigService,
125
+ IAMDataSourceProvider,
126
+ ActionService,
127
+ PermissionService,
128
+ PermissionCacheService,
129
+ PermissionEvaluatorHelper,
130
+ ...permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL ? [
131
+ RoleService
132
+ ] : []
133
+ ]
134
+ };
135
+ if (global) {
136
+ return {
137
+ ...module,
138
+ global: true
139
+ };
140
+ }
141
+ return module;
142
+ }
143
+ static forRootAsync(asyncOptions) {
144
+ const { global = false, includeController = false, imports: externalImports = [] } = asyncOptions;
145
+ const databaseMode = asyncOptions.bootstrapAppConfig?.databaseMode;
146
+ const enableCompanyFeature = asyncOptions.bootstrapAppConfig?.enableCompanyFeature ?? false;
147
+ // Read permissionMode from bootstrap config using helper
148
+ const permissionMode = PermissionModeHelper.fromString(asyncOptions.bootstrapAppConfig?.permissionMode);
149
+ const isMultiTenant = databaseMode === 'multi-tenant';
150
+ const entities = this.getEntities(permissionMode, enableCompanyFeature);
151
+ const controllers = includeController ? this.getControllers(permissionMode, enableCompanyFeature) : [];
152
+ const asyncProviders = this.createAsyncProviders(asyncOptions);
153
+ const providers = [
154
+ ...asyncProviders,
155
+ IAMConfigService,
156
+ IAMDataSourceProvider,
157
+ ...this.getServices(permissionMode)
158
+ ];
159
+ const imports = [
160
+ ...externalImports,
161
+ CacheModule,
162
+ UtilsModule
163
+ ];
164
+ const module = {
165
+ module: IAMModule,
166
+ imports,
167
+ controllers,
168
+ providers,
169
+ exports: [
170
+ IAMConfigService,
171
+ IAMDataSourceProvider,
172
+ ActionService,
173
+ PermissionService,
174
+ PermissionCacheService,
175
+ PermissionEvaluatorHelper,
176
+ ...permissionMode === IAMPermissionMode.RBAC || permissionMode === IAMPermissionMode.FULL ? [
177
+ RoleService
178
+ ] : []
179
+ ]
180
+ };
181
+ if (global) {
182
+ return {
183
+ ...module,
184
+ global: true
185
+ };
186
+ }
187
+ return module;
188
+ }
189
+ static createAsyncProviders(options) {
190
+ if (options.useExisting || options.useFactory) {
191
+ return [
192
+ this.createAsyncOptionsProvider(options)
193
+ ];
194
+ }
195
+ const useClass = options.useClass;
196
+ return [
197
+ this.createAsyncOptionsProvider(options),
198
+ {
199
+ provide: useClass,
200
+ useClass
201
+ }
202
+ ];
203
+ }
204
+ static createAsyncOptionsProvider(options) {
205
+ if (options.useFactory) {
206
+ return {
207
+ provide: IAM_MODULE_OPTIONS,
208
+ useFactory: options.useFactory,
209
+ inject: options.inject || []
210
+ };
211
+ }
212
+ const inject = [
213
+ options.useClass || options.useExisting
214
+ ];
215
+ return {
216
+ provide: IAM_MODULE_OPTIONS,
217
+ useFactory: async (optionsFactory)=>optionsFactory.createIAMOptions(),
218
+ inject
219
+ };
220
+ }
221
+ static forFeature(options = {}) {
222
+ return this.forRoot(options);
223
+ }
224
+ }
225
+ IAMModule = _ts_decorate([
226
+ Module({})
227
+ ], IAMModule);
@@ -0,0 +1 @@
1
+ export * from './iam.module';
@@ -0,0 +1,243 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _ts_decorate(decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ }
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ function _ts_param(paramIndex, decorator) {
24
+ return function(target, key) {
25
+ decorator(target, key, paramIndex);
26
+ };
27
+ }
28
+ import { RequestScopedApiService, HybridCache } from '@flusys/nestjs-shared/classes';
29
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
30
+ import { Inject, Injectable, Logger, NotFoundException, Scope } from '@nestjs/common';
31
+ import { In } from 'typeorm';
32
+ import { Action } from '../entities/action.entity';
33
+ import { IAMConfigService } from './iam-config.service';
34
+ import { IAMDataSourceProvider } from './iam-datasource.provider';
35
+ import { PermissionService } from './permission.service';
36
+ export class ActionService extends RequestScopedApiService {
37
+ /**
38
+ * Resolve entity class for this service
39
+ * @returns Action entity class
40
+ */ resolveEntity() {
41
+ return Action;
42
+ }
43
+ /**
44
+ * Get DataSource provider for this service
45
+ * @returns IAMDataSourceProvider instance
46
+ */ getDataSourceProvider() {
47
+ return this.dataSourceProvider;
48
+ }
49
+ // ==================== Entity Conversion ====================
50
+ async convertSingleDtoToEntity(dto, _user) {
51
+ if (!('id' in dto) || !dto.id) {
52
+ return dto;
53
+ }
54
+ const existingAction = await this.repository.findOne({
55
+ where: {
56
+ id: dto.id
57
+ }
58
+ });
59
+ if (!existingAction) {
60
+ throw new NotFoundException(`Action with ID ${dto.id} not found`);
61
+ }
62
+ return {
63
+ ...existingAction,
64
+ ...dto
65
+ };
66
+ }
67
+ async getSelectQuery(query, _user, select) {
68
+ if (!select || !select.length) {
69
+ select = [
70
+ 'id',
71
+ 'name',
72
+ 'code',
73
+ 'description',
74
+ 'actionType',
75
+ 'permissionLogic',
76
+ 'isActive',
77
+ 'parentId',
78
+ 'serial',
79
+ 'createdAt'
80
+ ];
81
+ }
82
+ const selectFields = select.map((field)=>`${this.entityName}.${field}`);
83
+ query.select(selectFields);
84
+ return {
85
+ query,
86
+ isRaw: false
87
+ };
88
+ }
89
+ async getGlobalSearchQuery(query, search, _user) {
90
+ query.andWhere('(action.name LIKE :search OR action.code LIKE :search OR action.description LIKE :search)', {
91
+ search: `%${search}%`
92
+ });
93
+ return {
94
+ query,
95
+ isRaw: false
96
+ };
97
+ }
98
+ /**
99
+ * Override: Convert entity to response DTO
100
+ */ convertEntityToResponseDto(entity, _isRaw) {
101
+ return {
102
+ id: entity.id,
103
+ readOnly: entity.readOnly,
104
+ name: entity.name,
105
+ description: entity.description,
106
+ code: entity.code,
107
+ actionType: entity.actionType,
108
+ permissionLogic: entity.permissionLogic,
109
+ serial: entity.serial,
110
+ isActive: entity.isActive,
111
+ parentId: entity.parentId,
112
+ metadata: entity.metadata,
113
+ createdAt: entity.createdAt,
114
+ updatedAt: entity.updatedAt,
115
+ deletedAt: entity.deletedAt,
116
+ createdById: entity.createdById,
117
+ updatedById: entity.updatedById,
118
+ deletedById: entity.deletedById
119
+ };
120
+ }
121
+ /**
122
+ * Get actions available for permission assignment (filtered by company whitelist)
123
+ *
124
+ * @param user - Logged in user info
125
+ * @returns Array of actions with id, code, and name fields
126
+ */ async getActionsForPermission(user) {
127
+ await this.ensureRepositoryInitialized();
128
+ if (!user) {
129
+ throw new Error('User is required for getActionsForPermission');
130
+ }
131
+ const selectFields = [
132
+ 'id',
133
+ 'code',
134
+ 'name',
135
+ 'description',
136
+ 'actionType',
137
+ 'permissionLogic',
138
+ 'isActive',
139
+ 'parentId',
140
+ 'serial'
141
+ ];
142
+ const enableCompanyFeature = this.iamConfigService.isCompanyFeatureEnabled();
143
+ if (enableCompanyFeature && user.companyId) {
144
+ const companyActionIds = await this.permissionService.getCompanyActionIds(user.companyId);
145
+ if (companyActionIds.length === 0) {
146
+ return [];
147
+ }
148
+ const actions = await this.repository.find({
149
+ where: {
150
+ id: In(companyActionIds)
151
+ },
152
+ select: selectFields
153
+ });
154
+ return actions.map((action)=>this.convertEntityToResponseDto(action, false));
155
+ }
156
+ const actions = await this.repository.find({
157
+ select: selectFields
158
+ });
159
+ return actions.map((action)=>this.convertEntityToResponseDto(action, false));
160
+ }
161
+ /**
162
+ * Get actions in hierarchical tree structure
163
+ *
164
+ * @param user - Logged in user info for company filtering
165
+ * @param search - Optional search term (name or code)
166
+ * @param isActive - Optional filter by active status
167
+ * @param withDeleted - Include deleted actions (default: false)
168
+ * @returns Array of root actions with nested children
169
+ */ async getActionTree(user, search, isActive, withDeleted = false) {
170
+ await this.ensureRepositoryInitialized();
171
+ if (!user) {
172
+ throw new Error('User is required for getActionTree');
173
+ }
174
+ const query = this.repository.createQueryBuilder('action');
175
+ if (!withDeleted) {
176
+ query.andWhere('action.deletedAt IS NULL');
177
+ }
178
+ if (isActive !== undefined) {
179
+ query.andWhere('action.isActive = :isActive', {
180
+ isActive
181
+ });
182
+ }
183
+ if (search?.trim()) {
184
+ query.andWhere('(action.name LIKE :search OR action.code LIKE :search)', {
185
+ search: `%${search.trim()}%`
186
+ });
187
+ }
188
+ const actions = await query.orderBy('action.serial', 'ASC').getMany();
189
+ return this.buildActionTree(actions);
190
+ }
191
+ buildActionTree(actions) {
192
+ if (!actions?.length) {
193
+ return [];
194
+ }
195
+ const map = new Map();
196
+ const rootNodes = [];
197
+ for (const action of actions){
198
+ const treeNode = {
199
+ ...this.convertEntityToResponseDto(action, false),
200
+ children: []
201
+ };
202
+ map.set(action.id, treeNode);
203
+ }
204
+ for (const action of actions){
205
+ const node = map.get(action.id);
206
+ if (!node) {
207
+ continue;
208
+ }
209
+ if (action.parentId && map.has(action.parentId)) {
210
+ const parent = map.get(action.parentId);
211
+ if (parent?.children) {
212
+ parent.children.push(node);
213
+ }
214
+ } else {
215
+ rootNodes.push(node);
216
+ }
217
+ }
218
+ return rootNodes;
219
+ }
220
+ // NOTE: @Inject() required for bundled code - type metadata may be lost during esbuild
221
+ constructor(cacheManager, utilsService, iamConfigService, dataSourceProvider, permissionService){
222
+ // Repository will be set asynchronously by RequestScopedApiService
223
+ super('action', null, cacheManager, utilsService, ActionService.name, true), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "iamConfigService", void 0), _define_property(this, "dataSourceProvider", void 0), _define_property(this, "permissionService", void 0), _define_property(this, "logger", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.iamConfigService = iamConfigService, this.dataSourceProvider = dataSourceProvider, this.permissionService = permissionService, this.logger = new Logger(ActionService.name);
224
+ }
225
+ }
226
+ ActionService = _ts_decorate([
227
+ Injectable({
228
+ scope: Scope.REQUEST
229
+ }),
230
+ _ts_param(0, Inject('CACHE_INSTANCE')),
231
+ _ts_param(1, Inject(UtilsService)),
232
+ _ts_param(2, Inject(IAMConfigService)),
233
+ _ts_param(3, Inject(IAMDataSourceProvider)),
234
+ _ts_param(4, Inject(PermissionService)),
235
+ _ts_metadata("design:type", Function),
236
+ _ts_metadata("design:paramtypes", [
237
+ typeof HybridCache === "undefined" ? Object : HybridCache,
238
+ typeof UtilsService === "undefined" ? Object : UtilsService,
239
+ typeof IAMConfigService === "undefined" ? Object : IAMConfigService,
240
+ typeof IAMDataSourceProvider === "undefined" ? Object : IAMDataSourceProvider,
241
+ typeof PermissionService === "undefined" ? Object : PermissionService
242
+ ])
243
+ ], ActionService);
@@ -0,0 +1,97 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _ts_decorate(decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ }
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ function _ts_param(paramIndex, decorator) {
24
+ return function(target, key) {
25
+ decorator(target, key, paramIndex);
26
+ };
27
+ }
28
+ import { Inject, Injectable, Optional } from '@nestjs/common';
29
+ import { IAM_MODULE_OPTIONS } from '../config/iam.constants';
30
+ import { IAMPermissionMode } from '../enums/permission-type.enum';
31
+ import { PermissionModeHelper } from '../helpers';
32
+ import { IAMModuleOptions } from '../interfaces/iam-module-options.interface';
33
+ export class IAMConfigService {
34
+ // ==================== Database Mode ====================
35
+ /**
36
+ * Get database mode (single or multi-tenant)
37
+ */ getDatabaseMode() {
38
+ return this.options.bootstrapAppConfig?.databaseMode ?? 'single';
39
+ }
40
+ /**
41
+ * Check if running in multi-tenant mode
42
+ */ isMultiTenant() {
43
+ return this.getDatabaseMode() === 'multi-tenant';
44
+ }
45
+ // ==================== Company Feature ====================
46
+ /**
47
+ * Get enable company feature flag
48
+ */ getEnableCompanyFeature() {
49
+ return this.options.bootstrapAppConfig?.enableCompanyFeature ?? false;
50
+ }
51
+ /**
52
+ * Check if company feature is enabled (alias for getEnableCompanyFeature)
53
+ */ isCompanyFeatureEnabled() {
54
+ return this.getEnableCompanyFeature();
55
+ }
56
+ // ==================== Permission Mode ====================
57
+ /**
58
+ * Get permission mode from bootstrap config
59
+ *
60
+ * **Note:** Reads from bootstrapAppConfig (not runtime config)
61
+ * because permissionMode affects entity/controller registration.
62
+ */ getPermissionMode() {
63
+ return PermissionModeHelper.fromString(this.options.bootstrapAppConfig?.permissionMode);
64
+ }
65
+ /**
66
+ * Check if RBAC (role-based) permissions are enabled
67
+ */ isRbacEnabled() {
68
+ const mode = this.getPermissionMode();
69
+ return mode === IAMPermissionMode.RBAC || mode === IAMPermissionMode.FULL;
70
+ }
71
+ /**
72
+ * Check if direct (user-level) permissions are enabled
73
+ */ isDirectPermissionEnabled() {
74
+ const mode = this.getPermissionMode();
75
+ return mode === IAMPermissionMode.DIRECT || mode === IAMPermissionMode.FULL;
76
+ }
77
+ // ==================== Options ====================
78
+ getOptions() {
79
+ return this.options;
80
+ }
81
+ constructor(injectedOptions){
82
+ _define_property(this, "options", void 0);
83
+ this.options = injectedOptions ?? {
84
+ global: false,
85
+ includeController: false
86
+ };
87
+ }
88
+ }
89
+ IAMConfigService = _ts_decorate([
90
+ Injectable(),
91
+ _ts_param(0, Optional()),
92
+ _ts_param(0, Inject(IAM_MODULE_OPTIONS)),
93
+ _ts_metadata("design:type", Function),
94
+ _ts_metadata("design:paramtypes", [
95
+ typeof IAMModuleOptions === "undefined" ? Object : IAMModuleOptions
96
+ ])
97
+ ], IAMConfigService);