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