@solidxai/core 0.1.10-beta.0 → 0.1.10-beta.10

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 (189) hide show
  1. package/dist/commands/run-tests.command.d.ts +2 -0
  2. package/dist/commands/run-tests.command.d.ts.map +1 -1
  3. package/dist/commands/run-tests.command.js +49 -17
  4. package/dist/commands/run-tests.command.js.map +1 -1
  5. package/dist/controllers/action-metadata.controller.js +1 -1
  6. package/dist/controllers/action-metadata.controller.js.map +1 -1
  7. package/dist/controllers/facebook-authentication.controller.js +1 -1
  8. package/dist/controllers/facebook-authentication.controller.js.map +1 -1
  9. package/dist/controllers/google-authentication.controller.js +1 -1
  10. package/dist/controllers/google-authentication.controller.js.map +1 -1
  11. package/dist/controllers/menu-item-metadata.controller.js +1 -1
  12. package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
  13. package/dist/controllers/microsoft-authentication.controller.js +1 -1
  14. package/dist/controllers/microsoft-authentication.controller.js.map +1 -1
  15. package/dist/controllers/mq-message-queue.controller.js +1 -1
  16. package/dist/controllers/mq-message-queue.controller.js.map +1 -1
  17. package/dist/controllers/mq-message.controller.js +1 -1
  18. package/dist/controllers/mq-message.controller.js.map +1 -1
  19. package/dist/controllers/user.controller.d.ts.map +1 -1
  20. package/dist/controllers/user.controller.js.map +1 -1
  21. package/dist/controllers/view-metadata.controller.js +1 -1
  22. package/dist/controllers/view-metadata.controller.js.map +1 -1
  23. package/dist/dtos/update-user.dto.d.ts +1 -0
  24. package/dist/dtos/update-user.dto.d.ts.map +1 -1
  25. package/dist/dtos/update-user.dto.js +7 -1
  26. package/dist/dtos/update-user.dto.js.map +1 -1
  27. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  28. package/dist/entities/chatter-message-details.entity.js +0 -1
  29. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  30. package/dist/entities/user.entity.js +1 -0
  31. package/dist/entities/user.entity.js.map +1 -1
  32. package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
  33. package/dist/helpers/bootstrap.helper.js +2 -0
  34. package/dist/helpers/bootstrap.helper.js.map +1 -1
  35. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
  36. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
  37. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  38. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -1
  39. package/dist/jobs/database/chatter-queue-subscriber-database.service.js +3 -3
  40. package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -1
  41. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  42. package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.d.ts.map +1 -1
  43. package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.js +3 -3
  44. package/dist/jobs/rabbitmq/chatter-queue-subscriber.service.js.map +1 -1
  45. package/dist/jobs/redis/chatter-queue-subscriber-redis.service.d.ts.map +1 -1
  46. package/dist/jobs/redis/chatter-queue-subscriber-redis.service.js +3 -3
  47. package/dist/jobs/redis/chatter-queue-subscriber-redis.service.js.map +1 -1
  48. package/dist/repository/security-rule.repository.js.map +1 -1
  49. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  50. package/dist/seeders/module-test-data.service.d.ts +7 -0
  51. package/dist/seeders/module-test-data.service.d.ts.map +1 -1
  52. package/dist/seeders/module-test-data.service.js +94 -18
  53. package/dist/seeders/module-test-data.service.js.map +1 -1
  54. package/dist/seeders/permission-metadata-seeder.service.js.map +1 -1
  55. package/dist/seeders/seed-data/solid-core-metadata.json +34 -2
  56. package/dist/services/authentication.service.d.ts.map +1 -1
  57. package/dist/services/authentication.service.js +5 -5
  58. package/dist/services/authentication.service.js.map +1 -1
  59. package/dist/services/chatter-message.service.d.ts +6 -3
  60. package/dist/services/chatter-message.service.d.ts.map +1 -1
  61. package/dist/services/chatter-message.service.js +23 -35
  62. package/dist/services/chatter-message.service.js.map +1 -1
  63. package/dist/services/crud.service.js.map +1 -1
  64. package/dist/services/csv.service.js.map +1 -1
  65. package/dist/services/dashboard.service.js.map +1 -1
  66. package/dist/services/database/database-bootstrap.service.js.map +1 -1
  67. package/dist/services/excel.service.js.map +1 -1
  68. package/dist/services/export-transaction.service.js.map +1 -1
  69. package/dist/services/field-metadata.service.js +2 -2
  70. package/dist/services/field-metadata.service.js.map +1 -1
  71. package/dist/services/fixtures.service.js.map +1 -1
  72. package/dist/services/import-transaction.service.js.map +1 -1
  73. package/dist/services/list-of-values.service.js.map +1 -1
  74. package/dist/services/model-metadata.service.d.ts.map +1 -1
  75. package/dist/services/model-metadata.service.js +3 -13
  76. package/dist/services/model-metadata.service.js.map +1 -1
  77. package/dist/services/module-metadata.service.js.map +1 -1
  78. package/dist/services/queues/database-publisher.service.js +3 -3
  79. package/dist/services/queues/database-publisher.service.js.map +1 -1
  80. package/dist/services/queues/database-subscriber.service.js +3 -3
  81. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  82. package/dist/services/queues/rabbitmq-publisher.service.js +3 -3
  83. package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
  84. package/dist/services/queues/rabbitmq-subscriber.service.js +4 -4
  85. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  86. package/dist/services/queues/redis-publisher.service.d.ts.map +1 -1
  87. package/dist/services/queues/redis-publisher.service.js +4 -1
  88. package/dist/services/queues/redis-publisher.service.js.map +1 -1
  89. package/dist/services/queues/redis-subscriber.service.d.ts.map +1 -1
  90. package/dist/services/queues/redis-subscriber.service.js +4 -1
  91. package/dist/services/queues/redis-subscriber.service.js.map +1 -1
  92. package/dist/services/role-metadata.service.js.map +1 -1
  93. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  94. package/dist/services/settings/default-settings-provider.service.d.ts +58 -8
  95. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  96. package/dist/services/settings/default-settings-provider.service.js +21 -4
  97. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  98. package/dist/services/sms/TwilioSMSService.js.map +1 -1
  99. package/dist/services/solid-introspect.service.js.map +1 -1
  100. package/dist/services/user-activity-history.service.js.map +1 -1
  101. package/dist/services/view-metadata.service.d.ts.map +1 -1
  102. package/dist/services/view-metadata.service.js +17 -2
  103. package/dist/services/view-metadata.service.js.map +1 -1
  104. package/dist/solid-core.module.d.ts +1 -0
  105. package/dist/solid-core.module.d.ts.map +1 -1
  106. package/dist/solid-core.module.js +1 -0
  107. package/dist/solid-core.module.js.map +1 -1
  108. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  109. package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -1
  110. package/dist/subscribers/security-rule.subscriber.js.map +1 -1
  111. package/dist/subscribers/view-metadata.subscriber.js.map +1 -1
  112. package/dist/testing/core/testing-engine.js.map +1 -1
  113. package/dist/testing/reporter/console-reporter.d.ts +10 -0
  114. package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
  115. package/dist/testing/reporter/console-reporter.js +21 -0
  116. package/dist/testing/reporter/console-reporter.js.map +1 -1
  117. package/dist/testing/reporter/reporter.types.d.ts +7 -0
  118. package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
  119. package/dist/testing/reporter/reporter.types.js.map +1 -1
  120. package/dist/testing/reporter/webhook-reporter.d.ts +54 -0
  121. package/dist/testing/reporter/webhook-reporter.d.ts.map +1 -0
  122. package/dist/testing/reporter/webhook-reporter.js +74 -0
  123. package/dist/testing/reporter/webhook-reporter.js.map +1 -0
  124. package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
  125. package/dist/testing/runner/run-from-metadata.js +20 -1
  126. package/dist/testing/runner/run-from-metadata.js.map +1 -1
  127. package/package.json +5 -1
  128. package/src/commands/run-tests.command.ts +45 -17
  129. package/src/controllers/action-metadata.controller.ts +1 -1
  130. package/src/controllers/facebook-authentication.controller.ts +1 -1
  131. package/src/controllers/google-authentication.controller.ts +1 -1
  132. package/src/controllers/menu-item-metadata.controller.ts +1 -1
  133. package/src/controllers/microsoft-authentication.controller.ts +1 -1
  134. package/src/controllers/mq-message-queue.controller.ts +1 -1
  135. package/src/controllers/mq-message.controller.ts +1 -1
  136. package/src/controllers/user.controller.ts +16 -16
  137. package/src/controllers/view-metadata.controller.ts +1 -1
  138. package/src/dtos/update-user.dto.ts +4 -0
  139. package/src/entities/chatter-message-details.entity.ts +1 -2
  140. package/src/entities/user.entity.ts +1 -1
  141. package/src/helpers/bootstrap.helper.ts +3 -0
  142. package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +1 -1
  143. package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +1 -1
  144. package/src/helpers/module-metadata-helper.service.ts +1 -1
  145. package/src/jobs/database/chatter-queue-subscriber-database.service.ts +4 -2
  146. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +1 -1
  147. package/src/jobs/rabbitmq/chatter-queue-subscriber.service.ts +4 -2
  148. package/src/jobs/redis/chatter-queue-subscriber-redis.service.ts +10 -3
  149. package/src/repository/security-rule.repository.ts +1 -1
  150. package/src/seeders/module-metadata-seeder.service.ts +4 -4
  151. package/src/seeders/module-test-data.service.ts +107 -15
  152. package/src/seeders/permission-metadata-seeder.service.ts +1 -1
  153. package/src/seeders/seed-data/solid-core-metadata.json +34 -2
  154. package/src/services/authentication.service.ts +19 -31
  155. package/src/services/chatter-message.service.ts +28 -38
  156. package/src/services/crud.service.ts +3 -3
  157. package/src/services/csv.service.ts +1 -1
  158. package/src/services/dashboard.service.ts +1 -1
  159. package/src/services/database/database-bootstrap.service.ts +1 -1
  160. package/src/services/excel.service.ts +1 -1
  161. package/src/services/export-transaction.service.ts +2 -2
  162. package/src/services/field-metadata.service.ts +3 -3
  163. package/src/services/fixtures.service.ts +2 -2
  164. package/src/services/import-transaction.service.ts +2 -2
  165. package/src/services/list-of-values.service.ts +1 -1
  166. package/src/services/model-metadata.service.ts +22 -21
  167. package/src/services/module-metadata.service.ts +7 -7
  168. package/src/services/queues/database-publisher.service.ts +4 -4
  169. package/src/services/queues/database-subscriber.service.ts +7 -7
  170. package/src/services/queues/rabbitmq-publisher.service.ts +7 -7
  171. package/src/services/queues/rabbitmq-subscriber.service.ts +13 -13
  172. package/src/services/queues/redis-publisher.service.ts +7 -4
  173. package/src/services/queues/redis-subscriber.service.ts +9 -6
  174. package/src/services/role-metadata.service.ts +1 -1
  175. package/src/services/scheduled-jobs/scheduler.service.ts +5 -5
  176. package/src/services/settings/default-settings-provider.service.ts +21 -4
  177. package/src/services/sms/TwilioSMSService.ts +2 -2
  178. package/src/services/solid-introspect.service.ts +2 -2
  179. package/src/services/user-activity-history.service.ts +1 -1
  180. package/src/services/view-metadata.service.ts +25 -8
  181. package/src/solid-core.module.ts +1 -0
  182. package/src/subscribers/computed-entity-field.subscriber.ts +1 -1
  183. package/src/subscribers/security-rule.subscriber.ts +8 -8
  184. package/src/subscribers/view-metadata.subscriber.ts +1 -1
  185. package/src/testing/core/testing-engine.ts +2 -2
  186. package/src/testing/reporter/console-reporter.ts +27 -0
  187. package/src/testing/reporter/reporter.types.ts +7 -0
  188. package/src/testing/reporter/webhook-reporter.ts +116 -0
  189. package/src/testing/runner/run-from-metadata.ts +19 -1
@@ -3,6 +3,7 @@ import { SubCommand, CommandRunner, Option } from 'nest-commander';
3
3
  import * as path from 'path';
4
4
  import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
5
5
  import { ConsoleReporter } from 'src/testing/reporter/console-reporter';
6
+ import { WebhookReporter } from 'src/testing/reporter/webhook-reporter';
6
7
  import { runFromMetadata } from 'src/testing/runner/run-from-metadata';
7
8
  import type { TestingMetadata } from 'src/testing/contracts/testing-metadata.types';
8
9
  import { SpecRegistry } from 'src/testing/core/spec-registry';
@@ -21,6 +22,7 @@ interface TestRunCommandOptions {
21
22
  retries?: number;
22
23
  listSpecs?: boolean;
23
24
  printApiLogs?: boolean;
25
+ runName?: string;
24
26
  }
25
27
 
26
28
  @SubCommand({
@@ -89,23 +91,40 @@ export class TestRunCommand extends CommandRunner {
89
91
  const headless = options?.headless ?? true;
90
92
  const printApiLogs = options?.printApiLogs ?? false;
91
93
 
92
- await runFromMetadata({
93
- metadata: metadata as TestingMetadata,
94
- scenarioIds,
95
- includeTags,
96
- skipScenarioIds,
97
- reporter: new ConsoleReporter(),
98
- api: apiBaseUrl ? { baseUrl: apiBaseUrl } : undefined,
99
- ui: { baseUrl: uiBaseUrl, headless },
100
- defaults: {
101
- timeoutMs: options?.timeoutMs,
102
- retries: options?.retries,
103
- },
104
- options: { printApiLogs },
105
- specs: specEntries.length
106
- ? (registry) => loadSpecRegistrations(specEntries, metadataPath, registry)
107
- : undefined,
108
- });
94
+ const webhookUrl = process.env.SOLIDCTL_WEBHOOK_URL;
95
+ const runName = options?.runName ?? `run-${Date.now()}`;
96
+ const reporter = webhookUrl
97
+ ? new WebhookReporter(webhookUrl, runName)
98
+ : new ConsoleReporter();
99
+
100
+ try {
101
+ await runFromMetadata({
102
+ metadata: metadata as TestingMetadata,
103
+ scenarioIds,
104
+ includeTags,
105
+ skipScenarioIds,
106
+ reporter,
107
+ api: apiBaseUrl ? { baseUrl: apiBaseUrl } : undefined,
108
+ ui: { baseUrl: uiBaseUrl, headless },
109
+ defaults: {
110
+ timeoutMs: options?.timeoutMs,
111
+ retries: options?.retries,
112
+ },
113
+ options: { printApiLogs },
114
+ specs: specEntries.length
115
+ ? (registry) => loadSpecRegistrations(specEntries, metadataPath, registry)
116
+ : undefined,
117
+ });
118
+ } catch (err: any) {
119
+ this.logger.error('Run tests command failed');
120
+ console.error('Run tests command failed');
121
+ process.exitCode = 1;
122
+ } finally {
123
+ if (reporter instanceof WebhookReporter) {
124
+ await reporter.flush(Number(process.exitCode ?? 0));
125
+ }
126
+ }
127
+ return;
109
128
  } catch (err: any) {
110
129
  this.logger.error('Run tests command failed');
111
130
  console.error('Run tests command failed');
@@ -223,6 +242,15 @@ export class TestRunCommand extends CommandRunner {
223
242
  parseRetries(val: string): number {
224
243
  return Number(val);
225
244
  }
245
+
246
+ @Option({
247
+ flags: '--run-name [name]',
248
+ description: 'Logical name for this test run (used by webhook reporter).',
249
+ required: false,
250
+ })
251
+ parseRunName(val: string): string {
252
+ return val;
253
+ }
226
254
  }
227
255
 
228
256
  function splitCsv(value?: string): string[] | undefined {
@@ -7,7 +7,7 @@ import { UpdateActionMetadataDto } from '../dtos/update-action-metadata.dto';
7
7
  import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
8
8
  import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
9
9
 
10
- @ApiTags('App Builder')
10
+ @ApiTags('Solid Core')
11
11
  @Controller('action-metadata') //FIXME: Change this to the model plural name
12
12
  export class ActionMetadataController {
13
13
  constructor(private readonly service: ActionMetadataService) { }
@@ -24,7 +24,7 @@ import { UserService } from "../services/user.service";
24
24
  import type { SolidCoreSetting } from "../services/settings/default-settings-provider.service";
25
25
 
26
26
  @Auth(AuthType.None)
27
- @ApiTags("Iam")
27
+ @ApiTags("Solid Core")
28
28
  @Controller("iam/facebook")
29
29
  export class FacebookAuthenticationController {
30
30
  constructor(
@@ -16,7 +16,7 @@ import type { SolidCoreSetting } from "src/services/settings/default-settings-pr
16
16
 
17
17
  @Auth(AuthType.None)
18
18
  @Controller('iam/google')
19
- @ApiTags("Iam")
19
+ @ApiTags("Solid Core")
20
20
  // @UseGuards(ThrottlerGuard)
21
21
  // @SkipThrottle({ login: false, short: false, burst: true, sustained: true }) //Enable the login throttle only
22
22
  export class GoogleAuthenticationController {
@@ -9,7 +9,7 @@ import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
9
9
  import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
10
10
  import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
11
11
 
12
- @ApiTags('App Builder')
12
+ @ApiTags('Solid Core')
13
13
  @Controller('menu-item-metadata') //FIXME: Change this to the model plural name
14
14
  export class MenuItemMetadataController {
15
15
  constructor(private readonly service: MenuItemMetadataService) { }
@@ -24,7 +24,7 @@ import { UserService } from "../services/user.service";
24
24
  import type { SolidCoreSetting } from "../services/settings/default-settings-provider.service";
25
25
 
26
26
  @Auth(AuthType.None)
27
- @ApiTags("Iam")
27
+ @ApiTags("Solid Core")
28
28
  @Controller("iam/microsoft")
29
29
  export class MicrosoftAuthenticationController {
30
30
  constructor(
@@ -7,7 +7,7 @@ import { MqMessageQueueService } from '../services/mq-message-queue.service';
7
7
  import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
8
8
  import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
9
9
 
10
- @ApiTags('Queues')
10
+ @ApiTags('Solid Core')
11
11
  @Controller('mq-message-queue') //FIXME: Change this to the model plural name
12
12
  export class MqMessageQueueController {
13
13
  constructor(protected readonly service: MqMessageQueueService) { }
@@ -7,7 +7,7 @@ import { AnyFilesInterceptor } from '@nestjs/platform-express';
7
7
  import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
8
8
  import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
9
9
 
10
- @ApiTags('Queues')
10
+ @ApiTags('Solid Core')
11
11
  @Controller('mq-message') //FIXME: Change this to the model plural name
12
12
  export class MqMessageController {
13
13
  constructor(protected readonly service: MqMessageService) { }
@@ -20,37 +20,37 @@ export class UserController {
20
20
  @ApiBearerAuth("jwt")
21
21
  @Post()
22
22
  @UseInterceptors(AnyFilesInterceptor())
23
- create(@Body() createDto: CreateUserDto, @UploadedFiles() files: Array<Express.Multer.File>,@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
24
- return this.service.create(createDto, files,solidRequestContext);
23
+ create(@Body() createDto: CreateUserDto, @UploadedFiles() files: Array<Express.Multer.File>, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
24
+ return this.service.create(createDto, files, solidRequestContext);
25
25
  }
26
26
 
27
27
  @ApiBearerAuth("jwt")
28
28
  @Post('/bulk')
29
29
  @UseInterceptors(AnyFilesInterceptor())
30
- insertMany(@Body() createDtos: CreateUserDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = [],@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
31
- return this.service.insertMany(createDtos, filesArray,solidRequestContext);
30
+ insertMany(@Body() createDtos: CreateUserDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = [], @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
31
+ return this.service.insertMany(createDtos, filesArray, solidRequestContext);
32
32
  }
33
33
 
34
34
 
35
35
  @ApiBearerAuth("jwt")
36
36
  @Put(':id')
37
37
  @UseInterceptors(AnyFilesInterceptor())
38
- update(@Param('id') id: number, @Body() updateDto: UpdateUserDto, @UploadedFiles() files: Array<Express.Multer.File> ,@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
39
- return this.service.update(id, updateDto, files,false,solidRequestContext);
38
+ update(@Param('id') id: number, @Body() updateDto: UpdateUserDto, @UploadedFiles() files: Array<Express.Multer.File>, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
39
+ return this.service.update(id, updateDto, files, false, solidRequestContext);
40
40
  }
41
41
 
42
42
 
43
43
  @ApiBearerAuth("jwt")
44
44
  @Patch(':id/update-user-and-roles')
45
- updateUser(@Param('id') id: number,@Body() updateDto: any, @UploadedFiles() files: Array<Express.Multer.File>, @SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
46
- return this.service.updateUser(id, updateDto, files,solidRequestContext);
45
+ updateUser(@Param('id') id: number, @Body() updateDto: any, @UploadedFiles() files: Array<Express.Multer.File>, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
46
+ return this.service.updateUser(id, updateDto, files, solidRequestContext);
47
47
  }
48
48
 
49
49
 
50
50
  @ApiBearerAuth("jwt")
51
51
  @Patch(':id')
52
52
  @UseInterceptors(AnyFilesInterceptor())
53
- partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateUserDto, @UploadedFiles() files: Array<Express.Multer.File>,@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
53
+ partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateUserDto, @UploadedFiles() files: Array<Express.Multer.File>, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
54
54
  return this.service.update(id, updateDto, files, true, solidRequestContext);
55
55
  }
56
56
 
@@ -67,8 +67,8 @@ export class UserController {
67
67
  @ApiQuery({ name: 'populateMedia', required: false, type: Array })
68
68
  @ApiQuery({ name: 'filters', required: false, type: Array })
69
69
  @Get()
70
- async findMany(@Query() query: any, @SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
71
- return this.service.find(query,solidRequestContext);
70
+ async findMany(@Query() query: any, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
71
+ return this.service.find(query, solidRequestContext);
72
72
  }
73
73
 
74
74
  @ApiBearerAuth("jwt")
@@ -81,18 +81,18 @@ export class UserController {
81
81
 
82
82
  @ApiBearerAuth("jwt")
83
83
  @Get(':id')
84
- async findOne(@Param('id') id: string, @Query() query: any,@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
85
- return this.service.findOne(+id, query,solidRequestContext);
84
+ async findOne(@Param('id') id: string, @Query() query: any, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
85
+ return this.service.findOne(+id, query, solidRequestContext);
86
86
  }
87
87
 
88
88
  @Delete('/bulk')
89
- async deleteMany(@Body() ids: number[],@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
90
- return this.service.deleteMany(ids,solidRequestContext);
89
+ async deleteMany(@Body() ids: number[], @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
90
+ return this.service.deleteMany(ids, solidRequestContext);
91
91
  }
92
92
 
93
93
  @ApiBearerAuth("jwt")
94
94
  @Delete(':id')
95
- async delete(@Param('id') id: number,@SolidRequestContextDecorator() solidRequestContext:SolidRequestContextDto) {
95
+ async delete(@Param('id') id: number, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
96
96
  return this.service.delete(id, solidRequestContext);
97
97
  }
98
98
 
@@ -9,7 +9,7 @@ import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
9
9
  import { ActiveUser } from 'src/decorators/active-user.decorator';
10
10
  import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
11
11
 
12
- @ApiTags('App Builder')
12
+ @ApiTags('Solid Core')
13
13
  @Controller('view-metadata') //FIXME: Change this to the model plural name
14
14
  export class ViewMetadataController {
15
15
  constructor(private readonly service: ViewMetadataService) { }
@@ -161,4 +161,8 @@ export class UpdateUserDto {
161
161
  @IsOptional()
162
162
  @ApiProperty()
163
163
  userViewMetadataCommand: string;
164
+ @IsOptional()
165
+ @IsInt()
166
+ @ApiProperty()
167
+ failedLoginAttempts: number;
164
168
  }
@@ -18,7 +18,6 @@ export class ChatterMessageDetails extends CommonEntity {
18
18
  @Column({ type: "varchar", nullable: true })
19
19
  oldValueDisplay: string;
20
20
 
21
- @Index()
22
21
  @Column({ type: "varchar", nullable: true })
23
22
  newValueDisplay: string;
24
23
 
@@ -30,4 +29,4 @@ export class ChatterMessageDetails extends CommonEntity {
30
29
 
31
30
  @Column({ type: "varchar", nullable: true })
32
31
  fieldType: string;
33
- }
32
+ }
@@ -177,7 +177,7 @@ export class User extends CommonEntity {
177
177
  @Column({ nullable: true })
178
178
  rehashedAt: Date;
179
179
 
180
- // dont send to client
180
+ @Expose()
181
181
  @Column({ type: "int", default: 0 })
182
182
  failedLoginAttempts: number = 0;
183
183
 
@@ -1,5 +1,6 @@
1
1
  import { ValidationPipe } from '@nestjs/common';
2
2
  import { NestFactory } from '@nestjs/core';
3
+ import { WsAdapter } from '@nestjs/platform-ws';
3
4
  import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
4
5
  import { NextFunction, Request, Response } from 'express';
5
6
  import helmet from 'helmet';
@@ -178,6 +179,8 @@ export async function bootstrapSolidApp(
178
179
  const types = require('pg').types;
179
180
  types.setTypeParser(types.builtins.INT8, (val: string) => parseInt(val));
180
181
 
182
+ app.useWebSocketAdapter(new WsAdapter(app));
183
+
181
184
  await app.listen(port);
182
185
  }
183
186
 
@@ -20,7 +20,7 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
20
20
  if (typeof fieldValue === 'string' || typeof fieldValue === 'number') {
21
21
  fieldValue = BigInt(fieldValue);
22
22
  }
23
- } catch (err) {
23
+ } catch (err: any) {
24
24
  return [{ field: this.options.fieldName, error: 'Invalid numeric value' }];
25
25
  }
26
26
  }
@@ -119,7 +119,7 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
119
119
  }
120
120
  return false;
121
121
  }
122
- catch (error) {
122
+ catch (error: any) {
123
123
  // Use the values method as a fallback, if the value method is not implemented
124
124
  const values = await providerInstance.values('', ctxt);
125
125
  const isValid = values.some(v => v.value === fieldValue);
@@ -23,7 +23,7 @@ export class ModuleMetadataHelperService {
23
23
  const fileContent = await fs.readFile(configFilePath, 'utf8');
24
24
  return JSON.parse(fileContent);
25
25
  }
26
- catch (error) {
26
+ catch (error: any) {
27
27
  this.logger.error(`module metadata configuration non existent at: ${configFilePath}`);
28
28
  }
29
29
 
@@ -35,7 +35,7 @@ export class ChatterQueueSubscriberDatabase extends DatabaseSubscriber<AuditQueu
35
35
 
36
36
  switch (p.eventType) {
37
37
  case 'insert':
38
- await this.chatterMessageService.postAuditMessageOnInsert(p.after, p.modelName);
38
+ await this.chatterMessageService.postAuditMessageOnInsert(p.after, p.modelName, false, p.userId);
39
39
  break;
40
40
  case 'update':
41
41
  await this.chatterMessageService.postAuditMessageOnUpdate(
@@ -43,10 +43,12 @@ export class ChatterQueueSubscriberDatabase extends DatabaseSubscriber<AuditQueu
43
43
  p.modelName,
44
44
  p.before,
45
45
  (p.updatedColumnNames ?? []).map(n => ({ propertyName: n })),
46
+ false,
47
+ p.userId,
46
48
  );
47
49
  break;
48
50
  case 'delete':
49
- await this.chatterMessageService.postAuditMessageOnDelete(p.modelName, p.before);
51
+ await this.chatterMessageService.postAuditMessageOnDelete(p.modelName, p.before, false, p.userId);
50
52
  break;
51
53
  }
52
54
  }
@@ -60,7 +60,7 @@ export class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<Trigg
60
60
  // Fallback
61
61
  nestedResponse = String(raw);
62
62
  }
63
- } catch (err) {
63
+ } catch (err: any) {
64
64
  this.triggerMcpClientSubscriberLogger.error("Error processing AI response:", err);
65
65
  nestedResponse = `Error handling response: ${err?.message || String(err)}`;
66
66
  }
@@ -33,7 +33,7 @@ export class ChatterQueueSubscriberRabbitmq extends RabbitMqSubscriber<AuditQueu
33
33
 
34
34
  switch (p.eventType) {
35
35
  case 'insert':
36
- await this.chatterMessageService.postAuditMessageOnInsert(p.after, p.modelName);
36
+ await this.chatterMessageService.postAuditMessageOnInsert(p.after, p.modelName, false, p.userId);
37
37
  break;
38
38
  case 'update':
39
39
  await this.chatterMessageService.postAuditMessageOnUpdate(
@@ -41,10 +41,12 @@ export class ChatterQueueSubscriberRabbitmq extends RabbitMqSubscriber<AuditQueu
41
41
  p.modelName,
42
42
  p.before,
43
43
  (p.updatedColumnNames ?? []).map(n => ({ propertyName: n })),
44
+ false,
45
+ p.userId,
44
46
  );
45
47
  break;
46
48
  case 'delete':
47
- await this.chatterMessageService.postAuditMessageOnDelete(p.modelName, p.before);
49
+ await this.chatterMessageService.postAuditMessageOnDelete(p.modelName, p.before, false, p.userId);
48
50
  break;
49
51
  }
50
52
  }
@@ -33,13 +33,20 @@ export class ChatterQueueSubscriberRedis extends RedisSubscriber<any> {
33
33
 
34
34
  switch (p.eventType) {
35
35
  case 'insert':
36
- await this.chatterMessageService.postAuditMessageOnInsert(p.after, { name: p.modelName } as any);
36
+ await this.chatterMessageService.postAuditMessageOnInsert(p.after, p.modelName, false, p.userId);
37
37
  break;
38
38
  case 'update':
39
- await this.chatterMessageService.postAuditMessageOnUpdate(p.after, { name: p.modelName } as any, p.before, (p.updatedColumnNames || []).map(n => ({ propertyName: n })));
39
+ await this.chatterMessageService.postAuditMessageOnUpdate(
40
+ p.after,
41
+ p.modelName,
42
+ p.before,
43
+ (p.updatedColumnNames || []).map(n => ({ propertyName: n })),
44
+ false,
45
+ p.userId,
46
+ );
40
47
  break;
41
48
  case 'delete':
42
- await this.chatterMessageService.postAuditMessageOnDelete(p.before, { name: p.modelName } as any, p.before);
49
+ await this.chatterMessageService.postAuditMessageOnDelete(p.modelName, p.before, false, p.userId);
43
50
  break;
44
51
  }
45
52
  }
@@ -56,7 +56,7 @@ export class SecurityRuleRepository extends SolidBaseRepository<SecurityRule> {
56
56
 
57
57
  evaluatedRules.push(evaluatedRule);
58
58
 
59
- } catch (error) {
59
+ } catch (error: any) {
60
60
  this.logger.error(`Error parsing security rule: ${rule.securityRuleConfig}`, error);
61
61
  this.logger.error(error.stack);
62
62
  throw error;
@@ -238,7 +238,7 @@ export class ModuleMetadataSeederService {
238
238
 
239
239
  //FIXME: Handle displaying the created users credentials in a better way.
240
240
  // this.logger.log(`Newly created username is: ${usersDetail?.length > 0 ? usersDetail[0]?.username : ''} and password is ${usersDetail?.length > 0 ? usersDetail[0]?.password : ''}`);
241
- } catch (error) {
241
+ } catch (error: any) {
242
242
  this.logSeedFailureForCli(error, {
243
243
  moduleName: currentModule,
244
244
  step: currentStep,
@@ -463,7 +463,7 @@ export class ModuleMetadataSeederService {
463
463
  await this.createPermissionIfNotExists(permissionName);
464
464
  }
465
465
 
466
- } catch (error) {
466
+ } catch (error: any) {
467
467
  this.logger.error(error);
468
468
  }
469
469
  }
@@ -544,7 +544,7 @@ export class ModuleMetadataSeederService {
544
544
  moduleRoot = path.dirname(
545
545
  require.resolve('@solidxai/core/package.json'),
546
546
  );
547
- } catch (err) {
547
+ } catch (err: any) {
548
548
  this.logger.debug(
549
549
  'Could not resolve @solidxai/core from node_modules, assuming local execution',
550
550
  );
@@ -610,7 +610,7 @@ export class ModuleMetadataSeederService {
610
610
  moduleRoot = path.dirname(
611
611
  require.resolve('@solidxai/core/package.json'),
612
612
  );
613
- } catch (err) {
613
+ } catch (err: any) {
614
614
  this.logger.debug(
615
615
  'Could not resolve @solidxai/core from node_modules, assuming local execution',
616
616
  );
@@ -24,6 +24,7 @@ import { TestingRoleSpec, TestingUserSpec } from 'src/testing/contracts/testing-
24
24
  @Injectable()
25
25
  export class ModuleTestDataService {
26
26
  private readonly logger = new Logger(ModuleTestDataService.name);
27
+ private static readonly TEARDOWN_RETRY_ATTEMPTS = 5;
27
28
 
28
29
  constructor(
29
30
  private readonly moduleRef: ModuleRef,
@@ -665,31 +666,122 @@ export class ModuleTestDataService {
665
666
  private async dropTestDatabaseObjects(databases: Record<string, string>): Promise<void> {
666
667
  const entries = Object.entries(databases);
667
668
  for (const [dsName, dbName] of entries) {
668
- const dataSource = this.resolveDataSourceByName(dsName);
669
- if (!dataSource.isInitialized) {
670
- await dataSource.initialize();
671
- }
669
+ await this.dropTestDatabaseObjectsWithRetry(dsName, dbName);
670
+ }
671
+ }
672
672
 
673
- console.log(`Dropping test database/schema "${dbName}" on datasource "${dsName}"...`);
673
+ private async dropTestDatabaseObjectsWithRetry(dsName: string, dbName: string): Promise<void> {
674
+ let lastError: unknown;
675
+
676
+ for (let attempt = 1; attempt <= ModuleTestDataService.TEARDOWN_RETRY_ATTEMPTS; attempt += 1) {
677
+ console.log(`Attempting to tear down "${dbName}" on datasource "${dsName}" (${attempt}/${ModuleTestDataService.TEARDOWN_RETRY_ATTEMPTS})...`);
674
678
 
675
- const queryRunner = dataSource.createQueryRunner();
676
679
  try {
677
- const type = dataSource.options.type;
678
- if (type === 'postgres') {
679
- await queryRunner.query(`DROP DATABASE IF EXISTS "${dbName}"`);
680
- } else if (type === 'mssql') {
681
- await this.dropMssqlSchema(queryRunner, dbName);
682
- } else if (type === 'mysql' || type === 'mariadb') {
683
- await queryRunner.query(`DROP DATABASE IF EXISTS \`${dbName}\``);
684
- } else {
685
- throw new Error(`Unsupported database type for test data deletion: ${type}`);
680
+ await this.dropSingleTestDatabaseObject(dsName, dbName);
681
+ return;
682
+ } catch (error) {
683
+ lastError = error;
684
+ if (attempt >= ModuleTestDataService.TEARDOWN_RETRY_ATTEMPTS) {
685
+ throw error;
686
686
  }
687
+
688
+ await this.sleep(this.teardownRetryDelayMs(attempt));
689
+ }
690
+ }
691
+
692
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
693
+ }
694
+
695
+ private teardownRetryDelayMs(attempt: number): number {
696
+ const baseMs = 500;
697
+ const incrementMs = 350;
698
+ const jitterMs = Math.floor(Math.random() * 250);
699
+ return baseMs + ((attempt - 1) * incrementMs) + jitterMs;
700
+ }
701
+
702
+ private async sleep(ms: number): Promise<void> {
703
+ await new Promise((resolve) => setTimeout(resolve, ms));
704
+ }
705
+
706
+ private async dropSingleTestDatabaseObject(dsName: string, dbName: string): Promise<void> {
707
+ const dataSource = this.resolveDataSourceByName(dsName);
708
+
709
+ if (dataSource.options.type === 'postgres') {
710
+ await this.dropPostgresDatabase(dataSource, dbName);
711
+ return;
712
+ }
713
+
714
+ if (!dataSource.isInitialized) {
715
+ await dataSource.initialize();
716
+ }
717
+
718
+ const queryRunner = dataSource.createQueryRunner();
719
+ try {
720
+ const type = dataSource.options.type;
721
+ if (type === 'mssql') {
722
+ await this.dropMssqlSchema(queryRunner, dbName);
723
+ } else if (type === 'mysql' || type === 'mariadb') {
724
+ await queryRunner.query(`DROP DATABASE IF EXISTS \`${dbName}\``);
725
+ } else {
726
+ throw new Error(`Unsupported database type for test data deletion: ${type}`);
727
+ }
728
+ } finally {
729
+ await queryRunner.release();
730
+ }
731
+ }
732
+
733
+ private async dropPostgresDatabase(dataSource: DataSource, dbName: string): Promise<void> {
734
+ if (dataSource.isInitialized) {
735
+ await dataSource.destroy();
736
+ }
737
+
738
+ const adminDataSource = new DataSource({
739
+ ...(dataSource.options as any),
740
+ database: this.resolvePostgresMaintenanceDatabase(dataSource),
741
+ name: `${String(dataSource.name ?? 'default')}_teardown_admin_${Date.now()}`,
742
+ synchronize: false,
743
+ migrationsRun: false,
744
+ entities: [],
745
+ subscribers: [],
746
+ migrations: [],
747
+ });
748
+
749
+ try {
750
+ await adminDataSource.initialize();
751
+ const queryRunner = adminDataSource.createQueryRunner();
752
+ try {
753
+ await queryRunner.query(
754
+ `SELECT pg_terminate_backend(pid)
755
+ FROM pg_stat_activity
756
+ WHERE datname = $1
757
+ AND pid <> pg_backend_pid()`,
758
+ [dbName],
759
+ );
760
+ await queryRunner.query(`DROP DATABASE IF EXISTS "${dbName}"`);
687
761
  } finally {
688
762
  await queryRunner.release();
689
763
  }
764
+ } finally {
765
+ if (adminDataSource.isInitialized) {
766
+ await adminDataSource.destroy();
767
+ }
690
768
  }
691
769
  }
692
770
 
771
+ private resolvePostgresMaintenanceDatabase(dataSource: DataSource): string {
772
+ const configured = process.env.POSTGRES_MAINTENANCE_DATABASE?.trim();
773
+ if (configured) {
774
+ return configured;
775
+ }
776
+
777
+ const currentDb = String((dataSource.options as any)?.database ?? '').trim();
778
+ if (currentDb && currentDb !== 'postgres') {
779
+ return 'postgres';
780
+ }
781
+
782
+ return 'template1';
783
+ }
784
+
693
785
  private async dropMssqlSchema(queryRunner: ReturnType<DataSource['createQueryRunner']>, schemaName: string): Promise<void> {
694
786
  const foreignKeys: Array<{ fk_name: string; table_name: string }> = await queryRunner.query(
695
787
  `SELECT fk.name AS fk_name, t.name AS table_name
@@ -52,7 +52,7 @@ export class PermissionMetadataSeederService {
52
52
  }
53
53
  }
54
54
 
55
- } catch (error) {
55
+ } catch (error: any) {
56
56
  this.logger.error(error);
57
57
  }
58
58
  }