@solidxai/core 0.1.6-beta.9 → 0.1.7
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.
- package/.claude/settings.local.json +15 -0
- package/CHANGELOG.md +71 -0
- package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
- package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-layout.controller.js +204 -0
- package/dist/controllers/dashboard-layout.controller.js.map +1 -0
- package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
- package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-layout.dto.js +53 -0
- package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
- package/dist/dtos/create-dashboard-variable.dto.js +7 -1
- package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
- package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
- package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-layout.dto.js +53 -0
- package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
- package/dist/dtos/update-dashboard-variable.dto.js +7 -1
- package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
- package/dist/entities/action-metadata.entity.d.ts.map +1 -1
- package/dist/entities/action-metadata.entity.js.map +1 -1
- package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
- package/dist/entities/ai-interaction.entity.js +5 -4
- package/dist/entities/ai-interaction.entity.js.map +1 -1
- package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message-details.entity.js +4 -3
- package/dist/entities/chatter-message-details.entity.js.map +1 -1
- package/dist/entities/chatter-message.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message.entity.js +4 -3
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/entities/dashboard-layout.entity.d.ts +9 -0
- package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-layout.entity.js +41 -0
- package/dist/entities/dashboard-layout.entity.js.map +1 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
- package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question.entity.js +5 -4
- package/dist/entities/dashboard-question.entity.js.map +1 -1
- package/dist/entities/dashboard-variable.entity.d.ts +1 -0
- package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-variable.entity.js +10 -4
- package/dist/entities/dashboard-variable.entity.js.map +1 -1
- package/dist/entities/dashboard.entity.d.ts +2 -0
- package/dist/entities/dashboard.entity.d.ts.map +1 -1
- package/dist/entities/dashboard.entity.js +9 -3
- package/dist/entities/dashboard.entity.js.map +1 -1
- package/dist/entities/email-attachment.entity.d.ts.map +1 -1
- package/dist/entities/email-attachment.entity.js +2 -1
- package/dist/entities/email-attachment.entity.js.map +1 -1
- package/dist/entities/email-template.entity.js +1 -1
- package/dist/entities/email-template.entity.js.map +1 -1
- package/dist/entities/export-transaction.entity.d.ts.map +1 -1
- package/dist/entities/export-transaction.entity.js +2 -1
- package/dist/entities/export-transaction.entity.js.map +1 -1
- package/dist/entities/field-metadata.entity.js +2 -2
- package/dist/entities/field-metadata.entity.js.map +1 -1
- package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
- package/dist/entities/import-transaction-error-log.entity.js +3 -2
- package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
- package/dist/entities/import-transaction.entity.d.ts.map +1 -1
- package/dist/entities/import-transaction.entity.js +2 -1
- package/dist/entities/import-transaction.entity.js.map +1 -1
- package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
- package/dist/entities/mq-message-queue.entity.js.map +1 -1
- package/dist/entities/mq-message.entity.d.ts.map +1 -1
- package/dist/entities/mq-message.entity.js +5 -3
- package/dist/entities/mq-message.entity.js.map +1 -1
- package/dist/entities/saved-filters.entity.d.ts.map +1 -1
- package/dist/entities/saved-filters.entity.js +3 -2
- package/dist/entities/saved-filters.entity.js.map +1 -1
- package/dist/entities/security-rule.entity.d.ts.map +1 -1
- package/dist/entities/security-rule.entity.js +2 -1
- package/dist/entities/security-rule.entity.js.map +1 -1
- package/dist/entities/sms-template.entity.js +1 -1
- package/dist/entities/sms-template.entity.js.map +1 -1
- package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
- package/dist/entities/user-view-metadata.entity.js +2 -1
- package/dist/entities/user-view-metadata.entity.js.map +1 -1
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +2 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entities/view-metadata.entity.d.ts.map +1 -1
- package/dist/entities/view-metadata.entity.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts +14 -0
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
- package/dist/helpers/bootstrap.helper.js +132 -0
- package/dist/helpers/bootstrap.helper.js.map +1 -0
- package/dist/helpers/cache.helper.d.ts +2 -0
- package/dist/helpers/cache.helper.d.ts.map +1 -0
- package/dist/helpers/cache.helper.js +8 -0
- package/dist/helpers/cache.helper.js.map +1 -0
- package/dist/helpers/cors.helper.d.ts.map +1 -1
- package/dist/helpers/cors.helper.js +13 -4
- package/dist/helpers/cors.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +8 -9
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/helpers/solid-registry.d.ts +3 -0
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +7 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
- package/dist/helpers/typeorm-db-helper.js +21 -0
- package/dist/helpers/typeorm-db-helper.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +2 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/chatter-queue-options.js +1 -1
- package/dist/jobs/chatter-queue-options.js.map +1 -1
- package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
- package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
- package/dist/jobs/chatter-queue-publisher.service.js +5 -5
- package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
- package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
- package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
- package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
- package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
- package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
- package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-options-database.js +10 -0
- package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
- package/dist/repository/dashboard-layout.repository.d.ts +12 -0
- package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
- package/dist/repository/dashboard-layout.repository.js +34 -0
- package/dist/repository/dashboard-layout.repository.js.map +1 -0
- package/dist/repository/model-metadata.repository.d.ts +6 -1
- package/dist/repository/model-metadata.repository.d.ts.map +1 -1
- package/dist/repository/model-metadata.repository.js +41 -2
- package/dist/repository/model-metadata.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +4 -4
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +372 -32
- package/dist/services/chatter-message.service.d.ts +4 -4
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +33 -9
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
- package/dist/services/crud.service.js +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/dashboard-layout.service.d.ts +20 -0
- package/dist/services/dashboard-layout.service.d.ts.map +1 -0
- package/dist/services/dashboard-layout.service.js +120 -0
- package/dist/services/dashboard-layout.service.js.map +1 -0
- package/dist/services/dashboard.service.d.ts +2 -0
- package/dist/services/dashboard.service.d.ts.map +1 -1
- package/dist/services/dashboard.service.js +4 -0
- package/dist/services/dashboard.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +3 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +21 -2
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/permission-metadata.service.d.ts +5 -1
- package/dist/services/permission-metadata.service.d.ts.map +1 -1
- package/dist/services/permission-metadata.service.js +66 -20
- package/dist/services/permission-metadata.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +6 -1
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/publisher-factory.service.js +0 -1
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
- package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
- package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts +5 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +84 -9
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/request-context.service.d.ts +2 -1
- package/dist/services/request-context.service.d.ts.map +1 -1
- package/dist/services/request-context.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +20 -2
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/solid-introspect.service.d.ts +6 -1
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +27 -2
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.d.ts +9 -0
- package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
- package/dist/services/solid-ts-morph.service.js +76 -0
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +16 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +10 -7
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +58 -85
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
- package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
- package/dist/winston.logger.d.ts.map +1 -1
- package/dist/winston.logger.js +2 -1
- package/dist/winston.logger.js.map +1 -1
- package/package.json +3 -1
- package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
- package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
- package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
- package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
- package/src/controllers/dashboard-layout.controller.ts +106 -0
- package/src/dtos/create-dashboard-layout.dto.ts +31 -0
- package/src/dtos/create-dashboard-variable.dto.ts +4 -0
- package/src/dtos/update-dashboard-layout.dto.ts +30 -0
- package/src/dtos/update-dashboard-variable.dto.ts +5 -1
- package/src/entities/action-metadata.entity.ts +3 -2
- package/src/entities/ai-interaction.entity.ts +5 -4
- package/src/entities/chatter-message-details.entity.ts +4 -3
- package/src/entities/chatter-message.entity.ts +4 -3
- package/src/entities/dashboard-layout.entity.ts +18 -0
- package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
- package/src/entities/dashboard-question.entity.ts +5 -4
- package/src/entities/dashboard-variable.entity.ts +9 -4
- package/src/entities/dashboard.entity.ts +7 -2
- package/src/entities/email-attachment.entity.ts +2 -1
- package/src/entities/email-template.entity.ts +1 -1
- package/src/entities/export-transaction.entity.ts +2 -1
- package/src/entities/field-metadata.entity.ts +2 -2
- package/src/entities/import-transaction-error-log.entity.ts +3 -2
- package/src/entities/import-transaction.entity.ts +2 -1
- package/src/entities/mq-message-queue.entity.ts +8 -8
- package/src/entities/mq-message.entity.ts +5 -3
- package/src/entities/saved-filters.entity.ts +3 -2
- package/src/entities/security-rule.entity.ts +2 -1
- package/src/entities/sms-template.entity.ts +1 -1
- package/src/entities/user-view-metadata.entity.ts +2 -1
- package/src/entities/user.entity.ts +37 -2
- package/src/entities/view-metadata.entity.ts +3 -0
- package/src/helpers/bootstrap.helper.ts +222 -0
- package/src/helpers/cache.helper.ts +5 -0
- package/src/helpers/cors.helper.ts +26 -6
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +9 -9
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
- package/src/helpers/solid-registry.ts +10 -5
- package/src/helpers/typeorm-db-helper.ts +26 -0
- package/src/index.ts +3 -0
- package/src/interfaces.ts +3 -0
- package/src/jobs/chatter-queue-options.ts +1 -1
- package/src/jobs/chatter-queue-publisher.service.ts +11 -11
- package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
- package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
- package/src/jobs/database/chatter-queue-options-database.ts +9 -0
- package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
- package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
- package/src/repository/dashboard-layout.repository.ts +17 -0
- package/src/repository/model-metadata.repository.ts +45 -2
- package/src/seeders/module-metadata-seeder.service.ts +5 -5
- package/src/seeders/seed-data/solid-core-metadata.json +373 -33
- package/src/services/1.js +6 -0
- package/src/services/chatter-message.service.ts +41 -9
- package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
- package/src/services/crud.service.ts +1 -1
- package/src/services/dashboard-layout.service.ts +111 -0
- package/src/services/dashboard.service.ts +7 -0
- package/src/services/model-metadata.service.ts +22 -43
- package/src/services/permission-metadata.service.ts +73 -20
- package/src/services/queues/database-subscriber.service.ts +7 -1
- package/src/services/queues/publisher-factory.service.ts +1 -1
- package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
- package/src/services/queues/rabbitmq-subscriber.service.ts +127 -10
- package/src/services/request-context.service.ts +2 -1
- package/src/services/scheduled-jobs/scheduler.service.ts +22 -4
- package/src/services/solid-introspect.service.ts +28 -0
- package/src/services/solid-ts-morph.service.ts +98 -0
- package/src/solid-core.module.ts +21 -2
- package/src/subscribers/audit.subscriber.ts +63 -271
- package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
- package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
- package/src/winston.logger.ts +2 -1
- package/dist-tests/api/authenticate.spec.js +0 -119
- package/dist-tests/api/authenticate.spec.js.map +0 -1
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
- package/dist-tests/api/ping.spec.js +0 -21
- package/dist-tests/api/ping.spec.js.map +0 -1
- package/dist-tests/helpers/auth.js +0 -41
- package/dist-tests/helpers/auth.js.map +0 -1
- package/dist-tests/helpers/env.js +0 -11
- package/dist-tests/helpers/env.js.map +0 -1
|
@@ -6,6 +6,17 @@ import { MqMessageQueueService } from '../mq-message-queue.service';
|
|
|
6
6
|
import { MqMessageService } from '../mq-message.service';
|
|
7
7
|
import { buildNamespacedQueueName } from './common';
|
|
8
8
|
|
|
9
|
+
class ConsumerProcessingTimeoutError extends Error {
|
|
10
|
+
constructor(
|
|
11
|
+
readonly queueName: string,
|
|
12
|
+
readonly messageId: string,
|
|
13
|
+
readonly timeoutMs: number,
|
|
14
|
+
) {
|
|
15
|
+
super(`Subscriber processing timed out after ${timeoutMs}ms for queue ${queueName} and messageId ${messageId}`);
|
|
16
|
+
this.name = 'ConsumerProcessingTimeoutError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
9
20
|
|
|
10
21
|
export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility
|
|
11
22
|
private _loggerInstance?: Logger;
|
|
@@ -45,6 +56,10 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
45
56
|
|
|
46
57
|
abstract options(): QueuesModuleOptions;
|
|
47
58
|
|
|
59
|
+
protected shouldPersistToDatabase(): boolean {
|
|
60
|
+
return this.options().persistToDatabase ?? true;
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
async establishConnection(): Promise<amqp.Connection> {
|
|
49
64
|
|
|
50
65
|
const url = new URL(this.url);
|
|
@@ -73,9 +88,15 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
73
88
|
const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';
|
|
74
89
|
const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
|
|
75
90
|
const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
|
|
91
|
+
const roleAllowed = ['both', 'subscriber'].includes(this.serviceRole);
|
|
92
|
+
|
|
93
|
+
if (!roleAllowed) {
|
|
94
|
+
this.logger.log(`RabbitMqSubscriber is disabled because QUEUES_SERVICE_ROLE is "${this.serviceRole}". Expected "both" or "subscriber".`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
76
97
|
|
|
77
98
|
// we will start subscriber only if the current service role is subscriber.
|
|
78
|
-
if (this.url &&
|
|
99
|
+
if (this.url && solidCliRunning === "false" && defaultBroker === 'rabbitmq') {
|
|
79
100
|
const options = this.options();
|
|
80
101
|
const queueName = options.queueName;
|
|
81
102
|
|
|
@@ -113,6 +134,10 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
113
134
|
if (prefetch < 1) {
|
|
114
135
|
throw new Error(`RabbitMqSubscriber prefetch must be >= 1 for queue ${queueName}`);
|
|
115
136
|
}
|
|
137
|
+
const processingTimeoutMs = this.resolveProcessingTimeoutMs();
|
|
138
|
+
if (processingTimeoutMs > 0) {
|
|
139
|
+
this.logger.log(`RabbitMqSubscriber using processing timeout ${processingTimeoutMs}ms for queue ${queueName}`);
|
|
140
|
+
}
|
|
116
141
|
|
|
117
142
|
let connection: amqp.Connection;
|
|
118
143
|
try {
|
|
@@ -197,7 +222,7 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
197
222
|
if (!message.currentRetry) message.currentRetry = 0;
|
|
198
223
|
|
|
199
224
|
try {
|
|
200
|
-
await this.processMessage(message, rawMessage, channel);
|
|
225
|
+
await this.processMessage(message, rawMessage, channel, queueName);
|
|
201
226
|
} catch (error) {
|
|
202
227
|
await this.handleProcessingError(message, rawMessage, channel, error, queueName);
|
|
203
228
|
}
|
|
@@ -212,10 +237,12 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
212
237
|
// Retry flow: update DB -> increment retry -> send to retry queue with per-message expiration -> ack original.
|
|
213
238
|
private async handleProcessingError(message: QueueMessage<T>, rawMessage: amqp.ConsumeMessage, channel: amqp.Channel, error: any, queueName: string): Promise<void> {
|
|
214
239
|
const errorMessage = (error as Error)?.message || String(error);
|
|
215
|
-
this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}
|
|
240
|
+
this.logger.error(`Error processing message on queue ${queueName}: ${errorMessage}`, (error as Error)?.stack);
|
|
216
241
|
|
|
217
242
|
if (message.currentRetry < message.retryCount) {
|
|
218
|
-
|
|
243
|
+
if (this.shouldPersistToDatabase()) {
|
|
244
|
+
await this.updateStatusInDatabase('retrying', message);
|
|
245
|
+
}
|
|
219
246
|
|
|
220
247
|
message.currentRetry++;
|
|
221
248
|
const retryQueue = `${queueName}.retry`;
|
|
@@ -233,8 +260,9 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
233
260
|
this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on queue ${queueName}`);
|
|
234
261
|
return;
|
|
235
262
|
}
|
|
236
|
-
|
|
237
|
-
|
|
263
|
+
if (this.shouldPersistToDatabase()) {
|
|
264
|
+
await this.updateStatusInDatabase('failed', message, errorMessage, '');
|
|
265
|
+
}
|
|
238
266
|
channel.ack(rawMessage);
|
|
239
267
|
await this.publishToFailedQueue(queueName, Buffer.from(JSON.stringify(message)), channel, error);
|
|
240
268
|
this.logger.error(`Message failed after ${message.retryCount} attempts on queue ${queueName}: ${errorMessage}`);
|
|
@@ -333,17 +361,21 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
333
361
|
/**
|
|
334
362
|
* Abstract method for message processing logic.
|
|
335
363
|
*/
|
|
336
|
-
protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {
|
|
337
|
-
|
|
364
|
+
protected async processMessage(message: QueueMessage<T>, rawMessage, channel, queueName: string): Promise<void> {
|
|
365
|
+
if (this.shouldPersistToDatabase()) {
|
|
366
|
+
await this.updateStatusInDatabase('started', message);
|
|
367
|
+
}
|
|
338
368
|
|
|
339
369
|
// Capture the results of handling the task.
|
|
340
|
-
const result = await this.
|
|
370
|
+
const result = await this.subscribeWithTimeout(message, queueName);
|
|
341
371
|
|
|
342
372
|
// Ack the message.
|
|
343
373
|
channel.ack(rawMessage);
|
|
344
374
|
|
|
345
375
|
// Persist success output and timing.
|
|
346
|
-
|
|
376
|
+
if (this.shouldPersistToDatabase()) {
|
|
377
|
+
await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');
|
|
378
|
+
}
|
|
347
379
|
|
|
348
380
|
}
|
|
349
381
|
|
|
@@ -381,4 +413,89 @@ export abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
381
413
|
|
|
382
414
|
}
|
|
383
415
|
|
|
416
|
+
private resolveProcessingTimeoutMs(): number {
|
|
417
|
+
// Broker-side delivery-ack timeout (ms). If not provided, assume RabbitMQ default
|
|
418
|
+
// behavior used in this project: 30 minutes.
|
|
419
|
+
// Example (RabbitMQ broker):
|
|
420
|
+
// - Broker ack timeout: 30m => 1,800,000ms (QUEUES_RABBITMQ_CONSUMER_ACK_TIMEOUT_MS)
|
|
421
|
+
// - App soft timeout should be slightly lower, e.g. 29m30s => 1,770,000ms
|
|
422
|
+
// (QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS), so application code fails first,
|
|
423
|
+
// records DB state/error, and avoids broker-forced channel close as primary failure signal.
|
|
424
|
+
const brokerTimeoutMs = this.parsePositiveInt(process.env.QUEUES_RABBITMQ_CONSUMER_ACK_TIMEOUT_MS, 30 * 60 * 1000);
|
|
425
|
+
|
|
426
|
+
// Soft timeout should fire *before* broker timeout so we can fail explicitly,
|
|
427
|
+
// persist status/error, and avoid broker-forced channel closure as primary signal.
|
|
428
|
+
// Keep at least 1s to avoid zero/negative values when broker timeout is very small.
|
|
429
|
+
const defaultSoftTimeoutMs = Math.max(1_000, brokerTimeoutMs - 30_000);
|
|
430
|
+
|
|
431
|
+
// Final timeout precedence:
|
|
432
|
+
// 1) QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS (if valid positive int)
|
|
433
|
+
// 2) Derived defaultSoftTimeoutMs (broker timeout - 30s)
|
|
434
|
+
return this.parsePositiveInt(process.env.QUEUES_RABBITMQ_SUBSCRIBER_PROCESSING_TIMEOUT_MS, defaultSoftTimeoutMs);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private parsePositiveInt(value: string | undefined, fallback: number): number {
|
|
438
|
+
// Shared env parsing helper:
|
|
439
|
+
// - missing/invalid/non-positive => fallback
|
|
440
|
+
// - valid positive integer => parsed value
|
|
441
|
+
if (!value) return fallback;
|
|
442
|
+
const parsed = Number.parseInt(value, 10);
|
|
443
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private async subscribeWithTimeout(message: QueueMessage<T>, queueName: string): Promise<any> {
|
|
447
|
+
const timeoutMs = this.resolveProcessingTimeoutMs();
|
|
448
|
+
const messageId = message?.messageId || 'unknown';
|
|
449
|
+
|
|
450
|
+
// Allow an escape hatch: non-positive timeout means run without a soft timeout.
|
|
451
|
+
if (timeoutMs <= 0) {
|
|
452
|
+
return this.subscribe(message);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
let timedOut = false;
|
|
456
|
+
let timeoutHandle: NodeJS.Timeout | null = null;
|
|
457
|
+
|
|
458
|
+
// Main subscriber work promise.
|
|
459
|
+
// If timeout has already fired, suppress rethrow to avoid unhandled rejection noise
|
|
460
|
+
// (the timeout error is already the authoritative failure we track).
|
|
461
|
+
const subscribePromise = this.subscribe(message).catch((error) => {
|
|
462
|
+
if (timedOut) {
|
|
463
|
+
this.logger.error(
|
|
464
|
+
`Subscriber promise rejected after timeout for queue ${queueName} and messageId ${messageId}: ${(error as Error)?.message || String(error)}`,
|
|
465
|
+
(error as Error)?.stack,
|
|
466
|
+
);
|
|
467
|
+
return undefined;
|
|
468
|
+
}
|
|
469
|
+
throw error;
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// Timeout promise rejects after timeoutMs with an explicit domain-specific error.
|
|
473
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
474
|
+
timeoutHandle = setTimeout(() => {
|
|
475
|
+
timedOut = true;
|
|
476
|
+
reject(new ConsumerProcessingTimeoutError(queueName, messageId, timeoutMs));
|
|
477
|
+
}, timeoutMs);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
try {
|
|
481
|
+
// Promise.race settles as soon as the *first* promise settles.
|
|
482
|
+
// - If subscribePromise resolves/rejects first, we use that outcome.
|
|
483
|
+
// - If timeoutPromise rejects first, we fail fast with timeout error.
|
|
484
|
+
// This ensures we mark DB status via normal error handling before broker ack-timeout.
|
|
485
|
+
return await Promise.race([subscribePromise, timeoutPromise]);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
const errorMessage = (error as Error)?.message || String(error);
|
|
488
|
+
this.logger.error(
|
|
489
|
+
`Subscriber execution failed for queue ${queueName} and messageId ${messageId}: ${errorMessage}`,
|
|
490
|
+
(error as Error)?.stack,
|
|
491
|
+
);
|
|
492
|
+
throw error;
|
|
493
|
+
} finally {
|
|
494
|
+
// Always clear timer once race settles to avoid timer leaks.
|
|
495
|
+
if (timeoutHandle) {
|
|
496
|
+
clearTimeout(timeoutHandle);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
384
501
|
}
|
|
@@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
|
|
|
2
2
|
import { ClsService } from "nestjs-cls";
|
|
3
3
|
import { REQUEST_USER_KEY } from "src/constants";
|
|
4
4
|
import { BasicFilterDto } from "src/dtos/basic-filters.dto";
|
|
5
|
+
import { ActiveUserData } from "src/interfaces/active-user-data.interface";
|
|
5
6
|
|
|
6
7
|
@Injectable()
|
|
7
8
|
export class RequestContextService {
|
|
@@ -9,7 +10,7 @@ export class RequestContextService {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
// This method i.e getActiveUser() will fetch the user from the request object in the context
|
|
12
|
-
getActiveUser() {
|
|
13
|
+
getActiveUser(): ActiveUserData | undefined {
|
|
13
14
|
return this.cls.get(REQUEST_USER_KEY);
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -24,13 +24,23 @@ export class SchedulerServiceImpl implements ISchedulerService {
|
|
|
24
24
|
async runScheduledJobs(): Promise<void> {
|
|
25
25
|
const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || "true";
|
|
26
26
|
if (solidSchedulerEnabled.toLowerCase() !== "true") {
|
|
27
|
-
|
|
27
|
+
this.logger.debug('Solid scheduler is disabled via environment variable');
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
|
|
31
31
|
if (solidCliRunning === "true") {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
+
const jobsRegexToEnable = (process.env.SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE || '').trim();
|
|
35
|
+
let jobsRegex: RegExp | null = null;
|
|
36
|
+
if (jobsRegexToEnable && jobsRegexToEnable !== "all") {
|
|
37
|
+
try {
|
|
38
|
+
jobsRegex = new RegExp(jobsRegexToEnable);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
this.logger.error(`Invalid SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE regex "${jobsRegexToEnable}". Scheduler loop will skip this run.`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
34
44
|
|
|
35
45
|
const now = new Date();
|
|
36
46
|
|
|
@@ -53,6 +63,12 @@ export class SchedulerServiceImpl implements ISchedulerService {
|
|
|
53
63
|
|
|
54
64
|
for (const job of dueJobs) {
|
|
55
65
|
const jobKey = String(job.id ?? job.scheduleName ?? job.job);
|
|
66
|
+
const jobName = String(job.job ?? '');
|
|
67
|
+
|
|
68
|
+
if (jobsRegex && !jobsRegex.test(jobName)) {
|
|
69
|
+
this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${jobName} because it does not match SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE=${jobsRegexToEnable}`);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
56
72
|
|
|
57
73
|
if (this.runningJobs.has(jobKey)) {
|
|
58
74
|
this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);
|
|
@@ -194,16 +210,18 @@ export class SchedulerServiceImpl implements ISchedulerService {
|
|
|
194
210
|
tz: 'UTC'
|
|
195
211
|
});
|
|
196
212
|
const nextRun = interval.next().toDate();
|
|
213
|
+
const runAfterNext = interval.next().toDate();
|
|
197
214
|
|
|
198
|
-
// Validate minimum 1 minute
|
|
199
|
-
|
|
215
|
+
// Validate minimum 1 minute cadence between consecutive runs.
|
|
216
|
+
// Comparing nextRun to "from" is incorrect near minute boundaries.
|
|
217
|
+
if (runAfterNext.getTime() - nextRun.getTime() < 60000) {
|
|
200
218
|
throw new Error('Cron expression interval must be at least 1 minute');
|
|
201
219
|
}
|
|
202
220
|
|
|
203
221
|
this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);
|
|
204
222
|
return nextRun;
|
|
205
223
|
} catch (error) {
|
|
206
|
-
this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}
|
|
224
|
+
this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}. Reason: ${(error as Error).message}`);
|
|
207
225
|
// Fallback to daily if cron parsing fails
|
|
208
226
|
return new Date(base.getTime() + 24 * 60 * 60 * 1000);
|
|
209
227
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { classify } from '@angular-devkit/core/src/utils/strings';
|
|
2
2
|
import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
|
|
3
3
|
import { DiscoveryService, MetadataScanner, ModuleRef, Reflector } from '@nestjs/core';
|
|
4
|
+
import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
|
|
5
|
+
import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
|
|
4
6
|
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
5
7
|
import { getDataSourceToken } from '@nestjs/typeorm';
|
|
6
8
|
import { IS_COMPUTED_FIELD_PROVIDER } from 'src/decorators/computed-field-provider.decorator';
|
|
@@ -40,6 +42,8 @@ export class SolidIntrospectService implements OnApplicationBootstrap {
|
|
|
40
42
|
private readonly solidRegistry: SolidRegistry,
|
|
41
43
|
private readonly moduleRef: ModuleRef,
|
|
42
44
|
private readonly settingService: SettingService,
|
|
45
|
+
private readonly modelMetadataRepo: ModelMetadataRepository,
|
|
46
|
+
private readonly modelMetadataHelperService: ModelMetadataHelperService,
|
|
43
47
|
) { }
|
|
44
48
|
|
|
45
49
|
private readonly logger = new Logger(SolidIntrospectService.name);
|
|
@@ -142,9 +146,33 @@ export class SolidIntrospectService implements OnApplicationBootstrap {
|
|
|
142
146
|
|
|
143
147
|
// Register the core subscribers against all the configured database modules / datasources
|
|
144
148
|
await this.bootstrapCoreTypeOrmSubscribers(solidDatabaseModules);
|
|
149
|
+
await this.cacheAuditableModels();
|
|
145
150
|
await this.settingService.updateSettingsCache();
|
|
146
151
|
}
|
|
147
152
|
|
|
153
|
+
private async cacheAuditableModels(): Promise<void> {
|
|
154
|
+
const models = await this.modelMetadataRepo.find({
|
|
155
|
+
where: { enableAuditTracking: true },
|
|
156
|
+
relations: { fields: true, module: true },
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const auditableSet = new Set<string>();
|
|
160
|
+
for (const model of models) {
|
|
161
|
+
const allFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);
|
|
162
|
+
const hasAuditableField = allFields.some(field =>
|
|
163
|
+
field.enableAuditTracking &&
|
|
164
|
+
!['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&
|
|
165
|
+
!(field.type === 'relation' && field.relationType === 'one-to-many')
|
|
166
|
+
);
|
|
167
|
+
if (hasAuditableField) {
|
|
168
|
+
auditableSet.add(model.singularName.toLowerCase());
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.solidRegistry.registerAuditableModels(auditableSet);
|
|
173
|
+
this.logger.debug(`Cached ${auditableSet.size} auditable model(s): ${[...auditableSet].join(', ')}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
148
176
|
async bootstrapCoreTypeOrmSubscribers(dbModules: Array<InstanceWrapper<any>>): Promise<void> {
|
|
149
177
|
// Register core subscribers for each Solid database module
|
|
150
178
|
for (const wrapper of dbModules) {
|
|
@@ -324,6 +324,104 @@ export class SolidTsMorphService {
|
|
|
324
324
|
return { staged: true, overwritten: false, skipped: false };
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
|
|
328
|
+
//Removes all import declarations from a file whose module specifier matches the given predicate.
|
|
329
|
+
//Returns the set of identifier names that were imported by the removed declarations.
|
|
330
|
+
removeImports(
|
|
331
|
+
filePath: string,
|
|
332
|
+
filter: (moduleSpecifier: string) => boolean
|
|
333
|
+
): { removedIdentifiers: Set<string>; staged: boolean; skipped: boolean } {
|
|
334
|
+
const abs = this.resolveRepoPath(filePath);
|
|
335
|
+
if (!existsSync(abs)) {
|
|
336
|
+
this.logger.warn(`removeImport: file not found at ${filePath}, skipping.`);
|
|
337
|
+
return { removedIdentifiers: new Set(), staged: false, skipped: true };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const existing = this.project.getSourceFile(abs);
|
|
341
|
+
const sourceFile = existing
|
|
342
|
+
? existing
|
|
343
|
+
: this.project.createSourceFile(abs, readFileSync(abs, "utf8"), { overwrite: true });
|
|
344
|
+
|
|
345
|
+
const importsToRemove = sourceFile.getImportDeclarations().filter(decl => {
|
|
346
|
+
const spec = decl.getModuleSpecifierValue().replace(/\\/g, "/");
|
|
347
|
+
return filter(spec);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
if (importsToRemove.length === 0) {
|
|
351
|
+
return { removedIdentifiers: new Set(), staged: false, skipped: true };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const removedIdentifiers = new Set<string>();
|
|
355
|
+
for (const decl of importsToRemove) {
|
|
356
|
+
for (const named of decl.getNamedImports()) {
|
|
357
|
+
removedIdentifiers.add(named.getAliasNode()?.getText() ?? named.getName());
|
|
358
|
+
}
|
|
359
|
+
const defaultImport = decl.getDefaultImport();
|
|
360
|
+
if (defaultImport) removedIdentifiers.add(defaultImport.getText());
|
|
361
|
+
decl.remove();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
this.dirtySourceFiles.add(abs);
|
|
365
|
+
this.logger.log(`Staged removal of ${importsToRemove.length} import(s) in: ${this.rel(abs)}`);
|
|
366
|
+
return { removedIdentifiers, staged: true, skipped: false };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
//Removes the given identifier names from all @Module decorator array properties
|
|
370
|
+
removeModuleMembers(
|
|
371
|
+
filePath: string,
|
|
372
|
+
names: Set<string> | string[]
|
|
373
|
+
): { staged: boolean; skipped: boolean } {
|
|
374
|
+
const abs = this.resolveRepoPath(filePath);
|
|
375
|
+
if (!existsSync(abs)) {
|
|
376
|
+
this.logger.warn(`removeImportMembers: file not found at ${filePath}, skipping.`);
|
|
377
|
+
return { staged: false, skipped: true };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const identifiers = names instanceof Set ? names : new Set(names);
|
|
381
|
+
if (identifiers.size === 0) return { staged: false, skipped: true };
|
|
382
|
+
|
|
383
|
+
const existing = this.project.getSourceFile(abs);
|
|
384
|
+
const sourceFile = existing
|
|
385
|
+
? existing
|
|
386
|
+
: this.project.createSourceFile(abs, readFileSync(abs, "utf8"), { overwrite: true });
|
|
387
|
+
|
|
388
|
+
const nestModuleClass = sourceFile.getClasses().find(cls =>
|
|
389
|
+
cls.getDecorators().some(dec => dec.getName() === "Module")
|
|
390
|
+
);
|
|
391
|
+
if (!nestModuleClass) {
|
|
392
|
+
this.logger.warn(`removeImportMembers: no @Module() class found in ${filePath}`);
|
|
393
|
+
return { staged: false, skipped: true };
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const moduleDec = nestModuleClass.getDecorators().find(dec => dec.getName() === "Module");
|
|
397
|
+
const arg0 = moduleDec?.getCallExpression()?.getArguments()[0];
|
|
398
|
+
if (!arg0 || !Node.isObjectLiteralExpression(arg0)) return { staged: false, skipped: true };
|
|
399
|
+
|
|
400
|
+
const meta = arg0 as ObjectLiteralExpression;
|
|
401
|
+
for (const propName of ["imports", "providers", "controllers", "exports"] as const) {
|
|
402
|
+
const prop = meta.getProperty(propName);
|
|
403
|
+
if (!prop || !Node.isPropertyAssignment(prop)) continue;
|
|
404
|
+
const init = prop.getInitializer();
|
|
405
|
+
if (!init || !Node.isArrayLiteralExpression(init)) continue;
|
|
406
|
+
const arr = init as ArrayLiteralExpression;
|
|
407
|
+
const elements = arr.getElements();
|
|
408
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
409
|
+
const elemText = elements[i].getText().trim();
|
|
410
|
+
// Match direct identifiers (e.g. TestService) or call expressions that reference them (e.g. TypeOrmModule.forFeature([Test])).
|
|
411
|
+
const shouldRemove = identifiers.has(elemText) ||
|
|
412
|
+
[...identifiers].some(id => new RegExp(`\\b${id}\\b`).test(elemText));
|
|
413
|
+
if (shouldRemove) {
|
|
414
|
+
arr.removeElement(i);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
this.dirtySourceFiles.add(abs);
|
|
420
|
+
this.logger.log(`Staged removal of [${[...identifiers].join(", ")}] from @Module arrays in: ${this.rel(abs)}`);
|
|
421
|
+
return { staged: true, skipped: false };
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
|
|
327
425
|
addImport(
|
|
328
426
|
filePath: string,
|
|
329
427
|
importLine: string
|
package/src/solid-core.module.ts
CHANGED
|
@@ -94,6 +94,10 @@ import { Msg91SmsQueuePublisher } from './jobs/msg91-sms-publisher.service';
|
|
|
94
94
|
import { Msg91SmsQueueSubscriber } from './jobs/msg91-sms-subscriber.service';
|
|
95
95
|
import { SmtpEmailQueuePublisherRabbitmq } from './jobs/smtp-email-publisher.service';
|
|
96
96
|
import { SmtpEmailQueueSubscriberRabbitmq } from './jobs/smtp-email-subscriber.service';
|
|
97
|
+
import { ChatterQueuePublisherRabbitmq } from './jobs/chatter-queue-publisher.service';
|
|
98
|
+
import { ChatterQueueSubscriberRabbitmq } from './jobs/chatter-queue-subscriber.service';
|
|
99
|
+
import { ChatterQueuePublisherDatabase } from './jobs/database/chatter-queue-publisher-database.service';
|
|
100
|
+
import { ChatterQueueSubscriberDatabase } from './jobs/database/chatter-queue-subscriber-database.service';
|
|
97
101
|
import { TestQueuePublisher } from './jobs/test-queue-publisher.service';
|
|
98
102
|
import { TestQueueSubscriber } from './jobs/test-queue-subscriber.service';
|
|
99
103
|
import { UserRegistrationListener } from './listeners/user-registration.listener';
|
|
@@ -133,6 +137,8 @@ import { ChatterMessageController } from './controllers/chatter-message.controll
|
|
|
133
137
|
import { DashboardQuestionSqlDatasetConfigController } from './controllers/dashboard-question-sql-dataset-config.controller';
|
|
134
138
|
import { DashboardQuestionController } from './controllers/dashboard-question.controller';
|
|
135
139
|
import { DashboardVariableController } from './controllers/dashboard-variable.controller';
|
|
140
|
+
import { DashboardLayoutController } from './controllers/dashboard-layout.controller';
|
|
141
|
+
|
|
136
142
|
import { DashboardController } from './controllers/dashboard.controller';
|
|
137
143
|
import { ExportTemplateController } from './controllers/export-template.controller';
|
|
138
144
|
import { ExportTransactionController } from './controllers/export-transaction.controller';
|
|
@@ -156,6 +162,8 @@ import { ChatterMessage } from './entities/chatter-message.entity';
|
|
|
156
162
|
import { DashboardQuestionSqlDatasetConfig } from './entities/dashboard-question-sql-dataset-config.entity';
|
|
157
163
|
import { DashboardQuestion } from './entities/dashboard-question.entity';
|
|
158
164
|
import { DashboardVariable } from './entities/dashboard-variable.entity';
|
|
165
|
+
import { DashboardLayout } from './entities/dashboard-layout.entity';
|
|
166
|
+
|
|
159
167
|
import { Dashboard } from './entities/dashboard.entity';
|
|
160
168
|
import { ExportTemplate } from './entities/export-template.entity';
|
|
161
169
|
import { ExportTransaction } from './entities/export-transaction.entity';
|
|
@@ -221,6 +229,8 @@ import { DashboardQuestionSqlDatasetConfigRepository } from './repository/dashbo
|
|
|
221
229
|
import { DashboardQuestionRepository } from './repository/dashboard-question.repository';
|
|
222
230
|
import { DashboardVariableRepository } from './repository/dashboard-variable.repository';
|
|
223
231
|
import { DashboardRepository } from './repository/dashboard.repository';
|
|
232
|
+
import { DashboardLayoutRepository } from './repository/dashboard-layout.repository';
|
|
233
|
+
|
|
224
234
|
import { EmailTemplateRepository } from './repository/email-template.repository';
|
|
225
235
|
import { ExportTemplateRepository } from './repository/export-template.repository';
|
|
226
236
|
import { ExportTransactionRepository } from './repository/export-transaction.repository';
|
|
@@ -263,6 +273,8 @@ import { DashboardVariableSQLDynamicProvider } from './services/dashboard-select
|
|
|
263
273
|
import { DasbhoardVariableTestDynamicProvider } from './services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service';
|
|
264
274
|
import { DashboardVariableService } from './services/dashboard-variable.service';
|
|
265
275
|
import { DashboardService } from './services/dashboard.service';
|
|
276
|
+
import { DashboardLayoutService } from './services/dashboard-layout.service';
|
|
277
|
+
|
|
266
278
|
import { ExcelService } from './services/excel.service';
|
|
267
279
|
import { ExportTemplateService } from './services/export-template.service';
|
|
268
280
|
import { ExportTransactionService } from './services/export-transaction.service';
|
|
@@ -329,6 +341,7 @@ import { ImageEncodingService } from './helpers/image-encoding.helper';
|
|
|
329
341
|
import { SolidMicroserviceAdapter } from './helpers/solid-microservice-adapter.service';
|
|
330
342
|
import { InfoCommand } from './commands/info.command';
|
|
331
343
|
import { ListOfRolesSelectionProvider } from './services/selection-providers/list-of-roles-selectionproviders.service';
|
|
344
|
+
import { Entity } from 'typeorm';
|
|
332
345
|
|
|
333
346
|
|
|
334
347
|
@Global()
|
|
@@ -343,6 +356,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
|
|
|
343
356
|
DashboardQuestion,
|
|
344
357
|
DashboardQuestionSqlDatasetConfig,
|
|
345
358
|
DashboardVariable,
|
|
359
|
+
DashboardLayout,
|
|
346
360
|
EmailAttachment,
|
|
347
361
|
EmailTemplate,
|
|
348
362
|
ExportTemplate,
|
|
@@ -414,6 +428,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
|
|
|
414
428
|
DashboardQuestionController,
|
|
415
429
|
DashboardQuestionSqlDatasetConfigController,
|
|
416
430
|
DashboardVariableController,
|
|
431
|
+
DashboardLayoutController,
|
|
417
432
|
EmailTemplateController,
|
|
418
433
|
ExportTemplateController,
|
|
419
434
|
ExportTransactionController,
|
|
@@ -584,8 +599,10 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
|
|
|
584
599
|
TestQueuePublisher,
|
|
585
600
|
TestQueueSubscriber,
|
|
586
601
|
|
|
587
|
-
|
|
588
|
-
|
|
602
|
+
ChatterQueuePublisherRabbitmq,
|
|
603
|
+
ChatterQueueSubscriberRabbitmq,
|
|
604
|
+
ChatterQueuePublisherDatabase,
|
|
605
|
+
ChatterQueueSubscriberDatabase,
|
|
589
606
|
|
|
590
607
|
TestQueuePublisherDatabase,
|
|
591
608
|
TestQueueSubscriberDatabase,
|
|
@@ -638,6 +655,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
|
|
|
638
655
|
UserActivityHistoryService,
|
|
639
656
|
DashboardService,
|
|
640
657
|
DashboardVariableService,
|
|
658
|
+
DashboardLayoutService,
|
|
641
659
|
DashboardQuestionService,
|
|
642
660
|
DashboardVariableSQLDynamicProvider,
|
|
643
661
|
DasbhoardVariableTestDynamicProvider,
|
|
@@ -682,6 +700,7 @@ import { ListOfRolesSelectionProvider } from './services/selection-providers/lis
|
|
|
682
700
|
DashboardQuestionSqlDatasetConfigRepository,
|
|
683
701
|
DashboardQuestionRepository,
|
|
684
702
|
DashboardVariableRepository,
|
|
703
|
+
DashboardLayoutRepository,
|
|
685
704
|
EmailTemplateRepository,
|
|
686
705
|
ExportTemplateRepository,
|
|
687
706
|
ExportTransactionRepository,
|