@solidxai/core 0.1.10 → 0.1.11-beta.1

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 (158) hide show
  1. package/dist/controllers/datasource-introspection.controller.d.ts +234 -0
  2. package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -0
  3. package/dist/controllers/datasource-introspection.controller.js +98 -0
  4. package/dist/controllers/datasource-introspection.controller.js.map +1 -0
  5. package/dist/controllers/datasource-management.controller.d.ts +18 -0
  6. package/dist/controllers/datasource-management.controller.d.ts.map +1 -0
  7. package/dist/controllers/datasource-management.controller.js +55 -0
  8. package/dist/controllers/datasource-management.controller.js.map +1 -0
  9. package/dist/dtos/create-datasource-management.dto.d.ts +25 -0
  10. package/dist/dtos/create-datasource-management.dto.d.ts.map +1 -0
  11. package/dist/dtos/create-datasource-management.dto.js +169 -0
  12. package/dist/dtos/create-datasource-management.dto.js.map +1 -0
  13. package/dist/dtos/datasource-introspection-mapping.dto.d.ts +45 -0
  14. package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -0
  15. package/dist/dtos/datasource-introspection-mapping.dto.js +233 -0
  16. package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -0
  17. package/dist/index.d.ts +5 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +5 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/interfaces/datasource-introspection-provider.interface.d.ts +26 -0
  22. package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -0
  23. package/dist/interfaces/datasource-introspection-provider.interface.js +3 -0
  24. package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -0
  25. package/dist/repository/scheduled-job.repository.d.ts +3 -0
  26. package/dist/repository/scheduled-job.repository.d.ts.map +1 -1
  27. package/dist/repository/scheduled-job.repository.js +60 -0
  28. package/dist/repository/scheduled-job.repository.js.map +1 -1
  29. package/dist/seeders/module-metadata-seeder.service.d.ts +32 -1
  30. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  31. package/dist/seeders/module-metadata-seeder.service.js +1011 -230
  32. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  33. package/dist/seeders/seed-data/solid-core-metadata.json +21 -0
  34. package/dist/services/action-metadata.service.d.ts +7 -0
  35. package/dist/services/action-metadata.service.d.ts.map +1 -1
  36. package/dist/services/action-metadata.service.js +76 -3
  37. package/dist/services/action-metadata.service.js.map +1 -1
  38. package/dist/services/authentication.service.js +1 -1
  39. package/dist/services/authentication.service.js.map +1 -1
  40. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.d.ts.map +1 -1
  41. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js +2 -2
  42. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js.map +1 -1
  43. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.d.ts.map +1 -1
  44. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js +2 -2
  45. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js.map +1 -1
  46. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts +3 -0
  47. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts.map +1 -1
  48. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js +71 -0
  49. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js.map +1 -1
  50. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.d.ts.map +1 -1
  51. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js +3 -3
  52. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js.map +1 -1
  53. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts +11 -0
  54. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -0
  55. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +181 -0
  56. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -0
  57. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts +11 -0
  58. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -0
  59. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +90 -0
  60. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -0
  61. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts +11 -0
  62. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -0
  63. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +156 -0
  64. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -0
  65. package/dist/services/datasource-introspection.service.d.ts +288 -0
  66. package/dist/services/datasource-introspection.service.d.ts.map +1 -0
  67. package/dist/services/datasource-introspection.service.js +1278 -0
  68. package/dist/services/datasource-introspection.service.js.map +1 -0
  69. package/dist/services/datasource-management.service.d.ts +60 -0
  70. package/dist/services/datasource-management.service.d.ts.map +1 -0
  71. package/dist/services/datasource-management.service.js +461 -0
  72. package/dist/services/datasource-management.service.js.map +1 -0
  73. package/dist/services/field-metadata.service.d.ts.map +1 -1
  74. package/dist/services/field-metadata.service.js +19 -0
  75. package/dist/services/field-metadata.service.js.map +1 -1
  76. package/dist/services/model-metadata.service.d.ts +1 -3
  77. package/dist/services/model-metadata.service.d.ts.map +1 -1
  78. package/dist/services/model-metadata.service.js +47 -15
  79. package/dist/services/model-metadata.service.js.map +1 -1
  80. package/dist/services/role-metadata.service.d.ts +5 -0
  81. package/dist/services/role-metadata.service.d.ts.map +1 -1
  82. package/dist/services/role-metadata.service.js +85 -31
  83. package/dist/services/role-metadata.service.js.map +1 -1
  84. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.d.ts.map +1 -1
  85. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js +2 -3
  86. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js.map +1 -1
  87. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.d.ts.map +1 -1
  88. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js +2 -3
  89. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js.map +1 -1
  90. package/dist/services/setting.service.d.ts +1 -0
  91. package/dist/services/setting.service.d.ts.map +1 -1
  92. package/dist/services/setting.service.js +32 -8
  93. package/dist/services/setting.service.js.map +1 -1
  94. package/dist/services/solid-ts-morph.service.d.ts +1 -1
  95. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  96. package/dist/services/solid-ts-morph.service.js.map +1 -1
  97. package/dist/services/view-metadata.service.d.ts +6 -0
  98. package/dist/services/view-metadata.service.d.ts.map +1 -1
  99. package/dist/services/view-metadata.service.js +66 -1
  100. package/dist/services/view-metadata.service.js.map +1 -1
  101. package/dist/solid-core.module.d.ts.map +1 -1
  102. package/dist/solid-core.module.js +16 -0
  103. package/dist/solid-core.module.js.map +1 -1
  104. package/dist-tests/api/authenticate.spec.js +119 -0
  105. package/dist-tests/api/authenticate.spec.js.map +1 -0
  106. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
  107. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
  108. package/dist-tests/api/ping.spec.js +21 -0
  109. package/dist-tests/api/ping.spec.js.map +1 -0
  110. package/dist-tests/helpers/auth.js +41 -0
  111. package/dist-tests/helpers/auth.js.map +1 -0
  112. package/dist-tests/helpers/env.js +11 -0
  113. package/dist-tests/helpers/env.js.map +1 -0
  114. package/docs/agent-hub-grooming.md +301 -0
  115. package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
  116. package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
  117. package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
  118. package/docs/datasource-introspection-ddl-analysis.md +326 -0
  119. package/docs/datasource-introspection-implementation-plan.md +306 -0
  120. package/docs/grouping-enhancements.md +89 -0
  121. package/docs/java-spring/README.md +3 -0
  122. package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
  123. package/docs/module-package-import-handoff.md +691 -0
  124. package/docs/seed-changes.md +65 -0
  125. package/docs/test-data-workflow.md +200 -0
  126. package/docs/type-declaration-import-issue.md +24 -0
  127. package/package.json +1 -1
  128. package/src/controllers/datasource-introspection.controller.ts +58 -0
  129. package/src/controllers/datasource-management.controller.ts +24 -0
  130. package/src/dtos/create-datasource-management.dto.ts +139 -0
  131. package/src/dtos/datasource-introspection-mapping.dto.ts +182 -0
  132. package/src/index.ts +5 -0
  133. package/src/interfaces/datasource-introspection-provider.interface.ts +28 -0
  134. package/src/repository/scheduled-job.repository.ts +73 -0
  135. package/src/seeders/module-metadata-seeder.service.ts +1223 -262
  136. package/src/seeders/seed-data/solid-core-metadata.json +22 -1
  137. package/src/services/action-metadata.service.ts +87 -2
  138. package/src/services/authentication.service.ts +1 -1
  139. package/src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts +9 -4
  140. package/src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts +9 -4
  141. package/src/services/dashboard-providers/mq-dashboard-provider-utils.ts +82 -0
  142. package/src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts +10 -4
  143. package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +185 -0
  144. package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +95 -0
  145. package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +160 -0
  146. package/src/services/datasource-introspection.service.ts +1536 -0
  147. package/src/services/datasource-management.service.ts +566 -0
  148. package/src/services/field-metadata.service.ts +21 -1
  149. package/src/services/model-metadata.service.ts +50 -13
  150. package/src/services/role-metadata.service.ts +100 -47
  151. package/src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts +2 -4
  152. package/src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts +2 -4
  153. package/src/services/setting.service.ts +43 -12
  154. package/src/services/solid-ts-morph.service.ts +2 -2
  155. package/src/services/view-metadata.service.ts +79 -1
  156. package/src/solid-core.module.ts +16 -0
  157. package/.claude/settings.local.json +0 -15
  158. package/src/services/1.js +0 -6
@@ -30,6 +30,7 @@ let RoleMetadataService = RoleMetadataService_1 = class RoleMetadataService exte
30
30
  this.permissionRepository = permissionRepository;
31
31
  this.moduleRef = moduleRef;
32
32
  this.logger = new common_1.Logger(RoleMetadataService_1.name);
33
+ this.permissionAssignmentBatchSize = 500;
33
34
  }
34
35
  async findRoleByName(roleName) {
35
36
  const entity = await this.repo.findOne({
@@ -45,6 +46,19 @@ let RoleMetadataService = RoleMetadataService_1 = class RoleMetadataService exte
45
46
  }
46
47
  return entity;
47
48
  }
49
+ async assertRoleExistsByName(roleName) {
50
+ const entity = await this.repo.findOne({
51
+ where: {
52
+ name: roleName
53
+ },
54
+ select: {
55
+ id: true
56
+ }
57
+ });
58
+ if (!entity) {
59
+ throw new common_1.NotFoundException(`Entity #${roleName} not found`);
60
+ }
61
+ }
48
62
  async createRolesIfNotExists(roles) {
49
63
  for (let id = 0; id < roles.length; id++) {
50
64
  try {
@@ -84,46 +98,41 @@ let RoleMetadataService = RoleMetadataService_1 = class RoleMetadataService exte
84
98
  async _addPermissionsToRole(roleName, permissionNames) {
85
99
  const role = await this.repo.findOne({
86
100
  where: { name: roleName },
87
- relations: {
88
- permissions: true
101
+ select: {
102
+ id: true,
103
+ name: true,
89
104
  }
90
105
  });
91
106
  if (!role) {
92
107
  throw new Error(`Role '${roleName}' not found.`);
93
108
  }
94
- let newPermissions;
95
- if (permissionNames && permissionNames.length != 0) {
96
- newPermissions = await this.permissionRepository.find({ where: { name: (0, typeorm_2.In)(permissionNames) } });
97
- if (newPermissions.length !== permissionNames.length) {
98
- throw new Error(`One or more permissions not found.`);
99
- }
109
+ const joinInfo = this.getRolePermissionJoinInfo();
110
+ const targetPermissions = await this.loadTargetPermissions(permissionNames);
111
+ if (!permissionNames || permissionNames.length === 0) {
112
+ await this.entityManager
113
+ .createQueryBuilder()
114
+ .delete()
115
+ .from(joinInfo.tableName)
116
+ .where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })
117
+ .execute();
118
+ await this.insertRolePermissionMappings(role.id, targetPermissions.map((permission) => permission.id), joinInfo);
100
119
  }
101
120
  else {
102
- newPermissions = await this.permissionRepository.find();
103
- if (newPermissions.length == 0) {
104
- throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);
105
- }
106
- }
107
- if (role.permissions && role.permissions.length > 0) {
108
- for (let i = 0; i < newPermissions.length; i++) {
109
- const newPermission = newPermissions[i];
110
- let newPermissionFound = true;
111
- for (let j = 0; j < role.permissions.length; j++) {
112
- const existingPermission = role.permissions[j];
113
- if (existingPermission.name === newPermission.name) {
114
- newPermissionFound = false;
115
- break;
116
- }
117
- }
118
- if (newPermissionFound) {
119
- role.permissions.push(newPermission);
120
- }
121
+ const existingRows = await this.entityManager
122
+ .createQueryBuilder()
123
+ .select(joinInfo.permissionIdColumn, 'permissionId')
124
+ .from(joinInfo.tableName, 'role_permission')
125
+ .where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })
126
+ .getRawMany();
127
+ const existingPermissionIds = new Set(existingRows.map((row) => Number(row.permissionId)));
128
+ const missingPermissionIds = targetPermissions
129
+ .map((permission) => permission.id)
130
+ .filter((permissionId) => !existingPermissionIds.has(permissionId));
131
+ if (missingPermissionIds.length > 0) {
132
+ await this.insertRolePermissionMappings(role.id, missingPermissionIds, joinInfo);
121
133
  }
122
134
  }
123
- else {
124
- role.permissions = newPermissions;
125
- }
126
- return await this.repo.save(role);
135
+ return await this.findRoleByName(roleName);
127
136
  }
128
137
  async removePermissionsFromRole(roleName, permissionNames) {
129
138
  const role = await this.repo.findOne({
@@ -149,6 +158,51 @@ let RoleMetadataService = RoleMetadataService_1 = class RoleMetadataService exte
149
158
  }
150
159
  return existingPermission;
151
160
  }
161
+ async loadTargetPermissions(permissionNames) {
162
+ if (permissionNames && permissionNames.length !== 0) {
163
+ const uniquePermissionNames = [...new Set(permissionNames)];
164
+ const permissions = await this.permissionRepository.find({ where: { name: (0, typeorm_2.In)(uniquePermissionNames) } });
165
+ if (permissions.length !== uniquePermissionNames.length) {
166
+ throw new Error(`One or more permissions not found.`);
167
+ }
168
+ return permissions;
169
+ }
170
+ const permissions = await this.permissionRepository.find();
171
+ if (permissions.length === 0) {
172
+ throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);
173
+ }
174
+ return permissions;
175
+ }
176
+ getRolePermissionJoinInfo() {
177
+ const relation = this.repo.metadata.relations.find((candidate) => candidate.propertyName === 'permissions');
178
+ if (!relation?.junctionEntityMetadata) {
179
+ throw new Error('Role-permission join table metadata not found.');
180
+ }
181
+ const roleIdColumn = relation.joinColumns[0]?.databaseName;
182
+ const permissionIdColumn = relation.inverseJoinColumns[0]?.databaseName;
183
+ if (!roleIdColumn || !permissionIdColumn) {
184
+ throw new Error('Role-permission join table column metadata not found.');
185
+ }
186
+ return {
187
+ tableName: relation.junctionEntityMetadata.tableName,
188
+ roleIdColumn,
189
+ permissionIdColumn,
190
+ };
191
+ }
192
+ async insertRolePermissionMappings(roleId, permissionIds, joinInfo) {
193
+ for (let index = 0; index < permissionIds.length; index += this.permissionAssignmentBatchSize) {
194
+ const batch = permissionIds.slice(index, index + this.permissionAssignmentBatchSize);
195
+ await this.entityManager
196
+ .createQueryBuilder()
197
+ .insert()
198
+ .into(joinInfo.tableName)
199
+ .values(batch.map((permissionId) => ({
200
+ [joinInfo.roleIdColumn]: roleId,
201
+ [joinInfo.permissionIdColumn]: permissionId,
202
+ })))
203
+ .execute();
204
+ }
205
+ }
152
206
  };
153
207
  exports.RoleMetadataService = RoleMetadataService;
154
208
  exports.RoleMetadataService = RoleMetadataService = RoleMetadataService_1 = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"role-metadata.service.js","sourceRoot":"","sources":["../../src/services/role-metadata.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { EntityManager, In } from 'typeorm';\n\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PermissionMetadataRepository } from 'src/repository/permission-metadata.repository';\nimport { RoleMetadataRepository } from 'src/repository/role-metadata.repository';\nimport { CreateRoleMetadataDto } from '../dtos/create-role-metadata.dto';\nimport { PermissionMetadata } from '../entities/permission-metadata.entity';\nimport { RoleMetadata } from '../entities/role-metadata.entity';\n\n@Injectable()\nexport class RoleMetadataService extends CRUDService<RoleMetadata> {\n private readonly logger = new Logger(RoleMetadataService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(RoleMetadata, 'default')\n // readonly repo: Repository<RoleMetadata>,\n readonly repo: RoleMetadataRepository,\n // @InjectRepository(PermissionMetadata)\n // private readonly permissionRepository: Repository<PermissionMetadata>,\n readonly permissionRepository: PermissionMetadataRepository,\n readonly moduleRef: ModuleRef\n\n ) {\n super(entityManager, repo, 'roleMetadata', 'solid-core', moduleRef);\n }\n\n async findRoleByName(roleName: string) {\n const entity = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n if (!entity) {\n throw new NotFoundException(`Entity #${roleName} not found`);\n }\n return entity;\n }\n\n // OK\n async createRolesIfNotExists(roles: CreateRoleMetadataDto[]) {\n for (let id = 0; id < roles.length; id++) {\n try {\n const roleObj = roles[id];\n // this.logger.log(`Resolving role: ${JSON.stringify(roleObj)}`);\n\n const existingRole = await this.repo.findOne({\n where: {\n name: roleObj.name,\n },\n relations: {},\n });\n\n // Create only if not existing already.\n if (!existingRole) {\n this.logger.debug(`Role ${roleObj.name} does not exist, hence creating`);\n\n let permissions = [];\n\n if (roleObj.permissions && roleObj.permissions.length > 0) {\n await Promise.all(\n roleObj.permissions.map(permission => this.preloadPermissionByName(permission.name)),\n );\n }\n\n // const role = this.repo.create({ ...roleObj, permissions });\n const role = this.repo.create({ ...roleObj });\n await this.repo.save(role);\n } else {\n /*\n this.logger.debug(`Role ${roleObj.name} already exists`);\n const existingPermissions = existingRole.permissions.map(permission => permission.name);\n const newPermissions = roleObj.permissions.map(permission => permission.name);\n const permissionsToAdd = newPermissions.filter(permission => !existingPermissions.includes(permission));\n const permissionsToRemove = existingPermissions.filter(permission => !newPermissions.includes(permission));\n this.logger.debug(`Permissions to add: ${JSON.stringify(permissionsToAdd)}`);\n if (permissionsToAdd.length > 0) {\n await this.addPermissionsToRole(roleObj.name, permissionsToAdd);\n }\n this.logger.debug(`Permissions to remove: ${JSON.stringify(permissionsToRemove)}`);\n if (permissionsToRemove.length > 0) {\n await this.removePermissionsFromRole(roleObj.name, permissionsToRemove);\n }\n */\n }\n } catch (error: any) {\n this.logger.error(error);\n }\n }\n }\n\n async addAllPermissionsToRole(roleName: string): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, null);\n }\n\n async addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, permissionNames);\n }\n\n async addPermissionToRole(roleName: string, permissionName: string[]) {\n return await this._addPermissionsToRole(roleName, permissionName);\n }\n\n private async _addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n const role = await this.repo.findOne({\n where: { name: roleName },\n relations: {\n permissions: true\n }\n });\n if (!role) {\n throw new Error(`Role '${roleName}' not found.`);\n }\n\n // this.logger.log(`Found role ${roleName}`);\n\n // The new set of permissions which are to be added to this role.\n let newPermissions: PermissionMetadata[];\n\n // Load all the specified permissions in the system. \n if (permissionNames && permissionNames.length != 0) {\n // this.logger.log(`Loading specified permissions.`);\n\n newPermissions = await this.permissionRepository.find({ where: { name: In(permissionNames) } });\n if (newPermissions.length !== permissionNames.length) {\n throw new Error(`One or more permissions not found.`);\n }\n }\n else {\n // this.logger.log(`Loading all permissions in system.`);\n\n // Load all permissions in the system. \n // TODO: Do we want to convert this to a paginated query to avoid having to load a very large permissions table into memory?\n newPermissions = await this.permissionRepository.find();\n if (newPermissions.length == 0) {\n throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);\n }\n }\n\n // this.logger.log(`Adding ${newPermissions.length} permissions to role ${roleName}.`);\n\n // if there are already permissions assigned. \n if (role.permissions && role.permissions.length > 0) {\n for (let i = 0; i < newPermissions.length; i++) {\n const newPermission = newPermissions[i];\n let newPermissionFound = true;\n for (let j = 0; j < role.permissions.length; j++) {\n const existingPermission = role.permissions[j];\n if (existingPermission.name === newPermission.name) {\n newPermissionFound = false;\n break;\n }\n }\n\n if (newPermissionFound) {\n role.permissions.push(newPermission);\n }\n }\n\n }\n // else we create a new permissions set. \n else {\n role.permissions = newPermissions;\n }\n\n return await this.repo.save(role);\n }\n\n async removePermissionsFromRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n\n // load the role with the respective permissions.\n const role = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n\n if (!role) {\n throw new Error(ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));\n }\n\n // modify the permissions array.\n role.permissions = role.permissions.filter(permission => !permissionNames.includes(permission.name));\n\n return await this.repo.save(role);\n }\n\n private async preloadPermissionByName(name: string): Promise<PermissionMetadata> {\n const existingPermission = await this.permissionRepository.findOne({\n where: { name },\n });\n if (!existingPermission) {\n throw new NotFoundException(ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));\n }\n return existingPermission;\n }\n\n\n}\n"]}
1
+ {"version":3,"file":"role-metadata.service.js","sourceRoot":"","sources":["../../src/services/role-metadata.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { EntityManager, In } from 'typeorm';\n\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PermissionMetadataRepository } from 'src/repository/permission-metadata.repository';\nimport { RoleMetadataRepository } from 'src/repository/role-metadata.repository';\nimport { CreateRoleMetadataDto } from '../dtos/create-role-metadata.dto';\nimport { PermissionMetadata } from '../entities/permission-metadata.entity';\nimport { RoleMetadata } from '../entities/role-metadata.entity';\n\n@Injectable()\nexport class RoleMetadataService extends CRUDService<RoleMetadata> {\n private readonly logger = new Logger(RoleMetadataService.name);\n private readonly permissionAssignmentBatchSize = 500;\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(RoleMetadata, 'default')\n // readonly repo: Repository<RoleMetadata>,\n readonly repo: RoleMetadataRepository,\n // @InjectRepository(PermissionMetadata)\n // private readonly permissionRepository: Repository<PermissionMetadata>,\n readonly permissionRepository: PermissionMetadataRepository,\n readonly moduleRef: ModuleRef\n\n ) {\n super(entityManager, repo, 'roleMetadata', 'solid-core', moduleRef);\n }\n\n async findRoleByName(roleName: string) {\n const entity = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n if (!entity) {\n throw new NotFoundException(`Entity #${roleName} not found`);\n }\n return entity;\n }\n\n async assertRoleExistsByName(roleName: string): Promise<void> {\n const entity = await this.repo.findOne({\n where: {\n name: roleName\n },\n select: {\n id: true\n }\n });\n if (!entity) {\n throw new NotFoundException(`Entity #${roleName} not found`);\n }\n }\n\n // OK\n async createRolesIfNotExists(roles: CreateRoleMetadataDto[]) {\n for (let id = 0; id < roles.length; id++) {\n try {\n const roleObj = roles[id];\n // this.logger.log(`Resolving role: ${JSON.stringify(roleObj)}`);\n\n const existingRole = await this.repo.findOne({\n where: {\n name: roleObj.name,\n },\n relations: {},\n });\n\n // Create only if not existing already.\n if (!existingRole) {\n this.logger.debug(`Role ${roleObj.name} does not exist, hence creating`);\n\n let permissions = [];\n\n if (roleObj.permissions && roleObj.permissions.length > 0) {\n await Promise.all(\n roleObj.permissions.map(permission => this.preloadPermissionByName(permission.name)),\n );\n }\n\n // const role = this.repo.create({ ...roleObj, permissions });\n const role = this.repo.create({ ...roleObj });\n await this.repo.save(role);\n } else {\n /*\n this.logger.debug(`Role ${roleObj.name} already exists`);\n const existingPermissions = existingRole.permissions.map(permission => permission.name);\n const newPermissions = roleObj.permissions.map(permission => permission.name);\n const permissionsToAdd = newPermissions.filter(permission => !existingPermissions.includes(permission));\n const permissionsToRemove = existingPermissions.filter(permission => !newPermissions.includes(permission));\n this.logger.debug(`Permissions to add: ${JSON.stringify(permissionsToAdd)}`);\n if (permissionsToAdd.length > 0) {\n await this.addPermissionsToRole(roleObj.name, permissionsToAdd);\n }\n this.logger.debug(`Permissions to remove: ${JSON.stringify(permissionsToRemove)}`);\n if (permissionsToRemove.length > 0) {\n await this.removePermissionsFromRole(roleObj.name, permissionsToRemove);\n }\n */\n }\n } catch (error: any) {\n this.logger.error(error);\n }\n }\n }\n\n async addAllPermissionsToRole(roleName: string): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, null);\n }\n\n async addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, permissionNames);\n }\n\n async addPermissionToRole(roleName: string, permissionName: string[]) {\n return await this._addPermissionsToRole(roleName, permissionName);\n }\n\n private async _addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n const role = await this.repo.findOne({\n where: { name: roleName },\n select: {\n id: true,\n name: true,\n }\n });\n if (!role) {\n throw new Error(`Role '${roleName}' not found.`);\n }\n\n const joinInfo = this.getRolePermissionJoinInfo();\n const targetPermissions = await this.loadTargetPermissions(permissionNames);\n\n if (!permissionNames || permissionNames.length === 0) {\n await this.entityManager\n .createQueryBuilder()\n .delete()\n .from(joinInfo.tableName)\n .where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })\n .execute();\n\n await this.insertRolePermissionMappings(role.id, targetPermissions.map((permission) => permission.id), joinInfo);\n }\n else {\n const existingRows = await this.entityManager\n .createQueryBuilder()\n .select(joinInfo.permissionIdColumn, 'permissionId')\n .from(joinInfo.tableName, 'role_permission')\n .where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })\n .getRawMany();\n\n const existingPermissionIds = new Set(existingRows.map((row) => Number(row.permissionId)));\n const missingPermissionIds = targetPermissions\n .map((permission) => permission.id)\n .filter((permissionId) => !existingPermissionIds.has(permissionId));\n\n if (missingPermissionIds.length > 0) {\n await this.insertRolePermissionMappings(role.id, missingPermissionIds, joinInfo);\n }\n }\n\n return await this.findRoleByName(roleName);\n }\n\n async removePermissionsFromRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n\n // load the role with the respective permissions.\n const role = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n\n if (!role) {\n throw new Error(ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));\n }\n\n // modify the permissions array.\n role.permissions = role.permissions.filter(permission => !permissionNames.includes(permission.name));\n\n return await this.repo.save(role);\n }\n\n private async preloadPermissionByName(name: string): Promise<PermissionMetadata> {\n const existingPermission = await this.permissionRepository.findOne({\n where: { name },\n });\n if (!existingPermission) {\n throw new NotFoundException(ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));\n }\n return existingPermission;\n }\n\n private async loadTargetPermissions(permissionNames: string[] | null): Promise<PermissionMetadata[]> {\n if (permissionNames && permissionNames.length !== 0) {\n const uniquePermissionNames = [...new Set(permissionNames)];\n const permissions = await this.permissionRepository.find({ where: { name: In(uniquePermissionNames) } });\n if (permissions.length !== uniquePermissionNames.length) {\n throw new Error(`One or more permissions not found.`);\n }\n return permissions;\n }\n\n const permissions = await this.permissionRepository.find();\n if (permissions.length === 0) {\n throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);\n }\n return permissions;\n }\n\n private getRolePermissionJoinInfo(): { tableName: string; roleIdColumn: string; permissionIdColumn: string } {\n const relation = this.repo.metadata.relations.find((candidate) => candidate.propertyName === 'permissions');\n if (!relation?.junctionEntityMetadata) {\n throw new Error('Role-permission join table metadata not found.');\n }\n\n const roleIdColumn = relation.joinColumns[0]?.databaseName;\n const permissionIdColumn = relation.inverseJoinColumns[0]?.databaseName;\n if (!roleIdColumn || !permissionIdColumn) {\n throw new Error('Role-permission join table column metadata not found.');\n }\n\n return {\n tableName: relation.junctionEntityMetadata.tableName,\n roleIdColumn,\n permissionIdColumn,\n };\n }\n\n private async insertRolePermissionMappings(\n roleId: number,\n permissionIds: number[],\n joinInfo: { tableName: string; roleIdColumn: string; permissionIdColumn: string },\n ): Promise<void> {\n for (let index = 0; index < permissionIds.length; index += this.permissionAssignmentBatchSize) {\n const batch = permissionIds.slice(index, index + this.permissionAssignmentBatchSize);\n await this.entityManager\n .createQueryBuilder()\n .insert()\n .into(joinInfo.tableName)\n .values(\n batch.map((permissionId) => ({\n [joinInfo.roleIdColumn]: roleId,\n [joinInfo.permissionIdColumn]: permissionId,\n })),\n )\n .execute();\n }\n }\n\n\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mq-dashboard-message-broker-variable-options-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAEzG,qBAEa,+CAAgD,YAAW,kBAAkB,CAAC,yBAAyB,CAAC;IAE7G,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAG7D,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAKpE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAyB7G"}
1
+ {"version":3,"file":"mq-dashboard-message-broker-variable-options-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAGzG,qBAEa,+CAAgD,YAAW,kBAAkB,CAAC,yBAAyB,CAAC;IAE7G,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAG7D,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAKpE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAuB7G"}
@@ -13,6 +13,7 @@ exports.MqDashboardMessageBrokerVariableOptionsProvider = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const selection_provider_decorator_1 = require("../../decorators/selection-provider.decorator");
15
15
  const mq_message_repository_1 = require("../../repository/mq-message.repository");
16
+ const mq_dashboard_provider_utils_1 = require("../dashboard-providers/mq-dashboard-provider-utils");
16
17
  let MqDashboardMessageBrokerVariableOptionsProvider = class MqDashboardMessageBrokerVariableOptionsProvider {
17
18
  constructor(mqMessageRepository) {
18
19
  this.mqMessageRepository = mqMessageRepository;
@@ -34,9 +35,7 @@ let MqDashboardMessageBrokerVariableOptionsProvider = class MqDashboardMessageBr
34
35
  const offset = Math.max(ctxt?.offset ?? 0, 0);
35
36
  qb.select("DISTINCT mqMessage.messageBroker", "value")
36
37
  .where("mqMessage.messageBroker IS NOT NULL");
37
- if (query) {
38
- qb.andWhere("mqMessage.messageBroker ILIKE :query", { query: `%${query}%` });
39
- }
38
+ (0, mq_dashboard_provider_utils_1.applyCaseInsensitiveContainsFilter)(qb, "mqMessage.messageBroker", query, "query");
40
39
  const rows = await qb
41
40
  .orderBy("value", "ASC")
42
41
  .take(limit)
@@ -1 +1 @@
1
- {"version":3,"file":"mq-dashboard-message-broker-variable-options-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,kFAA2E;AAKpE,IAAM,+CAA+C,GAArD,MAAM,+CAA+C;IACxD,YACqB,mBAAwC;QAAxC,wBAAmB,GAAnB,mBAAmB,CAAqB;IACzD,CAAC;IAEL,IAAI;QACA,OAAO,iDAAiD,CAAC;IAC7D,CAAC;IAED,IAAI;QACA,OAAO,gEAAgE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB;QAC3B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA+B;QACvD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,mCAAmC,CAAC,WAAW,CAAC,CAAC;QAC3F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9C,EAAE,CAAC,MAAM,CAAC,kCAAkC,EAAE,OAAO,CAAC;aACjD,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAElD,IAAI,KAAK,EAAE,CAAC;YACR,EAAE,CAAC,QAAQ,CAAC,sCAAsC,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,EAAE;aAChB,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;aACvB,IAAI,CAAC,KAAK,CAAC;aACX,IAAI,CAAC,MAAM,CAAC;aACZ,UAAU,EAAqB,CAAC;QAErC,OAAO,IAAI;aACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACT,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,KAAK;SACjB,CAAC,CAAC,CAAC;IACZ,CAAC;CACJ,CAAA;AA3CY,0GAA+C;0DAA/C,+CAA+C;IAF3D,IAAA,gDAAiB,GAAE;IACnB,IAAA,mBAAU,GAAE;qCAGiC,2CAAmB;GAFpD,+CAA+C,CA2C3D","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SelectionProvider } from \"src/decorators/selection-provider.decorator\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from \"src/interfaces\";\n\n@SelectionProvider()\n@Injectable()\nexport class MqDashboardMessageBrokerVariableOptionsProvider implements ISelectionProvider<ISelectionProviderContext> {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardMessageBrokerVariableOptionsProvider\";\n }\n\n help(): string {\n return \"Dynamic options provider for dashboard messageBroker variable.\";\n }\n\n async value(optionValue: string): Promise<ISelectionProviderValues | null> {\n if (!optionValue) return null;\n return { label: optionValue, value: optionValue };\n }\n\n async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);\n const offset = Math.max(ctxt?.offset ?? 0, 0);\n\n qb.select(\"DISTINCT mqMessage.messageBroker\", \"value\")\n .where(\"mqMessage.messageBroker IS NOT NULL\");\n\n if (query) {\n qb.andWhere(\"mqMessage.messageBroker ILIKE :query\", { query: `%${query}%` });\n }\n\n const rows = await qb\n .orderBy(\"value\", \"ASC\")\n .take(limit)\n .skip(offset)\n .getRawMany<{ value: string }>();\n\n return rows\n .filter((r) => !!r?.value)\n .map((r) => ({\n label: r.value,\n value: r.value,\n }));\n }\n}\n\n"]}
1
+ {"version":3,"file":"mq-dashboard-message-broker-variable-options-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,kFAA2E;AAE3E,oGAAkH;AAI3G,IAAM,+CAA+C,GAArD,MAAM,+CAA+C;IACxD,YACqB,mBAAwC;QAAxC,wBAAmB,GAAnB,mBAAmB,CAAqB;IACzD,CAAC;IAEL,IAAI;QACA,OAAO,iDAAiD,CAAC;IAC7D,CAAC;IAED,IAAI;QACA,OAAO,gEAAgE,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB;QAC3B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA+B;QACvD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,mCAAmC,CAAC,WAAW,CAAC,CAAC;QAC3F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9C,EAAE,CAAC,MAAM,CAAC,kCAAkC,EAAE,OAAO,CAAC;aACjD,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAElD,IAAA,gEAAkC,EAAC,EAAE,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAElF,MAAM,IAAI,GAAG,MAAM,EAAE;aAChB,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC;aACvB,IAAI,CAAC,KAAK,CAAC;aACX,IAAI,CAAC,MAAM,CAAC;aACZ,UAAU,EAAqB,CAAC;QAErC,OAAO,IAAI;aACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACT,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,KAAK;SACjB,CAAC,CAAC,CAAC;IACZ,CAAC;CACJ,CAAA;AAzCY,0GAA+C;0DAA/C,+CAA+C;IAF3D,IAAA,gDAAiB,GAAE;IACnB,IAAA,mBAAU,GAAE;qCAGiC,2CAAmB;GAFpD,+CAA+C,CAyC3D","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SelectionProvider } from \"src/decorators/selection-provider.decorator\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from \"src/interfaces\";\nimport { applyCaseInsensitiveContainsFilter } from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\n@SelectionProvider()\n@Injectable()\nexport class MqDashboardMessageBrokerVariableOptionsProvider implements ISelectionProvider<ISelectionProviderContext> {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardMessageBrokerVariableOptionsProvider\";\n }\n\n help(): string {\n return \"Dynamic options provider for dashboard messageBroker variable.\";\n }\n\n async value(optionValue: string): Promise<ISelectionProviderValues | null> {\n if (!optionValue) return null;\n return { label: optionValue, value: optionValue };\n }\n\n async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);\n const offset = Math.max(ctxt?.offset ?? 0, 0);\n\n qb.select(\"DISTINCT mqMessage.messageBroker\", \"value\")\n .where(\"mqMessage.messageBroker IS NOT NULL\");\n\n applyCaseInsensitiveContainsFilter(qb, \"mqMessage.messageBroker\", query, \"query\");\n\n const rows = await qb\n .orderBy(\"value\", \"ASC\")\n .take(limit)\n .skip(offset)\n .getRawMany<{ value: string }>();\n\n return rows\n .filter((r) => !!r?.value)\n .map((r) => ({\n label: r.value,\n value: r.value,\n }));\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mq-dashboard-queue-name-variable-options-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAEzG,qBAEa,2CAA4C,YAAW,kBAAkB,CAAC,yBAAyB,CAAC;IAEzG,OAAO,CAAC,QAAQ,CAAC,wBAAwB;gBAAxB,wBAAwB,EAAE,wBAAwB;IAGvE,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IASpE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAoB7G"}
1
+ {"version":3,"file":"mq-dashboard-queue-name-variable-options-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAGzG,qBAEa,2CAA4C,YAAW,kBAAkB,CAAC,yBAAyB,CAAC;IAEzG,OAAO,CAAC,QAAQ,CAAC,wBAAwB;gBAAxB,wBAAwB,EAAE,wBAAwB;IAGvE,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IASpE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;CAkB7G"}
@@ -13,6 +13,7 @@ exports.MqDashboardQueueNameVariableOptionsProvider = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const selection_provider_decorator_1 = require("../../decorators/selection-provider.decorator");
15
15
  const mq_message_queue_repository_1 = require("../../repository/mq-message-queue.repository");
16
+ const mq_dashboard_provider_utils_1 = require("../dashboard-providers/mq-dashboard-provider-utils");
16
17
  let MqDashboardQueueNameVariableOptionsProvider = class MqDashboardQueueNameVariableOptionsProvider {
17
18
  constructor(mqMessageQueueRepository) {
18
19
  this.mqMessageQueueRepository = mqMessageQueueRepository;
@@ -37,9 +38,7 @@ let MqDashboardQueueNameVariableOptionsProvider = class MqDashboardQueueNameVari
37
38
  const qb = await this.mqMessageQueueRepository.createSecurityRuleAwareQueryBuilder("mqMessageQueue");
38
39
  const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);
39
40
  const offset = Math.max(ctxt?.offset ?? 0, 0);
40
- if (query) {
41
- qb.andWhere("mqMessageQueue.name ILIKE :query", { query: `%${query}%` });
42
- }
41
+ (0, mq_dashboard_provider_utils_1.applyCaseInsensitiveContainsFilter)(qb, "mqMessageQueue.name", query, "query");
43
42
  const records = await qb
44
43
  .select(["mqMessageQueue.name"])
45
44
  .orderBy("mqMessageQueue.name", "ASC")
@@ -1 +1 @@
1
- {"version":3,"file":"mq-dashboard-queue-name-variable-options-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,8FAAsF;AAK/E,IAAM,2CAA2C,GAAjD,MAAM,2CAA2C;IACpD,YACqB,wBAAkD;QAAlD,6BAAwB,GAAxB,wBAAwB,CAA0B;IACnE,CAAC;IAEL,IAAI;QACA,OAAO,6CAA6C,CAAC;IACzD,CAAC;IAED,IAAI;QACA,OAAO,4DAA4D,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB;QAC3B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;YACtD,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;SAC/B,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA+B;QACvD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,mCAAmC,CAAC,gBAAgB,CAAC,CAAC;QACrG,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9C,IAAI,KAAK,EAAE,CAAC;YACR,EAAE,CAAC,QAAQ,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE;aACnB,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;aAC/B,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC;aACrC,IAAI,CAAC,KAAK,CAAC;aACX,IAAI,CAAC,MAAM,CAAC;aACZ,OAAO,EAAE,CAAC;QAEf,OAAO,OAAO;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;CACJ,CAAA;AA1CY,kGAA2C;sDAA3C,2CAA2C;IAFvD,IAAA,gDAAiB,GAAE;IACnB,IAAA,mBAAU,GAAE;qCAGsC,sDAAwB;GAF9D,2CAA2C,CA0CvD","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SelectionProvider } from \"src/decorators/selection-provider.decorator\";\nimport { MqMessageQueueRepository } from \"src/repository/mq-message-queue.repository\";\nimport { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from \"src/interfaces\";\n\n@SelectionProvider()\n@Injectable()\nexport class MqDashboardQueueNameVariableOptionsProvider implements ISelectionProvider<ISelectionProviderContext> {\n constructor(\n private readonly mqMessageQueueRepository: MqMessageQueueRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardQueueNameVariableOptionsProvider\";\n }\n\n help(): string {\n return \"Dynamic options provider for dashboard queueName variable.\";\n }\n\n async value(optionValue: string): Promise<ISelectionProviderValues | null> {\n if (!optionValue) return null;\n const queue = await this.mqMessageQueueRepository.findOne({\n where: { name: optionValue },\n });\n if (!queue?.name) return null;\n return { label: queue.name, value: queue.name };\n }\n\n async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {\n const qb = await this.mqMessageQueueRepository.createSecurityRuleAwareQueryBuilder(\"mqMessageQueue\");\n const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);\n const offset = Math.max(ctxt?.offset ?? 0, 0);\n\n if (query) {\n qb.andWhere(\"mqMessageQueue.name ILIKE :query\", { query: `%${query}%` });\n }\n\n const records = await qb\n .select([\"mqMessageQueue.name\"])\n .orderBy(\"mqMessageQueue.name\", \"ASC\")\n .take(limit)\n .skip(offset)\n .getMany();\n\n return records\n .filter((r) => !!r?.name)\n .map((r) => ({ label: r.name, value: r.name }));\n }\n}\n\n"]}
1
+ {"version":3,"file":"mq-dashboard-queue-name-variable-options-provider.service.js","sourceRoot":"","sources":["../../../src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,gGAAgF;AAChF,8FAAsF;AAEtF,oGAAkH;AAI3G,IAAM,2CAA2C,GAAjD,MAAM,2CAA2C;IACpD,YACqB,wBAAkD;QAAlD,6BAAwB,GAAxB,wBAAwB,CAA0B;IACnE,CAAC;IAEL,IAAI;QACA,OAAO,6CAA6C,CAAC;IACzD,CAAC;IAED,IAAI;QACA,OAAO,4DAA4D,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB;QAC3B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;YACtD,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;SAC/B,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA+B;QACvD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,mCAAmC,CAAC,gBAAgB,CAAC,CAAC;QACrG,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9C,IAAA,gEAAkC,EAAC,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAE9E,MAAM,OAAO,GAAG,MAAM,EAAE;aACnB,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;aAC/B,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC;aACrC,IAAI,CAAC,KAAK,CAAC;aACX,IAAI,CAAC,MAAM,CAAC;aACZ,OAAO,EAAE,CAAC;QAEf,OAAO,OAAO;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;CACJ,CAAA;AAxCY,kGAA2C;sDAA3C,2CAA2C;IAFvD,IAAA,gDAAiB,GAAE;IACnB,IAAA,mBAAU,GAAE;qCAGsC,sDAAwB;GAF9D,2CAA2C,CAwCvD","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { SelectionProvider } from \"src/decorators/selection-provider.decorator\";\nimport { MqMessageQueueRepository } from \"src/repository/mq-message-queue.repository\";\nimport { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from \"src/interfaces\";\nimport { applyCaseInsensitiveContainsFilter } from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\n@SelectionProvider()\n@Injectable()\nexport class MqDashboardQueueNameVariableOptionsProvider implements ISelectionProvider<ISelectionProviderContext> {\n constructor(\n private readonly mqMessageQueueRepository: MqMessageQueueRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardQueueNameVariableOptionsProvider\";\n }\n\n help(): string {\n return \"Dynamic options provider for dashboard queueName variable.\";\n }\n\n async value(optionValue: string): Promise<ISelectionProviderValues | null> {\n if (!optionValue) return null;\n const queue = await this.mqMessageQueueRepository.findOne({\n where: { name: optionValue },\n });\n if (!queue?.name) return null;\n return { label: queue.name, value: queue.name };\n }\n\n async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {\n const qb = await this.mqMessageQueueRepository.createSecurityRuleAwareQueryBuilder(\"mqMessageQueue\");\n const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);\n const offset = Math.max(ctxt?.offset ?? 0, 0);\n\n applyCaseInsensitiveContainsFilter(qb, \"mqMessageQueue.name\", query, \"query\");\n\n const records = await qb\n .select([\"mqMessageQueue.name\"])\n .orderBy(\"mqMessageQueue.name\", \"ASC\")\n .take(limit)\n .skip(offset)\n .getMany();\n\n return records\n .filter((r) => !!r?.name)\n .map((r) => ({ label: r.name, value: r.name }));\n }\n}\n"]}
@@ -24,6 +24,7 @@ export declare class SettingService {
24
24
  private readonly arrayKeysToSkip;
25
25
  constructor(fileService: IFileService, pathBuilder: IStoragePathBuilder, solidRegistry: SolidRegistry, repo: SettingRepository, moduleMetadataRepo: ModuleMetadataRepository, requestContextService: RequestContextService, userRepository: Repository<User>);
26
26
  private getSettingsFromDb;
27
+ private getSettingsFromDbForSeeding;
27
28
  private parseSettingValue;
28
29
  private buildSettingLabel;
29
30
  private inferControlType;
@@ -1 +1 @@
1
- {"version":3,"file":"setting.service.d.ts","sourceRoot":"","sources":["../../src/services/setting.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAgB,YAAY,EAA6B,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAA0B,qBAAqB,EAAqB,OAAO,EAAsB,iBAAiB,EAAgB,MAAM,eAAe,CAAC;AAC/J,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAMrF,qBACa,cAAc;IAcD,QAAQ,CAAC,WAAW,EAAE,YAAY;IACrB,QAAQ,CAAC,WAAW,EAAE,mBAAmB;IAC5E,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,IAAI,EAAE,iBAAiB;IAChC,QAAQ,CAAC,kBAAkB,EAAE,wBAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACd,OAAO,CAAC,QAAQ,CAAC,cAAc;IAnBzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAE7D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAI7B;gBAG8B,WAAW,EAAE,YAAY,EACZ,WAAW,EAAE,mBAAmB,EACnE,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,iBAAiB,EACvB,kBAAkB,EAAE,wBAAwB,EACpC,qBAAqB,EAAE,qBAAqB,EACpB,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC;YAO7D,iBAAiB;IAK/B,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,2BAA2B;IA+BnC,cAAc,IAAI,iBAAiB,EAAE;IAI/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B1C,OAAO,CAAC,sBAAsB;IAcxB,uCAAuC,IAAI,OAAO,CAAC,IAAI,CAAC;IAkExD,kDAAkD,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAoCpF,cAAc,CAAC,QAAQ,GAAE,gBAAgB,EAAO,EAAE,aAAa,GAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA8H3H,cAAc,CAAC,CAAC,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAoB1C,SAAS,CAAC,YAAY,EAAE,YAAY,EAAE,mBAAmB,GAAE,GAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAuBzF"}
1
+ {"version":3,"file":"setting.service.d.ts","sourceRoot":"","sources":["../../src/services/setting.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAgB,YAAY,EAA6B,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAA0B,qBAAqB,EAAqB,OAAO,EAAsB,iBAAiB,EAAgB,MAAM,eAAe,CAAC;AAC/J,OAAO,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAMrF,qBACa,cAAc;IAcD,QAAQ,CAAC,WAAW,EAAE,YAAY;IACrB,QAAQ,CAAC,WAAW,EAAE,mBAAmB;IAC5E,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,IAAI,EAAE,iBAAiB;IAChC,QAAQ,CAAC,kBAAkB,EAAE,wBAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACd,OAAO,CAAC,QAAQ,CAAC,cAAc;IAnBzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2B;IAE7D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAI7B;gBAG8B,WAAW,EAAE,YAAY,EACZ,WAAW,EAAE,mBAAmB,EACnE,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,iBAAiB,EACvB,kBAAkB,EAAE,wBAAwB,EACpC,qBAAqB,EAAE,qBAAqB,EACpB,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC;YAO7D,iBAAiB;YAKjB,2BAA2B;IAIzC,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,2BAA2B;IA+BnC,cAAc,IAAI,iBAAiB,EAAE;IAI/B,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B1C,OAAO,CAAC,sBAAsB;IAcxB,uCAAuC,IAAI,OAAO,CAAC,IAAI,CAAC;IA6FxD,kDAAkD,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAoCpF,cAAc,CAAC,QAAQ,GAAE,gBAAgB,EAAO,EAAE,aAAa,GAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA8H3H,cAAc,CAAC,CAAC,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAoB1C,SAAS,CAAC,YAAY,EAAE,YAAY,EAAE,mBAAmB,GAAE,GAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAuBzF"}
@@ -88,6 +88,9 @@ let SettingService = SettingService_1 = class SettingService {
88
88
  const settings = await this.repo.find({ relations: ['user'] });
89
89
  return settings;
90
90
  }
91
+ async getSettingsFromDbForSeeding() {
92
+ return this.repo.find({ relations: ['moduleMetadata'] });
93
+ }
91
94
  parseSettingValue(value, key) {
92
95
  try {
93
96
  return JSON.parse(value);
@@ -192,11 +195,20 @@ let SettingService = SettingService_1 = class SettingService {
192
195
  }
193
196
  async seedSystemAdminEditableAndAboveSettings() {
194
197
  const saEditableAndAbove = this.getAllSettingsFromProviders().filter(i => [interfaces_1.SettingLevel.SystemAdminEditable, interfaces_1.SettingLevel.InternalUser].includes(i.level));
195
- const existingSettingsFromDb = await this.getSettingsFromDb();
198
+ const existingSettingsFromDb = await this.getSettingsFromDbForSeeding();
196
199
  const existingSettingsFromDbByKey = new Map(existingSettingsFromDb.map(setting => [setting.key, setting]));
197
- const settingsToMutate = [];
198
- for (const { key, value, level, moduleName, encrypted } of saEditableAndAbove) {
200
+ const settingsToCreate = [];
201
+ const settingsToUpdate = [];
202
+ const moduleNames = Array.from(new Set(saEditableAndAbove
203
+ .map(setting => setting.moduleName)
204
+ .filter((moduleName) => !!moduleName)));
205
+ const moduleMetadataByName = new Map();
206
+ await Promise.all(moduleNames.map(async (moduleName) => {
199
207
  const moduleMetadata = await this.moduleMetadataRepo.findOneBy({ name: moduleName });
208
+ moduleMetadataByName.set(moduleName, moduleMetadata);
209
+ }));
210
+ for (const { key, value, level, moduleName, encrypted } of saEditableAndAbove) {
211
+ const moduleMetadata = moduleName ? moduleMetadataByName.get(moduleName) : null;
200
212
  if (!existingSettingsFromDbByKey.has(key)) {
201
213
  const setting = new setting_entity_1.Setting();
202
214
  setting.key = key;
@@ -221,19 +233,31 @@ let SettingService = SettingService_1 = class SettingService {
221
233
  rawValue = this.encryptionService.encrypt(rawValue);
222
234
  }
223
235
  setting.value = rawValue;
224
- settingsToMutate.push(setting);
236
+ settingsToCreate.push(setting);
225
237
  }
226
238
  else {
227
239
  const setting = existingSettingsFromDbByKey.get(key);
240
+ const existingModuleMetadataId = setting.moduleMetadata?.id ?? null;
241
+ const nextModuleMetadataId = moduleMetadata?.id ?? null;
242
+ const levelChanged = setting.level !== level;
243
+ const encryptedChanged = setting.encrypted !== !!encrypted;
244
+ const moduleChanged = !!moduleMetadata && existingModuleMetadataId !== nextModuleMetadataId;
245
+ if (!levelChanged && !encryptedChanged && !moduleChanged) {
246
+ continue;
247
+ }
228
248
  setting.level = level;
229
249
  setting.encrypted = !!encrypted;
230
- if (moduleMetadata)
250
+ if (moduleMetadata) {
231
251
  setting.moduleMetadata = moduleMetadata;
232
- settingsToMutate.push(setting);
252
+ }
253
+ settingsToUpdate.push(setting);
233
254
  }
234
255
  }
235
- if (settingsToMutate.length > 0) {
236
- await this.repo.save(settingsToMutate);
256
+ if (settingsToCreate.length > 0) {
257
+ await this.repo.save(settingsToCreate);
258
+ }
259
+ if (settingsToUpdate.length > 0) {
260
+ await this.repo.save(settingsToUpdate);
237
261
  }
238
262
  }
239
263
  async getNonEncryptedSystemAdminReadonlyAndAboveSettings() {
@@ -1 +1 @@
1
- {"version":3,"file":"setting.service.js","sourceRoot":"","sources":["../../src/services/setting.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, ForbiddenException, Inject, Injectable } from '@nestjs/common';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { Repository } from 'typeorm';\nimport * as fsPromises from 'fs/promises';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { CreateSettingDto } from 'src/dtos/create-setting.dto';\nimport { GetMcpUrlDto } from 'src/dtos/get-mcp-url.dto';\nimport { User } from 'src/entities/user.entity';\nimport { SettingRepository } from '../repository/setting.repository';\nimport { FILE_SERVICE, IFileService, FILE_STORAGE_PATH_BUILDER, IStoragePathBuilder } from './file';\nimport { Setting } from '../entities/setting.entity';\nimport { RequestContextService } from './request-context.service';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { AdminSettingDefinition, AdminSettingsResponse, ISettingsProvider, NoInfer, SettingControlType, SettingDefinition, SettingLevel } from '../interfaces';\nimport { ModuleMetadataRepository } from 'src/repository/module-metadata.repository';\nimport type { SolidCoreSetting } from './settings/default-settings-provider.service';\nimport { Logger } from '@nestjs/common';\nimport { EncryptionService } from './encryption.service';\n\n\n@Injectable()\nexport class SettingService {\n private readonly _logger = new Logger(SettingService.name);\n\n private settings: SettingDefinition[] = [];\n private settingsByKey = new Map<string, SettingDefinition>();\n private readonly encryptionService: EncryptionService | null;\n\n private readonly arrayKeysToSkip = new Set([\n 'authenticationPasswordRegex',\n 'authenticationPasswordRegexErrorMessage',\n 'authenticationPasswordComplexityDescription',\n ]);\n\n constructor(\n @Inject(FILE_SERVICE) readonly fileService: IFileService,\n @Inject(FILE_STORAGE_PATH_BUILDER) readonly pathBuilder: IStoragePathBuilder,\n readonly solidRegistry: SolidRegistry,\n readonly repo: SettingRepository,\n readonly moduleMetadataRepo: ModuleMetadataRepository,\n private readonly requestContextService: RequestContextService,\n @InjectRepository(User) private readonly userRepository: Repository<User>,\n ) {\n const encKey = process.env.APP_ENCRYPTION_KEY;\n this.encryptionService = encKey ? new EncryptionService(encKey) : null;\n if (!encKey) this._logger.warn('APP_ENCRYPTION_KEY is not set — encrypted settings will not be decrypted');\n }\n\n private async getSettingsFromDb(): Promise<Setting[]> {\n const settings = await this.repo.find({ relations: ['user'] });\n return settings;\n }\n\n private parseSettingValue(value: string, key: string): any {\n try {\n return JSON.parse(value);\n } catch {\n if (value === 'true' || value === 'false') {\n return value === 'true';\n }\n if (!isNaN(Number(value)) && value.trim() !== '') {\n return Number(value);\n }\n if (!this.arrayKeysToSkip.has(key) && value.includes(',')) {\n return value.split(',').map(item => item.trim());\n }\n return value;\n }\n }\n\n private buildSettingLabel(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (match) => match.toUpperCase());\n }\n\n private inferControlType(setting: SettingDefinition): SettingControlType {\n if (setting.controlType) {\n return setting.controlType;\n }\n\n if (setting.options?.length) {\n return 'selectionStatic';\n }\n\n if (typeof setting.value === 'boolean') {\n return 'boolean';\n }\n\n if (typeof setting.value === 'number') {\n return 'numeric';\n }\n\n return 'shortText';\n }\n\n private toAdminSettingDefinition(setting: SettingDefinition): AdminSettingDefinition {\n return {\n ...setting,\n label: setting.label ?? this.buildSettingLabel(setting.key),\n controlType: this.inferControlType(setting),\n editable: setting.level === SettingLevel.SystemAdminEditable,\n };\n }\n\n /**\n * Reads all registered providers and gathers settings from across the running platform.\n * This is the superset of all possible settings. \n * @returns \n */\n private getAllSettingsFromProviders(): SettingDefinition[] {\n // get all settings from registry \n const allSettingsProviders = this.solidRegistry.getSettingsProviders();\n const settings: SettingDefinition[] = [];\n const seenKeys = new Map<string, { setting: SettingDefinition; providerName?: string }>();\n for (const wrapper of allSettingsProviders) {\n const instance = wrapper.instance as ISettingsProvider;\n // if (!instance?.getSettings) continue;\n for (const setting of instance.getSettings()) {\n const existing = seenKeys.get(setting.key);\n if (existing) {\n throw new Error(\n `Duplicate setting key detected: ${setting.key}. ` +\n `First: ${JSON.stringify(existing.setting)} from provider: ${existing.providerName ?? \"unknown\"}. ` +\n `Second: ${JSON.stringify(setting)} from provider: ${wrapper.name ?? \"unknown\"}.`\n );\n }\n seenKeys.set(setting.key, { setting, providerName: wrapper.name });\n settings.push(setting);\n }\n }\n\n return settings\n }\n\n /**\n * public method that gets all settings in the system, this includes settings from solid-core and any consuming projects.\n * this means that the settings returned are the ones provided by ISettingsProvider, merged with values if any from the database. \n * \n * @returns \n */\n getAllSettings(): SettingDefinition[] {\n return this.settings;\n }\n\n async updateSettingsCache(): Promise<void> {\n this._logger.debug(`updating settings cache...`);\n const settingsFromDb = await this.getSettingsFromDb();\n const settingsFromProviders = this.getAllSettingsFromProviders();\n const settingsFromDbByKey = new Map(settingsFromDb.map(setting => [setting.key, setting]));\n\n this.settings = settingsFromProviders.map(setting => {\n const settingFromDb = settingsFromDbByKey.get(setting.key);\n const valueFromDb = settingFromDb?.value;\n if (settingFromDb?.key && valueFromDb !== undefined && valueFromDb !== null) {\n let rawValue = valueFromDb;\n if (settingFromDb.encrypted && this.encryptionService) {\n try {\n rawValue = this.encryptionService.decrypt(rawValue);\n } catch {\n this._logger.warn(`Failed to decrypt setting \"${setting.key}\" — using raw value`);\n }\n }\n const parsedValue = typeof rawValue === 'string' ? this.parseSettingValue(rawValue, settingFromDb.key) : rawValue;\n return { ...setting, value: parsedValue };\n }\n return setting;\n });\n\n // Also keep a key vs SettingDefinition map...\n this.settingsByKey = new Map(this.settings.map(setting => [setting.key, setting]));\n }\n\n private isDisallowedSettingKey(key: string, settingLevelsToDisallow: SettingLevel[]): boolean {\n if (!key) {\n return false;\n }\n const setting = this.settingsByKey.get(key);\n // return setting ? [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly].includes(setting.level) : false;\n return setting ? settingLevelsToDisallow.includes(setting.level) : false;\n }\n\n /**\n * 1. \n * This method will seed (insert only) settings that are introduced in code but do not already exist in the database. \n * Also this method only deals with settings with level system-admin-editable & internal-user.\n */\n async seedSystemAdminEditableAndAboveSettings(): Promise<void> {\n // Seed only settings with level system-admin-editable & internal-user, \n // so basically settings which are either system-admin-editable and above.\n const saEditableAndAbove = this.getAllSettingsFromProviders().filter(i => [SettingLevel.SystemAdminEditable, SettingLevel.InternalUser].includes(i.level));\n\n // Get hold of the current values from the database.\n const existingSettingsFromDb: Setting[] = await this.getSettingsFromDb();\n\n // const existingKeysFromDb = new Set(existingSettingsFromDb.map(s => s.key));\n const existingSettingsFromDbByKey = new Map(existingSettingsFromDb.map(setting => [setting.key, setting]));\n const settingsToMutate: Setting[] = [];\n // const settingsToUpdate: Setting[] = [];\n\n for (const { key, value, level, moduleName, encrypted } of saEditableAndAbove) {\n const moduleMetadata = await this.moduleMetadataRepo.findOneBy({ name: moduleName });\n if (!existingSettingsFromDbByKey.has(key)) {\n const setting = new Setting();\n setting.key = key;\n setting.level = level;\n setting.encrypted = !!encrypted;\n if (moduleMetadata)\n setting.moduleMetadata = moduleMetadata;\n\n let rawValue: string | null;\n if (typeof value === 'boolean') {\n rawValue = value.toString();\n } else if (Array.isArray(value)) {\n rawValue = value.join(',');\n } else if (value === null || value === undefined) {\n rawValue = null;\n } else {\n rawValue = String(value);\n }\n\n if (encrypted && this.encryptionService && rawValue !== null) {\n rawValue = this.encryptionService.encrypt(rawValue);\n }\n setting.value = rawValue;\n\n settingsToMutate.push(setting);\n }\n else {\n const setting = existingSettingsFromDbByKey.get(key);\n setting.level = level;\n setting.encrypted = !!encrypted;\n if (moduleMetadata)\n setting.moduleMetadata = moduleMetadata;\n settingsToMutate.push(setting);\n }\n }\n\n if (settingsToMutate.length > 0) {\n await this.repo.save(settingsToMutate);\n }\n // if (settingsToUpdate.length > 0) {\n // await this.repo.save(settingsToUpdate);\n // }\n }\n\n /**\n * 2. \n * Method used from the solid-core-ui to fetch available settings. \n * Here we are returning settings other than system-env.\n * \n * @returns \n */\n async getNonEncryptedSystemAdminReadonlyAndAboveSettings(): Promise<AdminSettingsResponse> {\n const activeUser = this.requestContextService.getActiveUser();\n const hasViewEncryptedPermission = !!activeUser?.permissions?.includes('settings:view_encrypted');\n\n const data = this.settings\n .filter(i => i.level !== \"system-env\")\n .filter(i => hasViewEncryptedPermission || !i.encrypted)\n .filter((setting) => [SettingLevel.SystemAdminReadonly, SettingLevel.SystemAdminEditable].includes(setting.level))\n .map((setting) => this.toAdminSettingDefinition(setting))\n .sort((left, right) => {\n const groupCompare = (left.group ?? '').localeCompare(right.group ?? '');\n if (groupCompare !== 0) {\n return groupCompare;\n }\n\n const leftSort = left.sortOrder ?? Number.MAX_SAFE_INTEGER;\n const rightSort = right.sortOrder ?? Number.MAX_SAFE_INTEGER;\n if (leftSort !== rightSort) {\n return leftSort - rightSort;\n }\n\n return left.label!.localeCompare(right.label!);\n });\n\n return { data };\n }\n\n /**\n * 3. \n * This method updates settings from the admin user interface. \n * Most likely settings with level system-admin-editable & internal-user are the ones that will get modified here. \n * \n * @param settings \n * @param uploadedFiles \n * @returns \n */\n async updateSettings(settings: CreateSettingDto[] = [], uploadedFiles: Array<Express.Multer.File> = []): Promise<Setting[]> {\n const activeUser = this.requestContextService.getActiveUser();\n const userId = activeUser?.sub;\n\n const restrictedKeys = new Set<string>();\n\n settings.forEach(setting => {\n if (this.isDisallowedSettingKey(setting.key, [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly])) {\n restrictedKeys.add(setting.key);\n }\n });\n uploadedFiles.forEach(file => {\n if (this.isDisallowedSettingKey(file.fieldname, [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly])) {\n restrictedKeys.add(file.fieldname);\n }\n });\n\n if (restrictedKeys.size > 0) {\n throw new BadRequestException(`${ERROR_MESSAGES.FORBIDDEN}: Settings ${Array.from(restrictedKeys).join(', ')} cannot be modified.`);\n }\n\n // const existingSettings = await this.repo.find();\n const existingSettings: Setting[] = await this.getSettingsFromDb();\n\n const settingsToUpdate: Setting[] = [];\n const settingsToCreate: Setting[] = [];\n\n let user: User | null = null;\n const hasUserSettings = settings.some(dto => dto.type === 'user');\n if (hasUserSettings && userId) {\n user = await this.userRepository.findOne({ where: { id: userId } });\n }\n\n // Handle uploaded files\n if (uploadedFiles?.length) {\n for (const file of uploadedFiles) {\n const settingKey = file.fieldname;\n const relativeFileName = `${file.filename}-${file.originalname}`;\n\n // Read file from local disk (where Multer stores uploads) and write to storage\n // The path builder constructs the provider-appropriate storage path\n const fileContent = await fsPromises.readFile(file.path);\n const storagePath = this.pathBuilder.build(relativeFileName);\n const fileUrl = await this.fileService.write(storagePath, fileContent, { contentType: file.mimetype });\n // Delete the temp file from local disk\n await fsPromises.unlink(file.path);\n\n const matchedDto = settings.find(dto => dto.key === settingKey);\n const settingType = matchedDto?.type ?? 'system';\n\n const existingSetting = existingSettings.find(s => s.key === settingKey);\n if (existingSetting) {\n existingSetting.value = fileUrl;\n existingSetting.type = settingType;\n settingsToUpdate.push(existingSetting);\n } else {\n const newSetting = new Setting();\n newSetting.key = settingKey;\n newSetting.value = fileUrl;\n newSetting.type = settingType;\n\n if (settingType === 'user' && user) {\n newSetting.user = user;\n }\n\n settingsToCreate.push(newSetting);\n }\n }\n }\n\n // Handle non-file settings\n for (const settingDto of settings) {\n if (uploadedFiles?.some(file => file.fieldname === settingDto.key)) {\n continue; // skip if already handled via file\n }\n\n const key = settingDto.key;\n const rawValue = settingDto.value;\n let value = rawValue === null || rawValue === undefined ? null : String(rawValue);\n\n const settingType = settingDto.type ?? 'system';\n const definition = this.settingsByKey.get(key);\n const shouldEncrypt = !!definition?.encrypted && this.encryptionService !== null && value !== null;\n\n if (shouldEncrypt) {\n value = this.encryptionService.encrypt(value);\n }\n\n const existingSetting = existingSettings.find(s => s.key === key);\n if (existingSetting) {\n existingSetting.value = value;\n existingSetting.type = settingType;\n existingSetting.encrypted = shouldEncrypt;\n settingsToUpdate.push(existingSetting);\n } else {\n const newSetting = new Setting();\n newSetting.key = key;\n newSetting.value = value;\n newSetting.type = settingType;\n newSetting.encrypted = shouldEncrypt;\n\n if (settingType === 'user' && user) {\n newSetting.user = user;\n }\n\n settingsToCreate.push(newSetting);\n }\n }\n\n if (settingsToUpdate.length > 0) {\n await this.repo.save(settingsToUpdate);\n }\n\n if (settingsToCreate.length > 0) {\n await this.repo.save(settingsToCreate);\n }\n await this.updateSettingsCache();\n\n return [...settingsToUpdate, ...settingsToCreate];\n }\n\n /**\n * 4. \n * @param settingKey \n * @returns \n */\n getConfigValue<T = never>(settingKey: NoInfer<T>) {\n const cachedSetting = this.settingsByKey.get(settingKey as string);\n if (cachedSetting) {\n return cachedSetting.value;\n }\n\n return null;\n\n // const cachedSetting = this.settings.find(setting => setting.key === settingKey);\n // if (cachedSetting) {\n // return cachedSetting.value;\n // }\n\n // // This is probably not needed at all, but leaving it here as a backup for scenarios like \n // // if getConfigValue<SolidCoreSetting>() is called before onApplicationBootstrap() runs or if the cache refresh fails. \n // const getAllSettings = this.getAllSettingsFromProviders();\n // const settingValue = getAllSettings.find(i => (i.key == settingKey))\n // return settingValue?.value;\n }\n\n async getMcpUrl(getMcpUrlDto: GetMcpUrlDto, solidRequestContext: any = {}): Promise<any> {\n\n const { showHeader, inListView } = getMcpUrlDto;\n\n const mcpEnabled = this.getConfigValue<SolidCoreSetting>('mcpEnabled');\n if (mcpEnabled === 'false' || mcpEnabled === false) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n if (solidRequestContext.activeUser) {\n const permissionNames = [\"SettingController.getMcpUrl\"];\n const matchingPermssions = solidRequestContext.activeUser.permissions.filter((p: any) => permissionNames.includes(p));\n const hasPermission = matchingPermssions.length > 0;\n if (!hasPermission) {\n throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);\n }\n }\n const apiKey = this.getConfigValue<SolidCoreSetting>('mcpApiKey');\n const userId = solidRequestContext.activeUser.sub;\n const mcpServerUrl = this.getConfigValue<SolidCoreSetting>('mcpServerUrl');\n return { mcpUrl: `${mcpServerUrl}/static/frontend.html?solidx-mcp-api-key=${apiKey}&solidx-user-id=${userId}&solidx-show-header=${showHeader}&solidx-in-list-view=${inListView}` };\n }\n\n}\n"]}
1
+ {"version":3,"file":"setting.service.js","sourceRoot":"","sources":["../../src/services/setting.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, ForbiddenException, Inject, Injectable } from '@nestjs/common';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { Repository } from 'typeorm';\nimport * as fsPromises from 'fs/promises';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { CreateSettingDto } from 'src/dtos/create-setting.dto';\nimport { GetMcpUrlDto } from 'src/dtos/get-mcp-url.dto';\nimport { User } from 'src/entities/user.entity';\nimport { SettingRepository } from '../repository/setting.repository';\nimport { FILE_SERVICE, IFileService, FILE_STORAGE_PATH_BUILDER, IStoragePathBuilder } from './file';\nimport { Setting } from '../entities/setting.entity';\nimport { RequestContextService } from './request-context.service';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { AdminSettingDefinition, AdminSettingsResponse, ISettingsProvider, NoInfer, SettingControlType, SettingDefinition, SettingLevel } from '../interfaces';\nimport { ModuleMetadataRepository } from 'src/repository/module-metadata.repository';\nimport type { SolidCoreSetting } from './settings/default-settings-provider.service';\nimport { Logger } from '@nestjs/common';\nimport { EncryptionService } from './encryption.service';\n\n\n@Injectable()\nexport class SettingService {\n private readonly _logger = new Logger(SettingService.name);\n\n private settings: SettingDefinition[] = [];\n private settingsByKey = new Map<string, SettingDefinition>();\n private readonly encryptionService: EncryptionService | null;\n\n private readonly arrayKeysToSkip = new Set([\n 'authenticationPasswordRegex',\n 'authenticationPasswordRegexErrorMessage',\n 'authenticationPasswordComplexityDescription',\n ]);\n\n constructor(\n @Inject(FILE_SERVICE) readonly fileService: IFileService,\n @Inject(FILE_STORAGE_PATH_BUILDER) readonly pathBuilder: IStoragePathBuilder,\n readonly solidRegistry: SolidRegistry,\n readonly repo: SettingRepository,\n readonly moduleMetadataRepo: ModuleMetadataRepository,\n private readonly requestContextService: RequestContextService,\n @InjectRepository(User) private readonly userRepository: Repository<User>,\n ) {\n const encKey = process.env.APP_ENCRYPTION_KEY;\n this.encryptionService = encKey ? new EncryptionService(encKey) : null;\n if (!encKey) this._logger.warn('APP_ENCRYPTION_KEY is not set — encrypted settings will not be decrypted');\n }\n\n private async getSettingsFromDb(): Promise<Setting[]> {\n const settings = await this.repo.find({ relations: ['user'] });\n return settings;\n }\n\n private async getSettingsFromDbForSeeding(): Promise<Setting[]> {\n return this.repo.find({ relations: ['moduleMetadata'] });\n }\n\n private parseSettingValue(value: string, key: string): any {\n try {\n return JSON.parse(value);\n } catch {\n if (value === 'true' || value === 'false') {\n return value === 'true';\n }\n if (!isNaN(Number(value)) && value.trim() !== '') {\n return Number(value);\n }\n if (!this.arrayKeysToSkip.has(key) && value.includes(',')) {\n return value.split(',').map(item => item.trim());\n }\n return value;\n }\n }\n\n private buildSettingLabel(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[-_]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (match) => match.toUpperCase());\n }\n\n private inferControlType(setting: SettingDefinition): SettingControlType {\n if (setting.controlType) {\n return setting.controlType;\n }\n\n if (setting.options?.length) {\n return 'selectionStatic';\n }\n\n if (typeof setting.value === 'boolean') {\n return 'boolean';\n }\n\n if (typeof setting.value === 'number') {\n return 'numeric';\n }\n\n return 'shortText';\n }\n\n private toAdminSettingDefinition(setting: SettingDefinition): AdminSettingDefinition {\n return {\n ...setting,\n label: setting.label ?? this.buildSettingLabel(setting.key),\n controlType: this.inferControlType(setting),\n editable: setting.level === SettingLevel.SystemAdminEditable,\n };\n }\n\n /**\n * Reads all registered providers and gathers settings from across the running platform.\n * This is the superset of all possible settings. \n * @returns \n */\n private getAllSettingsFromProviders(): SettingDefinition[] {\n // get all settings from registry \n const allSettingsProviders = this.solidRegistry.getSettingsProviders();\n const settings: SettingDefinition[] = [];\n const seenKeys = new Map<string, { setting: SettingDefinition; providerName?: string }>();\n for (const wrapper of allSettingsProviders) {\n const instance = wrapper.instance as ISettingsProvider;\n // if (!instance?.getSettings) continue;\n for (const setting of instance.getSettings()) {\n const existing = seenKeys.get(setting.key);\n if (existing) {\n throw new Error(\n `Duplicate setting key detected: ${setting.key}. ` +\n `First: ${JSON.stringify(existing.setting)} from provider: ${existing.providerName ?? \"unknown\"}. ` +\n `Second: ${JSON.stringify(setting)} from provider: ${wrapper.name ?? \"unknown\"}.`\n );\n }\n seenKeys.set(setting.key, { setting, providerName: wrapper.name });\n settings.push(setting);\n }\n }\n\n return settings\n }\n\n /**\n * public method that gets all settings in the system, this includes settings from solid-core and any consuming projects.\n * this means that the settings returned are the ones provided by ISettingsProvider, merged with values if any from the database. \n * \n * @returns \n */\n getAllSettings(): SettingDefinition[] {\n return this.settings;\n }\n\n async updateSettingsCache(): Promise<void> {\n this._logger.debug(`updating settings cache...`);\n const settingsFromDb = await this.getSettingsFromDb();\n const settingsFromProviders = this.getAllSettingsFromProviders();\n const settingsFromDbByKey = new Map(settingsFromDb.map(setting => [setting.key, setting]));\n\n this.settings = settingsFromProviders.map(setting => {\n const settingFromDb = settingsFromDbByKey.get(setting.key);\n const valueFromDb = settingFromDb?.value;\n if (settingFromDb?.key && valueFromDb !== undefined && valueFromDb !== null) {\n let rawValue = valueFromDb;\n if (settingFromDb.encrypted && this.encryptionService) {\n try {\n rawValue = this.encryptionService.decrypt(rawValue);\n } catch {\n this._logger.warn(`Failed to decrypt setting \"${setting.key}\" — using raw value`);\n }\n }\n const parsedValue = typeof rawValue === 'string' ? this.parseSettingValue(rawValue, settingFromDb.key) : rawValue;\n return { ...setting, value: parsedValue };\n }\n return setting;\n });\n\n // Also keep a key vs SettingDefinition map...\n this.settingsByKey = new Map(this.settings.map(setting => [setting.key, setting]));\n }\n\n private isDisallowedSettingKey(key: string, settingLevelsToDisallow: SettingLevel[]): boolean {\n if (!key) {\n return false;\n }\n const setting = this.settingsByKey.get(key);\n // return setting ? [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly].includes(setting.level) : false;\n return setting ? settingLevelsToDisallow.includes(setting.level) : false;\n }\n\n /**\n * 1. \n * This method will seed (insert only) settings that are introduced in code but do not already exist in the database. \n * Also this method only deals with settings with level system-admin-editable & internal-user.\n */\n async seedSystemAdminEditableAndAboveSettings(): Promise<void> {\n // Seed only settings with level system-admin-editable & internal-user, \n // so basically settings which are either system-admin-editable and above.\n const saEditableAndAbove = this.getAllSettingsFromProviders().filter(i => [SettingLevel.SystemAdminEditable, SettingLevel.InternalUser].includes(i.level));\n\n // Get hold of the current values from the database.\n const existingSettingsFromDb: Setting[] = await this.getSettingsFromDbForSeeding();\n\n // const existingKeysFromDb = new Set(existingSettingsFromDb.map(s => s.key));\n const existingSettingsFromDbByKey = new Map(existingSettingsFromDb.map(setting => [setting.key, setting]));\n const settingsToCreate: Setting[] = [];\n const settingsToUpdate: Setting[] = [];\n const moduleNames = Array.from(\n new Set(\n saEditableAndAbove\n .map(setting => setting.moduleName)\n .filter((moduleName): moduleName is string => !!moduleName)\n )\n );\n const moduleMetadataByName = new Map<string, Awaited<ReturnType<ModuleMetadataRepository['findOneBy']>>>();\n\n await Promise.all(\n moduleNames.map(async (moduleName) => {\n const moduleMetadata = await this.moduleMetadataRepo.findOneBy({ name: moduleName });\n moduleMetadataByName.set(moduleName, moduleMetadata);\n })\n );\n\n for (const { key, value, level, moduleName, encrypted } of saEditableAndAbove) {\n const moduleMetadata = moduleName ? moduleMetadataByName.get(moduleName) : null;\n if (!existingSettingsFromDbByKey.has(key)) {\n const setting = new Setting();\n setting.key = key;\n setting.level = level;\n setting.encrypted = !!encrypted;\n if (moduleMetadata)\n setting.moduleMetadata = moduleMetadata;\n\n let rawValue: string | null;\n if (typeof value === 'boolean') {\n rawValue = value.toString();\n } else if (Array.isArray(value)) {\n rawValue = value.join(',');\n } else if (value === null || value === undefined) {\n rawValue = null;\n } else {\n rawValue = String(value);\n }\n\n if (encrypted && this.encryptionService && rawValue !== null) {\n rawValue = this.encryptionService.encrypt(rawValue);\n }\n setting.value = rawValue;\n\n settingsToCreate.push(setting);\n }\n else {\n const setting = existingSettingsFromDbByKey.get(key);\n const existingModuleMetadataId = setting.moduleMetadata?.id ?? null;\n const nextModuleMetadataId = moduleMetadata?.id ?? null;\n const levelChanged = setting.level !== level;\n const encryptedChanged = setting.encrypted !== !!encrypted;\n const moduleChanged = !!moduleMetadata && existingModuleMetadataId !== nextModuleMetadataId;\n\n if (!levelChanged && !encryptedChanged && !moduleChanged) {\n continue;\n }\n\n setting.level = level;\n setting.encrypted = !!encrypted;\n if (moduleMetadata) {\n setting.moduleMetadata = moduleMetadata;\n }\n settingsToUpdate.push(setting);\n }\n }\n\n if (settingsToCreate.length > 0) {\n await this.repo.save(settingsToCreate);\n }\n\n if (settingsToUpdate.length > 0) {\n await this.repo.save(settingsToUpdate);\n }\n }\n\n /**\n * 2. \n * Method used from the solid-core-ui to fetch available settings. \n * Here we are returning settings other than system-env.\n * \n * @returns \n */\n async getNonEncryptedSystemAdminReadonlyAndAboveSettings(): Promise<AdminSettingsResponse> {\n const activeUser = this.requestContextService.getActiveUser();\n const hasViewEncryptedPermission = !!activeUser?.permissions?.includes('settings:view_encrypted');\n\n const data = this.settings\n .filter(i => i.level !== \"system-env\")\n .filter(i => hasViewEncryptedPermission || !i.encrypted)\n .filter((setting) => [SettingLevel.SystemAdminReadonly, SettingLevel.SystemAdminEditable].includes(setting.level))\n .map((setting) => this.toAdminSettingDefinition(setting))\n .sort((left, right) => {\n const groupCompare = (left.group ?? '').localeCompare(right.group ?? '');\n if (groupCompare !== 0) {\n return groupCompare;\n }\n\n const leftSort = left.sortOrder ?? Number.MAX_SAFE_INTEGER;\n const rightSort = right.sortOrder ?? Number.MAX_SAFE_INTEGER;\n if (leftSort !== rightSort) {\n return leftSort - rightSort;\n }\n\n return left.label!.localeCompare(right.label!);\n });\n\n return { data };\n }\n\n /**\n * 3. \n * This method updates settings from the admin user interface. \n * Most likely settings with level system-admin-editable & internal-user are the ones that will get modified here. \n * \n * @param settings \n * @param uploadedFiles \n * @returns \n */\n async updateSettings(settings: CreateSettingDto[] = [], uploadedFiles: Array<Express.Multer.File> = []): Promise<Setting[]> {\n const activeUser = this.requestContextService.getActiveUser();\n const userId = activeUser?.sub;\n\n const restrictedKeys = new Set<string>();\n\n settings.forEach(setting => {\n if (this.isDisallowedSettingKey(setting.key, [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly])) {\n restrictedKeys.add(setting.key);\n }\n });\n uploadedFiles.forEach(file => {\n if (this.isDisallowedSettingKey(file.fieldname, [SettingLevel.SystemEnv, SettingLevel.SystemAdminReadonly])) {\n restrictedKeys.add(file.fieldname);\n }\n });\n\n if (restrictedKeys.size > 0) {\n throw new BadRequestException(`${ERROR_MESSAGES.FORBIDDEN}: Settings ${Array.from(restrictedKeys).join(', ')} cannot be modified.`);\n }\n\n // const existingSettings = await this.repo.find();\n const existingSettings: Setting[] = await this.getSettingsFromDb();\n\n const settingsToUpdate: Setting[] = [];\n const settingsToCreate: Setting[] = [];\n\n let user: User | null = null;\n const hasUserSettings = settings.some(dto => dto.type === 'user');\n if (hasUserSettings && userId) {\n user = await this.userRepository.findOne({ where: { id: userId } });\n }\n\n // Handle uploaded files\n if (uploadedFiles?.length) {\n for (const file of uploadedFiles) {\n const settingKey = file.fieldname;\n const relativeFileName = `${file.filename}-${file.originalname}`;\n\n // Read file from local disk (where Multer stores uploads) and write to storage\n // The path builder constructs the provider-appropriate storage path\n const fileContent = await fsPromises.readFile(file.path);\n const storagePath = this.pathBuilder.build(relativeFileName);\n const fileUrl = await this.fileService.write(storagePath, fileContent, { contentType: file.mimetype });\n // Delete the temp file from local disk\n await fsPromises.unlink(file.path);\n\n const matchedDto = settings.find(dto => dto.key === settingKey);\n const settingType = matchedDto?.type ?? 'system';\n\n const existingSetting = existingSettings.find(s => s.key === settingKey);\n if (existingSetting) {\n existingSetting.value = fileUrl;\n existingSetting.type = settingType;\n settingsToUpdate.push(existingSetting);\n } else {\n const newSetting = new Setting();\n newSetting.key = settingKey;\n newSetting.value = fileUrl;\n newSetting.type = settingType;\n\n if (settingType === 'user' && user) {\n newSetting.user = user;\n }\n\n settingsToCreate.push(newSetting);\n }\n }\n }\n\n // Handle non-file settings\n for (const settingDto of settings) {\n if (uploadedFiles?.some(file => file.fieldname === settingDto.key)) {\n continue; // skip if already handled via file\n }\n\n const key = settingDto.key;\n const rawValue = settingDto.value;\n let value = rawValue === null || rawValue === undefined ? null : String(rawValue);\n\n const settingType = settingDto.type ?? 'system';\n const definition = this.settingsByKey.get(key);\n const shouldEncrypt = !!definition?.encrypted && this.encryptionService !== null && value !== null;\n\n if (shouldEncrypt) {\n value = this.encryptionService.encrypt(value);\n }\n\n const existingSetting = existingSettings.find(s => s.key === key);\n if (existingSetting) {\n existingSetting.value = value;\n existingSetting.type = settingType;\n existingSetting.encrypted = shouldEncrypt;\n settingsToUpdate.push(existingSetting);\n } else {\n const newSetting = new Setting();\n newSetting.key = key;\n newSetting.value = value;\n newSetting.type = settingType;\n newSetting.encrypted = shouldEncrypt;\n\n if (settingType === 'user' && user) {\n newSetting.user = user;\n }\n\n settingsToCreate.push(newSetting);\n }\n }\n\n if (settingsToUpdate.length > 0) {\n await this.repo.save(settingsToUpdate);\n }\n\n if (settingsToCreate.length > 0) {\n await this.repo.save(settingsToCreate);\n }\n await this.updateSettingsCache();\n\n return [...settingsToUpdate, ...settingsToCreate];\n }\n\n /**\n * 4. \n * @param settingKey \n * @returns \n */\n getConfigValue<T = never>(settingKey: NoInfer<T>) {\n const cachedSetting = this.settingsByKey.get(settingKey as string);\n if (cachedSetting) {\n return cachedSetting.value;\n }\n\n return null;\n\n // const cachedSetting = this.settings.find(setting => setting.key === settingKey);\n // if (cachedSetting) {\n // return cachedSetting.value;\n // }\n\n // // This is probably not needed at all, but leaving it here as a backup for scenarios like \n // // if getConfigValue<SolidCoreSetting>() is called before onApplicationBootstrap() runs or if the cache refresh fails. \n // const getAllSettings = this.getAllSettingsFromProviders();\n // const settingValue = getAllSettings.find(i => (i.key == settingKey))\n // return settingValue?.value;\n }\n\n async getMcpUrl(getMcpUrlDto: GetMcpUrlDto, solidRequestContext: any = {}): Promise<any> {\n\n const { showHeader, inListView } = getMcpUrlDto;\n\n const mcpEnabled = this.getConfigValue<SolidCoreSetting>('mcpEnabled');\n if (mcpEnabled === 'false' || mcpEnabled === false) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n if (solidRequestContext.activeUser) {\n const permissionNames = [\"SettingController.getMcpUrl\"];\n const matchingPermssions = solidRequestContext.activeUser.permissions.filter((p: any) => permissionNames.includes(p));\n const hasPermission = matchingPermssions.length > 0;\n if (!hasPermission) {\n throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);\n }\n }\n const apiKey = this.getConfigValue<SolidCoreSetting>('mcpApiKey');\n const userId = solidRequestContext.activeUser.sub;\n const mcpServerUrl = this.getConfigValue<SolidCoreSetting>('mcpServerUrl');\n return { mcpUrl: `${mcpServerUrl}/static/frontend.html?solidx-mcp-api-key=${apiKey}&solidx-user-id=${userId}&solidx-show-header=${showHeader}&solidx-in-list-view=${inListView}` };\n }\n\n}\n"]}
@@ -1,4 +1,4 @@
1
- type Bucket = "providers" | "exports";
1
+ type Bucket = "imports" | "providers" | "exports";
2
2
  export declare class SolidTsMorphService {
3
3
  private readonly logger;
4
4
  private project;
@@ -1 +1 @@
1
- {"version":3,"file":"solid-ts-morph.service.d.ts","sourceRoot":"","sources":["../../src/services/solid-ts-morph.service.ts"],"names":[],"mappings":"AAOA,KAAK,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAStC,qBACa,mBAAmB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAA8D;IAClF,OAAO,CAAC,gBAAgB,CAAqB;IAG7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;;IA0BtD,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,GAAG;IAMX,KAAK,IAAI,IAAI;IAmBb,QAAQ,IAAI,IAAI;IAgBV,MAAM,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAiD1C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG;QAAE,eAAe,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAqB/G,oBAAoB,CAChB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,EACzB,WAAW,UAAO,GACnB;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE;IAyDtB,wBAAwB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACnB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IA6B9D,wBAAwB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAClB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IA2B9D,aAAa,CACT,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,GAC7C;QAAE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAqCzE,mBAAmB,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,GAC9B;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAoDxC,SAAS,CACL,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACnB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;CA6CjE"}
1
+ {"version":3,"file":"solid-ts-morph.service.d.ts","sourceRoot":"","sources":["../../src/services/solid-ts-morph.service.ts"],"names":[],"mappings":"AAOA,KAAK,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AASlD,qBACa,mBAAmB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAA8D;IAClF,OAAO,CAAC,gBAAgB,CAAqB;IAG7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;;IA0BtD,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,GAAG;IAMX,KAAK,IAAI,IAAI;IAmBb,QAAQ,IAAI,IAAI;IAgBV,MAAM,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAiD1C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG;QAAE,eAAe,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAqB/G,oBAAoB,CAChB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,EACzB,WAAW,UAAO,GACnB;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE;IAyDtB,wBAAwB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACnB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IA6B9D,wBAAwB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAClB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IA2B9D,aAAa,CACT,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,OAAO,GAC7C;QAAE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAqCzE,mBAAmB,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,GAC9B;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAoDxC,SAAS,CACL,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACnB;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;CA6CjE"}