@solidxai/core 0.1.10 → 0.1.11-beta.0

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 (113) 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/seeders/seed-data/solid-core-metadata.json +21 -0
  26. package/dist/services/authentication.service.js +1 -1
  27. package/dist/services/authentication.service.js.map +1 -1
  28. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.d.ts.map +1 -1
  29. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js +2 -2
  30. package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js.map +1 -1
  31. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.d.ts.map +1 -1
  32. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js +2 -2
  33. package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js.map +1 -1
  34. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts +3 -0
  35. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts.map +1 -1
  36. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js +71 -0
  37. package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js.map +1 -1
  38. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.d.ts.map +1 -1
  39. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js +3 -3
  40. package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js.map +1 -1
  41. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts +11 -0
  42. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -0
  43. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +181 -0
  44. package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -0
  45. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts +11 -0
  46. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -0
  47. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +90 -0
  48. package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -0
  49. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts +11 -0
  50. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -0
  51. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +156 -0
  52. package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -0
  53. package/dist/services/datasource-introspection.service.d.ts +288 -0
  54. package/dist/services/datasource-introspection.service.d.ts.map +1 -0
  55. package/dist/services/datasource-introspection.service.js +1278 -0
  56. package/dist/services/datasource-introspection.service.js.map +1 -0
  57. package/dist/services/datasource-management.service.d.ts +60 -0
  58. package/dist/services/datasource-management.service.d.ts.map +1 -0
  59. package/dist/services/datasource-management.service.js +461 -0
  60. package/dist/services/datasource-management.service.js.map +1 -0
  61. package/dist/services/field-metadata.service.d.ts.map +1 -1
  62. package/dist/services/field-metadata.service.js +19 -0
  63. package/dist/services/field-metadata.service.js.map +1 -1
  64. package/dist/services/model-metadata.service.d.ts +1 -3
  65. package/dist/services/model-metadata.service.d.ts.map +1 -1
  66. package/dist/services/model-metadata.service.js +47 -15
  67. package/dist/services/model-metadata.service.js.map +1 -1
  68. package/dist/services/role-metadata.service.d.ts +1 -0
  69. package/dist/services/role-metadata.service.d.ts.map +1 -1
  70. package/dist/services/role-metadata.service.js +13 -0
  71. package/dist/services/role-metadata.service.js.map +1 -1
  72. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.d.ts.map +1 -1
  73. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js +2 -3
  74. package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js.map +1 -1
  75. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.d.ts.map +1 -1
  76. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js +2 -3
  77. package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js.map +1 -1
  78. package/dist/services/setting.service.d.ts +1 -0
  79. package/dist/services/setting.service.d.ts.map +1 -1
  80. package/dist/services/setting.service.js +32 -8
  81. package/dist/services/setting.service.js.map +1 -1
  82. package/dist/services/solid-ts-morph.service.d.ts +1 -1
  83. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  84. package/dist/services/solid-ts-morph.service.js.map +1 -1
  85. package/dist/solid-core.module.d.ts.map +1 -1
  86. package/dist/solid-core.module.js +16 -0
  87. package/dist/solid-core.module.js.map +1 -1
  88. package/package.json +1 -1
  89. package/src/controllers/datasource-introspection.controller.ts +58 -0
  90. package/src/controllers/datasource-management.controller.ts +24 -0
  91. package/src/dtos/create-datasource-management.dto.ts +139 -0
  92. package/src/dtos/datasource-introspection-mapping.dto.ts +182 -0
  93. package/src/index.ts +5 -0
  94. package/src/interfaces/datasource-introspection-provider.interface.ts +28 -0
  95. package/src/seeders/seed-data/solid-core-metadata.json +22 -1
  96. package/src/services/authentication.service.ts +1 -1
  97. package/src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts +9 -4
  98. package/src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts +9 -4
  99. package/src/services/dashboard-providers/mq-dashboard-provider-utils.ts +82 -0
  100. package/src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts +10 -4
  101. package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +185 -0
  102. package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +95 -0
  103. package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +160 -0
  104. package/src/services/datasource-introspection.service.ts +1536 -0
  105. package/src/services/datasource-management.service.ts +566 -0
  106. package/src/services/field-metadata.service.ts +21 -1
  107. package/src/services/model-metadata.service.ts +50 -13
  108. package/src/services/role-metadata.service.ts +14 -0
  109. package/src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts +2 -4
  110. package/src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts +2 -4
  111. package/src/services/setting.service.ts +43 -12
  112. package/src/services/solid-ts-morph.service.ts +2 -2
  113. package/src/solid-core.module.ts +16 -0
@@ -0,0 +1,58 @@
1
+ import { Body, Controller, Get, Param, ParseIntPipe, Post, Query } from "@nestjs/common";
2
+ import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
3
+ import { DatasourceIntrospectionMappingDto } from "../dtos/datasource-introspection-mapping.dto";
4
+ import { DatasourceIntrospectionService } from "../services/datasource-introspection.service";
5
+
6
+ @Controller("datasource-introspection")
7
+ @ApiTags("Solid Core")
8
+ export class DatasourceIntrospectionController {
9
+ constructor(
10
+ private readonly datasourceIntrospectionService: DatasourceIntrospectionService,
11
+ ) { }
12
+
13
+ @ApiBearerAuth("jwt")
14
+ @Get("modules/:moduleId/bootstrap")
15
+ getBootstrap(
16
+ @Param("moduleId", ParseIntPipe) moduleId: number,
17
+ ) {
18
+ return this.datasourceIntrospectionService.getBootstrap(moduleId);
19
+ }
20
+
21
+ @ApiBearerAuth("jwt")
22
+ @Get("modules/:moduleId/tables")
23
+ getTables(
24
+ @Param("moduleId", ParseIntPipe) moduleId: number,
25
+ @Query("datasource") datasourceName: string,
26
+ ) {
27
+ return this.datasourceIntrospectionService.getTables(moduleId, datasourceName);
28
+ }
29
+
30
+ @ApiBearerAuth("jwt")
31
+ @Get("modules/:moduleId/table-detail")
32
+ getTableDetail(
33
+ @Param("moduleId", ParseIntPipe) moduleId: number,
34
+ @Query("datasource") datasourceName: string,
35
+ @Query("table") tableName: string,
36
+ @Query("schema") schema?: string,
37
+ ) {
38
+ return this.datasourceIntrospectionService.getTableDetail(moduleId, datasourceName, tableName, schema);
39
+ }
40
+
41
+ @ApiBearerAuth("jwt")
42
+ @Post("modules/:moduleId/mapping-preview")
43
+ previewMapping(
44
+ @Param("moduleId", ParseIntPipe) moduleId: number,
45
+ @Body() mappingDto: DatasourceIntrospectionMappingDto,
46
+ ) {
47
+ return this.datasourceIntrospectionService.previewMapping(moduleId, mappingDto);
48
+ }
49
+
50
+ @ApiBearerAuth("jwt")
51
+ @Post("modules/:moduleId/apply-mapping")
52
+ applyMapping(
53
+ @Param("moduleId", ParseIntPipe) moduleId: number,
54
+ @Body() mappingDto: DatasourceIntrospectionMappingDto,
55
+ ) {
56
+ return this.datasourceIntrospectionService.applyMapping(moduleId, mappingDto);
57
+ }
58
+ }
@@ -0,0 +1,24 @@
1
+ import { Body, Controller, Get, Post } from "@nestjs/common";
2
+ import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
3
+ import { CreateDatasourceManagementDto } from "../dtos/create-datasource-management.dto";
4
+ import { DatasourceManagementService } from "../services/datasource-management.service";
5
+
6
+ @Controller("datasource-management")
7
+ @ApiTags("Solid Core")
8
+ export class DatasourceManagementController {
9
+ constructor(
10
+ private readonly datasourceManagementService: DatasourceManagementService,
11
+ ) { }
12
+
13
+ @ApiBearerAuth("jwt")
14
+ @Get()
15
+ findMany() {
16
+ return this.datasourceManagementService.findMany();
17
+ }
18
+
19
+ @ApiBearerAuth("jwt")
20
+ @Post()
21
+ create(@Body() createDto: CreateDatasourceManagementDto) {
22
+ return this.datasourceManagementService.create(createDto);
23
+ }
24
+ }
@@ -0,0 +1,139 @@
1
+ import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
2
+ import { Type } from "class-transformer";
3
+ import {
4
+ IsBoolean,
5
+ IsIn,
6
+ IsInt,
7
+ IsOptional,
8
+ IsString,
9
+ Matches,
10
+ Max,
11
+ Min,
12
+ } from "class-validator";
13
+ import { DatasourceType } from "./create-model-metadata.dto";
14
+
15
+ export class CreateDatasourceManagementDto {
16
+ @ApiProperty({ description: "Logical datasource key used in generated filenames and env prefixes." })
17
+ @IsString()
18
+ @Matches(/^[a-z][a-z0-9-]*$/, {
19
+ message: "Datasource name must start with a lower-case letter and use only lower-case letters, numbers, or hyphens.",
20
+ })
21
+ name: string;
22
+
23
+ @ApiPropertyOptional({ description: "Human friendly label shown in the admin interface." })
24
+ @IsOptional()
25
+ @IsString()
26
+ displayName?: string;
27
+
28
+ @ApiProperty({ enum: [DatasourceType.postgres, DatasourceType.mysql, DatasourceType.mssql] })
29
+ @IsIn([DatasourceType.postgres, DatasourceType.mysql, DatasourceType.mssql])
30
+ type: DatasourceType;
31
+
32
+ @ApiProperty()
33
+ @IsString()
34
+ host: string;
35
+
36
+ @ApiProperty()
37
+ @Type(() => Number)
38
+ @IsInt()
39
+ @Min(1)
40
+ @Max(65535)
41
+ port: number;
42
+
43
+ @ApiProperty()
44
+ @IsString()
45
+ database: string;
46
+
47
+ @ApiProperty()
48
+ @IsString()
49
+ username: string;
50
+
51
+ @ApiProperty()
52
+ @IsString()
53
+ password: string;
54
+
55
+ @ApiPropertyOptional()
56
+ @IsOptional()
57
+ @Type(() => Boolean)
58
+ @IsBoolean()
59
+ synchronize?: boolean;
60
+
61
+ @ApiPropertyOptional()
62
+ @IsOptional()
63
+ @Type(() => Boolean)
64
+ @IsBoolean()
65
+ logging?: boolean;
66
+
67
+ @ApiPropertyOptional()
68
+ @IsOptional()
69
+ @Type(() => Boolean)
70
+ @IsBoolean()
71
+ ssl?: boolean;
72
+
73
+ @ApiPropertyOptional()
74
+ @IsOptional()
75
+ @Type(() => Boolean)
76
+ @IsBoolean()
77
+ sslRejectUnauthorized?: boolean;
78
+
79
+ @ApiPropertyOptional()
80
+ @IsOptional()
81
+ @Type(() => Number)
82
+ @IsInt()
83
+ @Min(0)
84
+ poolMax?: number;
85
+
86
+ @ApiPropertyOptional()
87
+ @IsOptional()
88
+ @Type(() => Number)
89
+ @IsInt()
90
+ @Min(0)
91
+ connectionTimeoutMs?: number;
92
+
93
+ @ApiPropertyOptional()
94
+ @IsOptional()
95
+ @Type(() => Number)
96
+ @IsInt()
97
+ @Min(0)
98
+ idleTimeoutMs?: number;
99
+
100
+ @ApiPropertyOptional()
101
+ @IsOptional()
102
+ @Type(() => Number)
103
+ @IsInt()
104
+ @Min(0)
105
+ statementTimeoutMs?: number;
106
+
107
+ @ApiPropertyOptional()
108
+ @IsOptional()
109
+ @Type(() => Number)
110
+ @IsInt()
111
+ @Min(0)
112
+ idleInTxTimeoutMs?: number;
113
+
114
+ @ApiPropertyOptional()
115
+ @IsOptional()
116
+ @Type(() => Number)
117
+ @IsInt()
118
+ @Min(0)
119
+ retryAttempts?: number;
120
+
121
+ @ApiPropertyOptional()
122
+ @IsOptional()
123
+ @Type(() => Number)
124
+ @IsInt()
125
+ @Min(0)
126
+ retryDelayMs?: number;
127
+
128
+ @ApiPropertyOptional()
129
+ @IsOptional()
130
+ @Type(() => Boolean)
131
+ @IsBoolean()
132
+ encrypt?: boolean;
133
+
134
+ @ApiPropertyOptional()
135
+ @IsOptional()
136
+ @Type(() => Boolean)
137
+ @IsBoolean()
138
+ trustServerCertificate?: boolean;
139
+ }
@@ -0,0 +1,182 @@
1
+ import { ApiProperty } from "@nestjs/swagger";
2
+ import { Type } from "class-transformer";
3
+ import {
4
+ IsArray,
5
+ IsBoolean,
6
+ IsEnum,
7
+ IsInt,
8
+ IsObject,
9
+ IsOptional,
10
+ IsString,
11
+ ValidateNested,
12
+ } from "class-validator";
13
+ import { OrmType, SolidFieldType } from "./create-field-metadata.dto";
14
+ import { LegacyTableType } from "src/enums/legacy-table-type.enum";
15
+
16
+ export class DatasourceIntrospectionMappingColumnDto {
17
+ @ApiProperty()
18
+ @IsString()
19
+ columnName: string;
20
+
21
+ @ApiProperty()
22
+ @IsString()
23
+ fieldName: string;
24
+
25
+ @ApiProperty()
26
+ @IsString()
27
+ dataType: string;
28
+
29
+ @ApiProperty({ enum: SolidFieldType })
30
+ @IsEnum(SolidFieldType)
31
+ solidFieldType: SolidFieldType;
32
+
33
+ @ApiProperty()
34
+ @IsString()
35
+ ormType: OrmType;
36
+
37
+ @ApiProperty()
38
+ @IsBoolean()
39
+ nullable: boolean;
40
+
41
+ @ApiProperty({ required: false, nullable: true })
42
+ @IsOptional()
43
+ defaultValue?: string | null;
44
+
45
+ @ApiProperty({ required: false, nullable: true })
46
+ @IsOptional()
47
+ @IsInt()
48
+ characterMaximumLength?: number | null;
49
+
50
+ @ApiProperty({ required: false, nullable: true })
51
+ @IsOptional()
52
+ @IsInt()
53
+ numericPrecision?: number | null;
54
+
55
+ @ApiProperty({ required: false, nullable: true })
56
+ @IsOptional()
57
+ @IsInt()
58
+ numericScale?: number | null;
59
+
60
+ @ApiProperty({ required: false, nullable: true })
61
+ @IsOptional()
62
+ @IsInt()
63
+ ordinalPosition?: number | null;
64
+
65
+ @ApiProperty()
66
+ @IsBoolean()
67
+ isAutoGenerated: boolean;
68
+
69
+ @ApiProperty()
70
+ @IsBoolean()
71
+ handledBySuperclass: boolean;
72
+
73
+ @ApiProperty({ required: false, nullable: true })
74
+ @IsOptional()
75
+ @IsString()
76
+ superclassFieldName?: string | null;
77
+
78
+ @ApiProperty({ required: false, nullable: true })
79
+ @IsOptional()
80
+ @IsInt()
81
+ fieldId?: number | null;
82
+
83
+ @ApiProperty()
84
+ @IsBoolean()
85
+ include: boolean;
86
+
87
+ @ApiProperty()
88
+ @IsBoolean()
89
+ matched: boolean;
90
+
91
+ @ApiProperty()
92
+ @IsBoolean()
93
+ isPrimaryKey: boolean;
94
+ }
95
+
96
+ export class DatasourceIntrospectionMappingDto {
97
+ @ApiProperty()
98
+ @IsBoolean()
99
+ mapped: boolean;
100
+
101
+ @ApiProperty({ required: false, nullable: true })
102
+ @IsOptional()
103
+ @IsInt()
104
+ modelId?: number | null;
105
+
106
+ @ApiProperty()
107
+ @IsString()
108
+ singularName: string;
109
+
110
+ @ApiProperty()
111
+ @IsString()
112
+ pluralName: string;
113
+
114
+ @ApiProperty()
115
+ @IsString()
116
+ displayName: string;
117
+
118
+ @ApiProperty()
119
+ @IsString()
120
+ description: string;
121
+
122
+ @ApiProperty()
123
+ @IsString()
124
+ tableName: string;
125
+
126
+ @ApiProperty({ required: false, nullable: true })
127
+ @IsOptional()
128
+ @IsString()
129
+ schema?: string | null;
130
+
131
+ @ApiProperty()
132
+ @IsString()
133
+ dataSource: string;
134
+
135
+ @ApiProperty()
136
+ @IsString()
137
+ dataSourceType: string;
138
+
139
+ @ApiProperty({ enum: LegacyTableType })
140
+ @IsEnum(LegacyTableType)
141
+ legacyTableType: LegacyTableType;
142
+
143
+ @ApiProperty()
144
+ @IsString()
145
+ baseClassName: string;
146
+
147
+ @ApiProperty()
148
+ @IsString()
149
+ userKeyField: string;
150
+
151
+ @ApiProperty()
152
+ @IsBoolean()
153
+ enableAuditTracking: boolean;
154
+
155
+ @ApiProperty()
156
+ @IsBoolean()
157
+ enableSoftDelete: boolean;
158
+
159
+ @ApiProperty()
160
+ @IsBoolean()
161
+ draftPublishWorkflow: boolean;
162
+
163
+ @ApiProperty()
164
+ @IsBoolean()
165
+ internationalisation: boolean;
166
+
167
+ @ApiProperty({ required: false, nullable: true })
168
+ @IsOptional()
169
+ @IsInt()
170
+ plannedMigrationTimestamp?: number | null;
171
+
172
+ @ApiProperty({ type: () => [DatasourceIntrospectionMappingColumnDto] })
173
+ @IsArray()
174
+ @ValidateNested({ each: true })
175
+ @Type(() => DatasourceIntrospectionMappingColumnDto)
176
+ columns: DatasourceIntrospectionMappingColumnDto[];
177
+
178
+ @ApiProperty({ required: false, type: "object" })
179
+ @IsOptional()
180
+ @IsObject()
181
+ reviewedModel?: Record<string, any>;
182
+ }
package/src/index.ts CHANGED
@@ -62,6 +62,7 @@ export * from './dtos/create-view-metadata.dto'
62
62
  export * from './dtos/create-chatter-message.dto'
63
63
  export * from './dtos/create-chatter-message-details.dto'
64
64
  export * from './dtos/create-locale.dto'
65
+ export * from './dtos/create-datasource-management.dto'
65
66
  export * from './dtos/fetch-roles.dto'
66
67
  export * from './dtos/initiate-forgot-password.dto'
67
68
  export * from './dtos/mutate-role-permissions.dto'
@@ -334,7 +335,11 @@ export * from './services/whatsapp/GupshupOtpWhatsappService'
334
335
  export * from './services/setting.service'
335
336
  export * from './services/encryption.service'
336
337
  export * from './services/info.service'
338
+ export * from './services/datasource-management.service'
339
+ export * from './services/datasource-introspection.service'
337
340
  export * from './controllers/info.controller'
341
+ export * from './controllers/datasource-management.controller'
342
+ export * from './controllers/datasource-introspection.controller'
338
343
  export * from './controllers/module-metadata-explorer.controller'
339
344
  export * from './controllers/module-package.controller'
340
345
  export * from './services/settings/default-settings-provider.service'
@@ -0,0 +1,28 @@
1
+ import { DataSource } from "typeorm";
2
+
3
+ export type DatasourceIntrospectionTableRef = {
4
+ tableSchema: string | null;
5
+ tableName: string;
6
+ };
7
+
8
+ export type DatasourceIntrospectionColumn = {
9
+ tableSchema: string | null;
10
+ tableName: string;
11
+ columnName: string;
12
+ dataType: string;
13
+ isAutoGenerated: boolean;
14
+ isNullable: boolean;
15
+ defaultValue: string | null;
16
+ characterMaximumLength: number | null;
17
+ numericPrecision: number | null;
18
+ numericScale: number | null;
19
+ ordinalPosition: number | null;
20
+ };
21
+
22
+ export interface DatasourceIntrospectionProvider {
23
+ readonly type: string;
24
+ supports(type: string): boolean;
25
+ listTables(dataSource: DataSource): Promise<DatasourceIntrospectionTableRef[]>;
26
+ listColumns(dataSource: DataSource): Promise<DatasourceIntrospectionColumn[]>;
27
+ getTableDefinition(dataSource: DataSource, table: DatasourceIntrospectionTableRef): Promise<string | null>;
28
+ }
@@ -5381,6 +5381,19 @@
5381
5381
  "moduleUserKey": "solid-core",
5382
5382
  "modelUserKey": "fieldMetadata"
5383
5383
  },
5384
+ {
5385
+ "displayName": "Datasource Management",
5386
+ "name": "datasource-management-action",
5387
+ "type": "custom",
5388
+ "domain": "",
5389
+ "context": "",
5390
+ "customComponent": "/admin/core/solid-core/datasources",
5391
+ "customIsModal": true,
5392
+ "serverEndpoint": "",
5393
+ "viewUserKey": "",
5394
+ "moduleUserKey": "solid-core",
5395
+ "modelUserKey": "moduleMetadata"
5396
+ },
5384
5397
  {
5385
5398
  "displayName": "Field Metadata Tree Action",
5386
5399
  "name": "fieldMetadata-tree-action",
@@ -6105,6 +6118,14 @@
6105
6118
  "moduleUserKey": "solid-core",
6106
6119
  "parentMenuItemUserKey": "appBuilder-menu-item"
6107
6120
  },
6121
+ {
6122
+ "displayName": "Datasources",
6123
+ "name": "datasource-management-menu-item",
6124
+ "sequenceNumber": 4,
6125
+ "actionUserKey": "datasource-management-action",
6126
+ "moduleUserKey": "solid-core",
6127
+ "parentMenuItemUserKey": "appBuilder-menu-item"
6128
+ },
6108
6129
  {
6109
6130
  "displayName": "Menu Item",
6110
6131
  "name": "menuItemMetadata-menu-item",
@@ -14737,4 +14758,4 @@
14737
14758
  }
14738
14759
  ],
14739
14760
  "savedFilters": []
14740
- }
14761
+ }
@@ -309,7 +309,7 @@ export class AuthenticationService {
309
309
  if (signUpDto.roles && signUpDto.roles.length > 0) {
310
310
  for (let i = 0; i < signUpDto.roles.length; i++) {
311
311
  const roleName = signUpDto.roles[i];
312
- await this.roleMetadataService.findRoleByName(roleName);
312
+ await this.roleMetadataService.assertRoleExistsByName(roleName);
313
313
  }
314
314
  }
315
315
  user.username = signUpDto.username;
@@ -2,7 +2,13 @@ import { Injectable } from "@nestjs/common";
2
2
  import { DashboardWidgetDataProvider } from "src/decorators/dashboard-widget-data-provider.decorator";
3
3
  import { MqMessageRepository } from "src/repository/mq-message.repository";
4
4
  import { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from "src/interfaces";
5
- import { applyMqDashboardFilters, normalizeBucket, toNumber } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
5
+ import {
6
+ applyMqDashboardFilters,
7
+ buildMqDashboardBucketExpression,
8
+ normalizeBucket,
9
+ normalizeMqDashboardBucketValue,
10
+ toNumber,
11
+ } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
6
12
 
7
13
  @DashboardWidgetDataProvider()
8
14
  @Injectable()
@@ -29,7 +35,7 @@ export class MqDashboardLatencyTrendProvider implements IDashboardWidgetDataProv
29
35
  applyMqDashboardFilters(qb, ctxt.variables ?? {});
30
36
  qb.andWhere("mqMessage.elapsedMillis IS NOT NULL");
31
37
 
32
- const bucketExpr = `DATE_TRUNC('${bucket}', mqMessage.createdAt)`;
38
+ const bucketExpr = buildMqDashboardBucketExpression(qb, bucket, "mqMessage.createdAt");
33
39
  const rows = await qb
34
40
  .select(bucketExpr, "bucket")
35
41
  .addSelect("AVG(mqMessage.elapsedMillis)", "value")
@@ -37,7 +43,7 @@ export class MqDashboardLatencyTrendProvider implements IDashboardWidgetDataProv
37
43
  .orderBy("bucket", "ASC")
38
44
  .getRawMany<{ bucket: string; value: string | number }>();
39
45
 
40
- const categories = rows.map((r) => new Date(r.bucket).toISOString());
46
+ const categories = rows.map((r) => normalizeMqDashboardBucketValue(r.bucket));
41
47
  const values = rows.map((r) => Number(toNumber(r.value).toFixed(2)));
42
48
 
43
49
  return {
@@ -55,4 +61,3 @@ export class MqDashboardLatencyTrendProvider implements IDashboardWidgetDataProv
55
61
  };
56
62
  }
57
63
  }
58
-
@@ -2,7 +2,13 @@ import { Injectable } from "@nestjs/common";
2
2
  import { DashboardWidgetDataProvider } from "src/decorators/dashboard-widget-data-provider.decorator";
3
3
  import { MqMessageRepository } from "src/repository/mq-message.repository";
4
4
  import { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from "src/interfaces";
5
- import { applyMqDashboardFilters, normalizeBucket, toNumber } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
5
+ import {
6
+ applyMqDashboardFilters,
7
+ buildMqDashboardBucketExpression,
8
+ normalizeBucket,
9
+ normalizeMqDashboardBucketValue,
10
+ toNumber,
11
+ } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
6
12
 
7
13
  @DashboardWidgetDataProvider()
8
14
  @Injectable()
@@ -31,7 +37,7 @@ export class MqDashboardMessagesOverTimeProvider implements IDashboardWidgetData
31
37
  const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder("mqMessage");
32
38
  applyMqDashboardFilters(qb, ctxt.variables ?? {});
33
39
 
34
- const bucketExpr = `DATE_TRUNC('${bucket}', mqMessage.createdAt)`;
40
+ const bucketExpr = buildMqDashboardBucketExpression(qb, bucket, "mqMessage.createdAt");
35
41
  const rows = await qb
36
42
  .select(bucketExpr, "bucket")
37
43
  .addSelect("mqMessage.stage", "stage")
@@ -43,7 +49,7 @@ export class MqDashboardMessagesOverTimeProvider implements IDashboardWidgetData
43
49
 
44
50
  const bucketToStageMap = new Map<string, Record<string, number>>();
45
51
  for (const row of rows) {
46
- const key = new Date(row.bucket).toISOString();
52
+ const key = normalizeMqDashboardBucketValue(row.bucket);
47
53
  const entry = bucketToStageMap.get(key) ?? {};
48
54
  entry[row.stage] = (entry[row.stage] ?? 0) + toNumber(row.count, 0);
49
55
  bucketToStageMap.set(key, entry);
@@ -76,4 +82,3 @@ export class MqDashboardMessagesOverTimeProvider implements IDashboardWidgetData
76
82
  };
77
83
  }
78
84
  }
79
-
@@ -54,6 +54,59 @@ export function toNumber(value: any, fallback = 0): number {
54
54
  return Number.isFinite(n) ? n : fallback;
55
55
  }
56
56
 
57
+ export function buildMqDashboardBucketExpression(
58
+ qb: SelectQueryBuilder<MqMessage>,
59
+ bucket: 'hour' | 'day' | 'week' | 'month',
60
+ columnExpr: string,
61
+ ): string {
62
+ const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();
63
+
64
+ switch (driver) {
65
+ case 'postgres':
66
+ case 'cockroachdb':
67
+ return `DATE_TRUNC('${bucket}', ${columnExpr})`;
68
+ case 'mysql':
69
+ case 'mariadb':
70
+ switch (bucket) {
71
+ case 'hour':
72
+ return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d %H:00:00')`;
73
+ case 'day':
74
+ return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d 00:00:00')`;
75
+ case 'week':
76
+ return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;
77
+ case 'month':
78
+ return `DATE_FORMAT(${columnExpr}, '%Y-%m-01 00:00:00')`;
79
+ default:
80
+ throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);
81
+ }
82
+ case 'mssql':
83
+ case 'sqlserver':
84
+ switch (bucket) {
85
+ case 'hour':
86
+ return `DATEADD(hour, DATEDIFF(hour, 0, ${columnExpr}), 0)`;
87
+ case 'day':
88
+ return `DATEADD(day, DATEDIFF(day, 0, ${columnExpr}), 0)`;
89
+ case 'week':
90
+ return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;
91
+ case 'month':
92
+ return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;
93
+ default:
94
+ throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);
95
+ }
96
+ default:
97
+ throw new Error(`Unsupported driver ${driver} for mq dashboard bucket expressions.`);
98
+ }
99
+ }
100
+
101
+ export function normalizeMqDashboardBucketValue(value: any): string {
102
+ if (!value) return '';
103
+ const parsed = value instanceof Date ? value : new Date(value);
104
+ if (Number.isNaN(parsed.getTime())) {
105
+ return `${value}`;
106
+ }
107
+ return parsed.toISOString();
108
+ }
109
+
57
110
 
58
111
  function applyDateFilter(qb: SelectQueryBuilder<MqMessage>, dateVariable: any): void {
59
112
  const range = resolveDateRange(dateVariable);
@@ -88,6 +141,35 @@ function applyStringOrArrayFilter(
88
141
  qb.andWhere(`${qualifiedColumn} IN (:...${paramKey})`, { [paramKey]: values });
89
142
  }
90
143
 
144
+ export function applyCaseInsensitiveContainsFilter<T>(
145
+ qb: SelectQueryBuilder<T>,
146
+ qualifiedColumn: string,
147
+ query: string | undefined,
148
+ paramKey: string,
149
+ ) {
150
+ if (!query) {
151
+ return;
152
+ }
153
+
154
+ const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();
155
+ const value = `%${query}%`;
156
+
157
+ switch (driver) {
158
+ case 'postgres':
159
+ case 'cockroachdb':
160
+ qb.andWhere(`${qualifiedColumn} ILIKE :${paramKey}`, { [paramKey]: value });
161
+ return;
162
+ case 'mysql':
163
+ case 'mariadb':
164
+ case 'mssql':
165
+ case 'sqlserver':
166
+ qb.andWhere(`LOWER(${qualifiedColumn}) LIKE LOWER(:${paramKey})`, { [paramKey]: value });
167
+ return;
168
+ default:
169
+ qb.andWhere(`${qualifiedColumn} LIKE :${paramKey}`, { [paramKey]: value });
170
+ }
171
+ }
172
+
91
173
  function resolveDateRange(dateVariable: any): { from?: Date; to?: Date } {
92
174
  if (!dateVariable) return {};
93
175