@solidxai/core 0.1.9-beta.8 → 0.1.10-alpha.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.
- package/LICENSE +89 -0
- package/README.md +3 -1
- package/dist/commands/run-tests.command.d.ts +2 -0
- package/dist/commands/run-tests.command.d.ts.map +1 -1
- package/dist/commands/run-tests.command.js +49 -17
- package/dist/commands/run-tests.command.js.map +1 -1
- package/dist/controllers/action-metadata.controller.js +1 -1
- package/dist/controllers/action-metadata.controller.js.map +1 -1
- package/dist/controllers/facebook-authentication.controller.js +1 -1
- package/dist/controllers/facebook-authentication.controller.js.map +1 -1
- package/dist/controllers/google-authentication.controller.js +1 -1
- package/dist/controllers/google-authentication.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
- package/dist/controllers/microsoft-authentication.controller.js +1 -1
- package/dist/controllers/microsoft-authentication.controller.js.map +1 -1
- package/dist/controllers/mq-message-queue.controller.js +1 -1
- package/dist/controllers/mq-message-queue.controller.js.map +1 -1
- package/dist/controllers/mq-message.controller.js +1 -1
- package/dist/controllers/mq-message.controller.js.map +1 -1
- package/dist/controllers/user.controller.d.ts.map +1 -1
- package/dist/controllers/user.controller.js.map +1 -1
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/view-metadata.controller.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
- package/dist/helpers/bootstrap.helper.js +2 -0
- package/dist/helpers/bootstrap.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
- package/dist/passport-strategies/facebook-oauth.strategy.d.ts +5 -3
- package/dist/passport-strategies/facebook-oauth.strategy.d.ts.map +1 -1
- package/dist/passport-strategies/facebook-oauth.strategy.js +41 -18
- package/dist/passport-strategies/facebook-oauth.strategy.js.map +1 -1
- package/dist/repository/security-rule.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/permission-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +14 -3
- package/dist/services/authentication.service.d.ts +12 -13
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +42 -18
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/csv.service.js.map +1 -1
- package/dist/services/dashboard.service.js.map +1 -1
- package/dist/services/database/database-bootstrap.service.js.map +1 -1
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/export-transaction.service.js.map +1 -1
- package/dist/services/field-metadata.service.js +2 -2
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/fixtures.service.js.map +1 -1
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/list-of-values.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +3 -13
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/queues/database-publisher.service.js +3 -3
- package/dist/services/queues/database-publisher.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +3 -3
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.js +3 -3
- package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +4 -4
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/queues/redis-publisher.service.d.ts.map +1 -1
- package/dist/services/queues/redis-publisher.service.js +4 -1
- package/dist/services/queues/redis-publisher.service.js.map +1 -1
- package/dist/services/queues/redis-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/redis-subscriber.service.js +4 -1
- package/dist/services/queues/redis-subscriber.service.js.map +1 -1
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +74 -8
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +96 -16
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/sms/TwilioSMSService.js.map +1 -1
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/user-activity-history.service.js.map +1 -1
- package/dist/services/user.service.d.ts +10 -8
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +85 -46
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +17 -2
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/solid-core.module.d.ts +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +1 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -1
- package/dist/subscribers/security-rule.subscriber.js.map +1 -1
- package/dist/subscribers/view-metadata.subscriber.js.map +1 -1
- package/dist/testing/core/testing-engine.js.map +1 -1
- package/dist/testing/reporter/webhook-reporter.d.ts +54 -0
- package/dist/testing/reporter/webhook-reporter.d.ts.map +1 -0
- package/dist/testing/reporter/webhook-reporter.js +74 -0
- package/dist/testing/reporter/webhook-reporter.js.map +1 -0
- package/package.json +6 -2
- package/src/commands/run-tests.command.ts +45 -17
- package/src/controllers/action-metadata.controller.ts +1 -1
- package/src/controllers/facebook-authentication.controller.ts +1 -1
- package/src/controllers/google-authentication.controller.ts +1 -1
- package/src/controllers/menu-item-metadata.controller.ts +1 -1
- package/src/controllers/microsoft-authentication.controller.ts +1 -1
- package/src/controllers/mq-message-queue.controller.ts +1 -1
- package/src/controllers/mq-message.controller.ts +1 -1
- package/src/controllers/user.controller.ts +16 -16
- package/src/controllers/view-metadata.controller.ts +1 -1
- package/src/helpers/bootstrap.helper.ts +3 -0
- package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +1 -1
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +1 -1
- package/src/helpers/module-metadata-helper.service.ts +1 -1
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +1 -1
- package/src/passport-strategies/facebook-oauth.strategy.ts +82 -31
- package/src/repository/security-rule.repository.ts +1 -1
- package/src/seeders/module-metadata-seeder.service.ts +4 -4
- package/src/seeders/permission-metadata-seeder.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +14 -3
- package/src/services/authentication.service.ts +215 -151
- package/src/services/chatter-message.service.ts +1 -1
- package/src/services/crud.service.ts +3 -3
- package/src/services/csv.service.ts +1 -1
- package/src/services/dashboard.service.ts +1 -1
- package/src/services/database/database-bootstrap.service.ts +1 -1
- package/src/services/excel.service.ts +1 -1
- package/src/services/export-transaction.service.ts +2 -2
- package/src/services/field-metadata.service.ts +3 -3
- package/src/services/fixtures.service.ts +2 -2
- package/src/services/import-transaction.service.ts +2 -2
- package/src/services/list-of-values.service.ts +1 -1
- package/src/services/model-metadata.service.ts +22 -21
- package/src/services/module-metadata.service.ts +7 -7
- package/src/services/queues/database-publisher.service.ts +4 -4
- package/src/services/queues/database-subscriber.service.ts +7 -7
- package/src/services/queues/rabbitmq-publisher.service.ts +7 -7
- package/src/services/queues/rabbitmq-subscriber.service.ts +13 -13
- package/src/services/queues/redis-publisher.service.ts +7 -4
- package/src/services/queues/redis-subscriber.service.ts +9 -6
- package/src/services/role-metadata.service.ts +1 -1
- package/src/services/scheduled-jobs/scheduler.service.ts +5 -5
- package/src/services/settings/default-settings-provider.service.ts +101 -21
- package/src/services/sms/TwilioSMSService.ts +2 -2
- package/src/services/solid-introspect.service.ts +2 -2
- package/src/services/user-activity-history.service.ts +1 -1
- package/src/services/user.service.ts +149 -77
- package/src/services/view-metadata.service.ts +25 -8
- package/src/solid-core.module.ts +1 -0
- package/src/subscribers/computed-entity-field.subscriber.ts +1 -1
- package/src/subscribers/security-rule.subscriber.ts +8 -8
- package/src/subscribers/view-metadata.subscriber.ts +1 -1
- package/src/testing/core/testing-engine.ts +2 -2
- package/src/testing/reporter/webhook-reporter.ts +116 -0
- package/dev-grooming-docs/ozzy-prompts.txt +0 -70
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-publisher.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/redis-publisher.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,8BAAsB,cAAc,CAAC,CAAC,CAAE,YAAW,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC;IAM7E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IANnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,MAAM,CAAsB;gBAGb,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"redis-publisher.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/redis-publisher.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,8BAAsB,cAAc,CAAC,CAAC,CAAE,YAAW,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC;IAM7E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IANnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,MAAM,CAAsB;gBAGb,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAWnE,QAAQ,CAAC,OAAO,IAAI,mBAAmB;IAEvC,OAAO,CAAC,SAAS;IAUX,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAOhC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;YA+B1C,iBAAiB;CAmBlC"}
|
|
@@ -14,7 +14,10 @@ class RedisPublisher {
|
|
|
14
14
|
this.mqMessageQueueService = mqMessageQueueService;
|
|
15
15
|
this.logger = new common_1.Logger(RedisPublisher.name);
|
|
16
16
|
this.client = null;
|
|
17
|
-
this.serviceRole = process.env.QUEUES_SERVICE_ROLE;
|
|
17
|
+
this.serviceRole = process.env.QUEUES_SERVICE_ROLE || 'both';
|
|
18
|
+
if (!process.env.QUEUES_SERVICE_ROLE) {
|
|
19
|
+
this.logger.debug('QUEUES_SERVICE_ROLE is not defined. Defaulting RedisPublisher service role to "both".');
|
|
20
|
+
}
|
|
18
21
|
if (!process.env.QUEUES_REDIS_URL) {
|
|
19
22
|
this.logger.debug('RedisPublisher: QUEUES_REDIS_URL is not defined in the environment variables');
|
|
20
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/redis-publisher.service.ts"],"names":[],"mappings":";;;;;;AAAA,2CAAyD;AACzD,sDAA4B;AAC5B,+BAAoC;AAKpC,qCAAoD;AAEpD,MAAsB,cAAc;IAKhC,YACuB,gBAAkC,EAClC,qBAA4C;QAD5C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QANlD,WAAM,GAAG,IAAI,eAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAElD,WAAM,GAAiB,IAAI,CAAC;QAMhC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/redis-publisher.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleDestroy } from '@nestjs/common';\nimport Redis from 'ioredis';\nimport { v4 as uuidv4 } from 'uuid';\nimport { QueuesModuleOptions } from '../../interfaces';\nimport { QueueMessage, QueuePublisher } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { buildNamespacedQueueName } from './common';\n\nexport abstract class RedisPublisher<T> implements OnModuleDestroy, QueuePublisher<T> {\n private readonly logger = new Logger(RedisPublisher.name);\n private readonly serviceRole: string;\n private client: Redis | null = null;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE || 'both';\n if (!process.env.QUEUES_SERVICE_ROLE) {\n this.logger.debug('QUEUES_SERVICE_ROLE is not defined. Defaulting RedisPublisher service role to \"both\".');\n }\n if (!process.env.QUEUES_REDIS_URL) {\n this.logger.debug('RedisPublisher: QUEUES_REDIS_URL is not defined in the environment variables');\n }\n }\n\n abstract options(): QueuesModuleOptions;\n\n private getClient(): Redis {\n if (!this.client) {\n this.client = new Redis(process.env.QUEUES_REDIS_URL);\n this.client.on('error', (err) => {\n this.logger.error(`RedisPublisher connection error: ${err.message}`, err.stack);\n });\n }\n return this.client;\n }\n\n async onModuleDestroy(): Promise<void> {\n if (this.client) {\n await this.client.quit();\n this.client = null;\n }\n }\n\n async publish(message: QueueMessage<T>): Promise<string> {\n if (!process.env.QUEUES_REDIS_URL) {\n throw new Error('RedisPublisher: QUEUES_REDIS_URL is not defined in the environment variables');\n }\n if (!this.serviceRole) {\n throw new Error('RedisPublisher: Queue service Role is not defined in the environment variables');\n }\n if (this.serviceRole === 'subscriber') {\n throw new Error('RedisPublisher: Queue service Role is subscriber, cannot publish messages');\n }\n\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n message.messageId = uuidv4();\n\n const queueName = this.options().queueName;\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n\n await this.persistToDatabase(namespacedQueueName, message);\n\n try {\n const client = this.getClient();\n await client.publish(namespacedQueueName, JSON.stringify(message));\n this.logger.debug(`RedisPublisher published message ${message.messageId} to channel ${namespacedQueueName}`);\n } catch (err: any) {\n this.logger.error(`RedisPublisher failed to publish message: ${(err as Error).message}`, (err as Error).stack);\n }\n\n return message.messageId;\n }\n\n private async persistToDatabase(queueName: string, message: QueueMessage<T>): Promise<void> {\n try {\n const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);\n await this.mqMessageService.create({\n messageBroker: this.options().type,\n messageId: message.messageId,\n retryCount: message.retryCount,\n retryInterval: message.retryInterval,\n stage: 'pending',\n startedAt: new Date(),\n input: JSON.stringify(message, null, 2),\n parentEntityId: message.parentEntityId,\n parentEntity: message.parentEntity,\n mqMessageQueueId: mqMessageQueue.id,\n });\n } catch (error: any) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/redis-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,8BAAsB,eAAe,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;IAQ7F,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IARnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAGF,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"redis-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/redis-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,8BAAsB,eAAe,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;IAQ7F,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IARnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAS;gBAGF,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAWnE,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAE1D,QAAQ,CAAC,OAAO,IAAI,mBAAmB;IAEjC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC7B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAKxB,mBAAmB;YA2CnB,qBAAqB;IAuBnC,OAAO,CAAC,gBAAgB;YAkBV,OAAO;IAarB,OAAO,CAAC,OAAO;cAQC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAMzD,sBAAsB;CAyBvC"}
|
|
@@ -15,7 +15,10 @@ class RedisSubscriber {
|
|
|
15
15
|
this.client = null;
|
|
16
16
|
this.reconnectAttempt = 0;
|
|
17
17
|
this.stopping = false;
|
|
18
|
-
this.serviceRole = process.env.QUEUES_SERVICE_ROLE;
|
|
18
|
+
this.serviceRole = process.env.QUEUES_SERVICE_ROLE || 'both';
|
|
19
|
+
if (!process.env.QUEUES_SERVICE_ROLE) {
|
|
20
|
+
this.logger.debug('QUEUES_SERVICE_ROLE is not defined. Defaulting RedisSubscriber service role to "both".');
|
|
21
|
+
}
|
|
19
22
|
if (!process.env.QUEUES_REDIS_URL) {
|
|
20
23
|
this.logger.debug('RedisSubscriber: QUEUES_REDIS_URL is not defined in the environment variables');
|
|
21
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/redis-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';\nimport Redis from 'ioredis';\nimport { QueuesModuleOptions } from '../../interfaces';\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { buildNamespacedQueueName } from './common';\n\nexport abstract class RedisSubscriber<T> implements OnModuleInit, OnModuleDestroy, QueueSubscriber<T> {\n private readonly logger = new Logger(RedisSubscriber.name);\n private readonly serviceRole: string;\n private client: Redis | null = null;\n private reconnectAttempt = 0;\n private stopping = false;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!process.env.QUEUES_REDIS_URL) {\n this.logger.debug('RedisSubscriber: QUEUES_REDIS_URL is not defined in the environment variables');\n }\n }\n\n abstract subscribe(message: QueueMessage<T>): Promise<any>;\n\n abstract options(): QueuesModuleOptions;\n\n async onModuleInit(): Promise<void> {\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || 'false';\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n if (\n process.env.QUEUES_REDIS_URL &&\n ['both', 'subscriber'].includes(this.serviceRole) &&\n solidCliRunning === 'false' &&\n defaultBroker === 'redis'\n ) {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== 'all') {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(\n `RedisSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`,\n );\n return;\n }\n } catch (error) {\n this.logger.error(\n `Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`,\n );\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n await this.connectAndSubscribe(namespacedQueueName);\n this.logger.log(`RedisSubscriber ready to consume messages: ${JSON.stringify(options)}`);\n }\n }\n\n async onModuleDestroy(): Promise<void> {\n this.stopping = true;\n await this.cleanup();\n }\n\n private async connectAndSubscribe(channel: string): Promise<void> {\n await this.cleanup();\n\n const client = new Redis(process.env.QUEUES_REDIS_URL);\n this.client = client;\n\n client.on('error', (err) => {\n if (client !== this.client) return;\n this.logger.error(`RedisSubscriber connection error for channel ${channel}: ${err.message}`, err.stack);\n });\n\n client.on('close', () => {\n if (client !== this.client) return;\n this.logger.warn(`RedisSubscriber connection closed for channel ${channel}`);\n this.triggerReconnect(channel, 'connection closed');\n });\n\n client.on('message', async (receivedChannel, rawMessage) => {\n if (receivedChannel !== channel) return;\n\n let message: QueueMessage<T> = null;\n try {\n message = JSON.parse(rawMessage) as QueueMessage<T>;\n } catch (error) {\n this.logger.error(`RedisSubscriber invalid JSON on channel ${channel}: ${(error as Error).message}`);\n return;\n }\n\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n try {\n await this.processMessage(message);\n } catch (error) {\n await this.handleProcessingError(message, error, channel);\n }\n });\n\n await client.subscribe(channel);\n this.reconnectAttempt = 0;\n }\n\n private async handleProcessingError(message: QueueMessage<T>, error: any, channel: string): Promise<void> {\n const errorMessage = (error as Error)?.message || String(error);\n this.logger.error(`Error processing message on channel ${channel}: ${errorMessage}`);\n\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n message.currentRetry++;\n this.logger.warn(\n `Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on channel ${channel}`,\n );\n setTimeout(async () => {\n try {\n await this.processMessage(message);\n } catch (retryError) {\n await this.handleProcessingError(message, retryError, channel);\n }\n }, message.retryInterval);\n } else {\n await this.updateStatusInDatabase('failed', message, errorMessage, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts on channel ${channel}: ${errorMessage}`);\n }\n }\n\n private triggerReconnect(channel: string, reason: string): void {\n if (this.stopping) return;\n\n this.reconnectAttempt++;\n const delay = this.backoff();\n this.logger.warn(`RedisSubscriber reconnecting for channel ${channel} (${reason}) in ${delay}ms`);\n\n setTimeout(async () => {\n if (this.stopping) return;\n try {\n await this.connectAndSubscribe(channel);\n this.logger.log(`RedisSubscriber reconnected for channel ${channel}`);\n } catch (err) {\n this.triggerReconnect(channel, `reconnect failed: ${(err as Error).message}`);\n }\n }, delay);\n }\n\n private async cleanup(): Promise<void> {\n const client = this.client;\n this.client = null;\n\n if (client) {\n try {\n await client.quit();\n } catch (_) {\n // ignore\n }\n }\n }\n\n private backoff(): number {\n const baseMs = 1000;\n const maxMs = 30_000;\n const exp = Math.min(maxMs, baseMs * Math.pow(2, this.reconnectAttempt));\n const jitter = Math.floor(Math.random() * (exp * 0.2));\n return Math.min(maxMs, exp + jitter);\n }\n\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n const result: any = await (this.subscribe(message) as any);\n await this.updateStatusInDatabase('succeeded', message, '', result != null ? JSON.stringify(result, null, 2) : '');\n }\n\n private async updateStatusInDatabase(\n stage: string,\n message: QueueMessage<T>,\n error: string = '',\n result: string = '',\n ): Promise<void> {\n try {\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: { messageId: message.messageId },\n });\n\n if (mqMessage) {\n const updatedFields: Record<string, any> = { stage };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') updatedFields['output'] = result;\n if (stage === 'failed') updatedFields['error'] = error;\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n } catch (err) {\n this.logger.error(err.message, err.stack);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"redis-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/redis-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';\nimport Redis from 'ioredis';\nimport { QueuesModuleOptions } from '../../interfaces';\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { buildNamespacedQueueName } from './common';\n\nexport abstract class RedisSubscriber<T> implements OnModuleInit, OnModuleDestroy, QueueSubscriber<T> {\n private readonly logger = new Logger(RedisSubscriber.name);\n private readonly serviceRole: string;\n private client: Redis | null = null;\n private reconnectAttempt = 0;\n private stopping = false;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE || 'both';\n if (!process.env.QUEUES_SERVICE_ROLE) {\n this.logger.debug('QUEUES_SERVICE_ROLE is not defined. Defaulting RedisSubscriber service role to \"both\".');\n }\n if (!process.env.QUEUES_REDIS_URL) {\n this.logger.debug('RedisSubscriber: QUEUES_REDIS_URL is not defined in the environment variables');\n }\n }\n\n abstract subscribe(message: QueueMessage<T>): Promise<any>;\n\n abstract options(): QueuesModuleOptions;\n\n async onModuleInit(): Promise<void> {\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || 'false';\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n if (\n process.env.QUEUES_REDIS_URL &&\n ['both', 'subscriber'].includes(this.serviceRole) &&\n solidCliRunning === 'false' &&\n defaultBroker === 'redis'\n ) {\n const options = this.options();\n const queueName = options.queueName;\n\n if (queueNameRegex && queueNameRegex !== 'all') {\n try {\n const regex = new RegExp(queueNameRegex);\n if (!regex.test(queueName)) {\n this.logger.log(\n `RedisSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`,\n );\n return;\n }\n } catch (error: any) {\n this.logger.error(\n `Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`,\n );\n return;\n }\n }\n\n const namespacedQueueName = buildNamespacedQueueName(queueName);\n await this.connectAndSubscribe(namespacedQueueName);\n this.logger.log(`RedisSubscriber ready to consume messages: ${JSON.stringify(options)}`);\n }\n }\n\n async onModuleDestroy(): Promise<void> {\n this.stopping = true;\n await this.cleanup();\n }\n\n private async connectAndSubscribe(channel: string): Promise<void> {\n await this.cleanup();\n\n const client = new Redis(process.env.QUEUES_REDIS_URL);\n this.client = client;\n\n client.on('error', (err) => {\n if (client !== this.client) return;\n this.logger.error(`RedisSubscriber connection error for channel ${channel}: ${err.message}`, err.stack);\n });\n\n client.on('close', () => {\n if (client !== this.client) return;\n this.logger.warn(`RedisSubscriber connection closed for channel ${channel}`);\n this.triggerReconnect(channel, 'connection closed');\n });\n\n client.on('message', async (receivedChannel, rawMessage) => {\n if (receivedChannel !== channel) return;\n\n let message: QueueMessage<T> = null;\n try {\n message = JSON.parse(rawMessage) as QueueMessage<T>;\n } catch (error: any) {\n this.logger.error(`RedisSubscriber invalid JSON on channel ${channel}: ${(error as Error).message}`);\n return;\n }\n\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n try {\n await this.processMessage(message);\n } catch (error: any) {\n await this.handleProcessingError(message, error, channel);\n }\n });\n\n await client.subscribe(channel);\n this.reconnectAttempt = 0;\n }\n\n private async handleProcessingError(message: QueueMessage<T>, error: any, channel: string): Promise<void> {\n const errorMessage = (error as Error)?.message || String(error);\n this.logger.error(`Error processing message on channel ${channel}: ${errorMessage}`);\n\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n message.currentRetry++;\n this.logger.warn(\n `Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms on channel ${channel}`,\n );\n setTimeout(async () => {\n try {\n await this.processMessage(message);\n } catch (retryError) {\n await this.handleProcessingError(message, retryError, channel);\n }\n }, message.retryInterval);\n } else {\n await this.updateStatusInDatabase('failed', message, errorMessage, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts on channel ${channel}: ${errorMessage}`);\n }\n }\n\n private triggerReconnect(channel: string, reason: string): void {\n if (this.stopping) return;\n\n this.reconnectAttempt++;\n const delay = this.backoff();\n this.logger.warn(`RedisSubscriber reconnecting for channel ${channel} (${reason}) in ${delay}ms`);\n\n setTimeout(async () => {\n if (this.stopping) return;\n try {\n await this.connectAndSubscribe(channel);\n this.logger.log(`RedisSubscriber reconnected for channel ${channel}`);\n } catch (err: any) {\n this.triggerReconnect(channel, `reconnect failed: ${(err as Error).message}`);\n }\n }, delay);\n }\n\n private async cleanup(): Promise<void> {\n const client = this.client;\n this.client = null;\n\n if (client) {\n try {\n await client.quit();\n } catch (_) {\n // ignore\n }\n }\n }\n\n private backoff(): number {\n const baseMs = 1000;\n const maxMs = 30_000;\n const exp = Math.min(maxMs, baseMs * Math.pow(2, this.reconnectAttempt));\n const jitter = Math.floor(Math.random() * (exp * 0.2));\n return Math.min(maxMs, exp + jitter);\n }\n\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n const result: any = await (this.subscribe(message) as any);\n await this.updateStatusInDatabase('succeeded', message, '', result != null ? JSON.stringify(result, null, 2) : '');\n }\n\n private async updateStatusInDatabase(\n stage: string,\n message: QueueMessage<T>,\n error: string = '',\n result: string = '',\n ): Promise<void> {\n try {\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: { messageId: message.messageId },\n });\n\n if (mqMessage) {\n const updatedFields: Record<string, any> = { stage };\n if (stage === 'failed' || stage === 'succeeded') {\n updatedFields['finishedAt'] = new Date();\n updatedFields['elapsedMillis'] = updatedFields['finishedAt'].getTime() - mqMessage.startedAt.getTime();\n }\n if (stage === 'succeeded') updatedFields['output'] = result;\n if (stage === 'failed') updatedFields['error'] = error;\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n } catch (err: any) {\n this.logger.error(err.message, err.stack);\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-metadata.service.js","sourceRoot":"","sources":["../../src/services/role-metadata.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { EntityManager, In } from 'typeorm';\n\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PermissionMetadataRepository } from 'src/repository/permission-metadata.repository';\nimport { RoleMetadataRepository } from 'src/repository/role-metadata.repository';\nimport { CreateRoleMetadataDto } from '../dtos/create-role-metadata.dto';\nimport { PermissionMetadata } from '../entities/permission-metadata.entity';\nimport { RoleMetadata } from '../entities/role-metadata.entity';\n\n@Injectable()\nexport class RoleMetadataService extends CRUDService<RoleMetadata> {\n private readonly logger = new Logger(RoleMetadataService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(RoleMetadata, 'default')\n // readonly repo: Repository<RoleMetadata>,\n readonly repo: RoleMetadataRepository,\n // @InjectRepository(PermissionMetadata)\n // private readonly permissionRepository: Repository<PermissionMetadata>,\n readonly permissionRepository: PermissionMetadataRepository,\n readonly moduleRef: ModuleRef\n\n ) {\n super(entityManager, repo, 'roleMetadata', 'solid-core', moduleRef);\n }\n\n async findRoleByName(roleName: string) {\n const entity = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n if (!entity) {\n throw new NotFoundException(`Entity #${roleName} not found`);\n }\n return entity;\n }\n\n // OK\n async createRolesIfNotExists(roles: CreateRoleMetadataDto[]) {\n for (let id = 0; id < roles.length; id++) {\n try {\n const roleObj = roles[id];\n // this.logger.log(`Resolving role: ${JSON.stringify(roleObj)}`);\n\n const existingRole = await this.repo.findOne({\n where: {\n name: roleObj.name,\n },\n relations: {},\n });\n\n // Create only if not existing already.\n if (!existingRole) {\n this.logger.debug(`Role ${roleObj.name} does not exist, hence creating`);\n\n let permissions = [];\n\n if (roleObj.permissions && roleObj.permissions.length > 0) {\n await Promise.all(\n roleObj.permissions.map(permission => this.preloadPermissionByName(permission.name)),\n );\n }\n\n // const role = this.repo.create({ ...roleObj, permissions });\n const role = this.repo.create({ ...roleObj });\n await this.repo.save(role);\n } else {\n /*\n this.logger.debug(`Role ${roleObj.name} already exists`);\n const existingPermissions = existingRole.permissions.map(permission => permission.name);\n const newPermissions = roleObj.permissions.map(permission => permission.name);\n const permissionsToAdd = newPermissions.filter(permission => !existingPermissions.includes(permission));\n const permissionsToRemove = existingPermissions.filter(permission => !newPermissions.includes(permission));\n this.logger.debug(`Permissions to add: ${JSON.stringify(permissionsToAdd)}`);\n if (permissionsToAdd.length > 0) {\n await this.addPermissionsToRole(roleObj.name, permissionsToAdd);\n }\n this.logger.debug(`Permissions to remove: ${JSON.stringify(permissionsToRemove)}`);\n if (permissionsToRemove.length > 0) {\n await this.removePermissionsFromRole(roleObj.name, permissionsToRemove);\n }\n */\n }\n } catch (error) {\n this.logger.error(error);\n }\n }\n }\n\n async addAllPermissionsToRole(roleName: string): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, null);\n }\n\n async addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, permissionNames);\n }\n\n async addPermissionToRole(roleName: string, permissionName: string[]) {\n return await this._addPermissionsToRole(roleName, permissionName);\n }\n\n private async _addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n const role = await this.repo.findOne({\n where: { name: roleName },\n relations: {\n permissions: true\n }\n });\n if (!role) {\n throw new Error(`Role '${roleName}' not found.`);\n }\n\n // this.logger.log(`Found role ${roleName}`);\n\n // The new set of permissions which are to be added to this role.\n let newPermissions: PermissionMetadata[];\n\n // Load all the specified permissions in the system. \n if (permissionNames && permissionNames.length != 0) {\n // this.logger.log(`Loading specified permissions.`);\n\n newPermissions = await this.permissionRepository.find({ where: { name: In(permissionNames) } });\n if (newPermissions.length !== permissionNames.length) {\n throw new Error(`One or more permissions not found.`);\n }\n }\n else {\n // this.logger.log(`Loading all permissions in system.`);\n\n // Load all permissions in the system. \n // TODO: Do we want to convert this to a paginated query to avoid having to load a very large permissions table into memory?\n newPermissions = await this.permissionRepository.find();\n if (newPermissions.length == 0) {\n throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);\n }\n }\n\n // this.logger.log(`Adding ${newPermissions.length} permissions to role ${roleName}.`);\n\n // if there are already permissions assigned. \n if (role.permissions && role.permissions.length > 0) {\n for (let i = 0; i < newPermissions.length; i++) {\n const newPermission = newPermissions[i];\n let newPermissionFound = true;\n for (let j = 0; j < role.permissions.length; j++) {\n const existingPermission = role.permissions[j];\n if (existingPermission.name === newPermission.name) {\n newPermissionFound = false;\n break;\n }\n }\n\n if (newPermissionFound) {\n role.permissions.push(newPermission);\n }\n }\n\n }\n // else we create a new permissions set. \n else {\n role.permissions = newPermissions;\n }\n\n return await this.repo.save(role);\n }\n\n async removePermissionsFromRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n\n // load the role with the respective permissions.\n const role = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n\n if (!role) {\n throw new Error(ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));\n }\n\n // modify the permissions array.\n role.permissions = role.permissions.filter(permission => !permissionNames.includes(permission.name));\n\n return await this.repo.save(role);\n }\n\n private async preloadPermissionByName(name: string): Promise<PermissionMetadata> {\n const existingPermission = await this.permissionRepository.findOne({\n where: { name },\n });\n if (!existingPermission) {\n throw new NotFoundException(ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));\n }\n return existingPermission;\n }\n\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"role-metadata.service.js","sourceRoot":"","sources":["../../src/services/role-metadata.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAuE;AACvE,uCAAyC;AACzC,6CAAsD;AACtD,iDAAwD;AACxD,qCAA4C;AAE5C,gEAA8D;AAC9D,iGAA6F;AAC7F,qFAAiF;AAM1E,IAAM,mBAAmB,2BAAzB,MAAM,mBAAoB,SAAQ,0BAAyB;IAGhE,YAEE,aAAqC,EAG5B,IAA4B,EAG5B,oBAAkD,EAClD,SAAoB;QAG7B,KAAK,CAAC,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QAV3D,kBAAa,GAAb,aAAa,CAAe;QAG5B,SAAI,GAAJ,IAAI,CAAwB;QAG5B,yBAAoB,GAApB,oBAAoB,CAA8B;QAClD,cAAS,GAAT,SAAS,CAAW;QAXd,WAAM,GAAG,IAAI,eAAM,CAAC,qBAAmB,CAAC,IAAI,CAAC,CAAC;IAe/D,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACrC,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;aACf;YACD,SAAS,EAAE;gBACT,WAAW,EAAE,IAAI;aAClB;SACF,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,0BAAiB,CAAC,WAAW,QAAQ,YAAY,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD,KAAK,CAAC,sBAAsB,CAAC,KAA8B;QACzD,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;gBAG1B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;oBAC3C,KAAK,EAAE;wBACL,IAAI,EAAE,OAAO,CAAC,IAAI;qBACnB;oBACD,SAAS,EAAE,EAAE;iBACd,CAAC,CAAC;gBAGH,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,OAAO,CAAC,IAAI,iCAAiC,CAAC,CAAC;oBAEzE,IAAI,WAAW,GAAG,EAAE,CAAC;oBAErB,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC1D,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CACrF,CAAC;oBACJ,CAAC;oBAGD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;oBAC9C,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;gBAgBR,CAAC;YACH,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,QAAgB;QAC5C,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,QAAgB,EAAE,eAAyB;QACpE,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,QAAgB,EAAE,cAAwB;QAClE,OAAO,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACpE,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,QAAgB,EAAE,eAAyB;QAC7E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACnC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACzB,SAAS,EAAE;gBACT,WAAW,EAAE,IAAI;aAClB;SACF,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,SAAS,QAAQ,cAAc,CAAC,CAAC;QACnD,CAAC;QAKD,IAAI,cAAoC,CAAC;QAGzC,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAGnD,cAAc,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAA,YAAE,EAAC,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC;YAChG,IAAI,cAAc,CAAC,MAAM,KAAK,eAAe,CAAC,MAAM,EAAE,CAAC;gBACrD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;aACI,CAAC;YAKJ,cAAc,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;YACxD,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;YACjH,CAAC;QACH,CAAC;QAKD,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,kBAAkB,GAAG,IAAI,CAAC;gBAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;oBAC/C,IAAI,kBAAkB,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;wBACnD,kBAAkB,GAAG,KAAK,CAAC;wBAC3B,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,kBAAkB,EAAE,CAAC;oBACvB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;QAEH,CAAC;aAEI,CAAC;YACJ,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC;QACpC,CAAC;QAED,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,QAAgB,EAAE,eAAyB;QAGzE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACnC,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;aACf;YACD,SAAS,EAAE;gBACT,WAAW,EAAE,IAAI;aAClB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,+BAAc,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3D,CAAC;QAGD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAErG,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,IAAY;QAChD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;YACjE,KAAK,EAAE,EAAE,IAAI,EAAE;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,MAAM,IAAI,0BAAiB,CAAC,+BAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;CAGF,CAAA;AAnMY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,6BAAmB,GAAE,CAAA;qCACE,uBAAa;QAGtB,iDAAsB;QAGN,6DAA4B;QACvC,gBAAS;GAZpB,mBAAmB,CAmM/B","sourcesContent":["import { Injectable, Logger, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { CRUDService } from 'src/services/crud.service';\nimport { EntityManager, In } from 'typeorm';\n\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PermissionMetadataRepository } from 'src/repository/permission-metadata.repository';\nimport { RoleMetadataRepository } from 'src/repository/role-metadata.repository';\nimport { CreateRoleMetadataDto } from '../dtos/create-role-metadata.dto';\nimport { PermissionMetadata } from '../entities/permission-metadata.entity';\nimport { RoleMetadata } from '../entities/role-metadata.entity';\n\n@Injectable()\nexport class RoleMetadataService extends CRUDService<RoleMetadata> {\n private readonly logger = new Logger(RoleMetadataService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(RoleMetadata, 'default')\n // readonly repo: Repository<RoleMetadata>,\n readonly repo: RoleMetadataRepository,\n // @InjectRepository(PermissionMetadata)\n // private readonly permissionRepository: Repository<PermissionMetadata>,\n readonly permissionRepository: PermissionMetadataRepository,\n readonly moduleRef: ModuleRef\n\n ) {\n super(entityManager, repo, 'roleMetadata', 'solid-core', moduleRef);\n }\n\n async findRoleByName(roleName: string) {\n const entity = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n if (!entity) {\n throw new NotFoundException(`Entity #${roleName} not found`);\n }\n return entity;\n }\n\n // OK\n async createRolesIfNotExists(roles: CreateRoleMetadataDto[]) {\n for (let id = 0; id < roles.length; id++) {\n try {\n const roleObj = roles[id];\n // this.logger.log(`Resolving role: ${JSON.stringify(roleObj)}`);\n\n const existingRole = await this.repo.findOne({\n where: {\n name: roleObj.name,\n },\n relations: {},\n });\n\n // Create only if not existing already.\n if (!existingRole) {\n this.logger.debug(`Role ${roleObj.name} does not exist, hence creating`);\n\n let permissions = [];\n\n if (roleObj.permissions && roleObj.permissions.length > 0) {\n await Promise.all(\n roleObj.permissions.map(permission => this.preloadPermissionByName(permission.name)),\n );\n }\n\n // const role = this.repo.create({ ...roleObj, permissions });\n const role = this.repo.create({ ...roleObj });\n await this.repo.save(role);\n } else {\n /*\n this.logger.debug(`Role ${roleObj.name} already exists`);\n const existingPermissions = existingRole.permissions.map(permission => permission.name);\n const newPermissions = roleObj.permissions.map(permission => permission.name);\n const permissionsToAdd = newPermissions.filter(permission => !existingPermissions.includes(permission));\n const permissionsToRemove = existingPermissions.filter(permission => !newPermissions.includes(permission));\n this.logger.debug(`Permissions to add: ${JSON.stringify(permissionsToAdd)}`);\n if (permissionsToAdd.length > 0) {\n await this.addPermissionsToRole(roleObj.name, permissionsToAdd);\n }\n this.logger.debug(`Permissions to remove: ${JSON.stringify(permissionsToRemove)}`);\n if (permissionsToRemove.length > 0) {\n await this.removePermissionsFromRole(roleObj.name, permissionsToRemove);\n }\n */\n }\n } catch (error: any) {\n this.logger.error(error);\n }\n }\n }\n\n async addAllPermissionsToRole(roleName: string): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, null);\n }\n\n async addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n return await this._addPermissionsToRole(roleName, permissionNames);\n }\n\n async addPermissionToRole(roleName: string, permissionName: string[]) {\n return await this._addPermissionsToRole(roleName, permissionName);\n }\n\n private async _addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n const role = await this.repo.findOne({\n where: { name: roleName },\n relations: {\n permissions: true\n }\n });\n if (!role) {\n throw new Error(`Role '${roleName}' not found.`);\n }\n\n // this.logger.log(`Found role ${roleName}`);\n\n // The new set of permissions which are to be added to this role.\n let newPermissions: PermissionMetadata[];\n\n // Load all the specified permissions in the system. \n if (permissionNames && permissionNames.length != 0) {\n // this.logger.log(`Loading specified permissions.`);\n\n newPermissions = await this.permissionRepository.find({ where: { name: In(permissionNames) } });\n if (newPermissions.length !== permissionNames.length) {\n throw new Error(`One or more permissions not found.`);\n }\n }\n else {\n // this.logger.log(`Loading all permissions in system.`);\n\n // Load all permissions in the system. \n // TODO: Do we want to convert this to a paginated query to avoid having to load a very large permissions table into memory?\n newPermissions = await this.permissionRepository.find();\n if (newPermissions.length == 0) {\n throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);\n }\n }\n\n // this.logger.log(`Adding ${newPermissions.length} permissions to role ${roleName}.`);\n\n // if there are already permissions assigned. \n if (role.permissions && role.permissions.length > 0) {\n for (let i = 0; i < newPermissions.length; i++) {\n const newPermission = newPermissions[i];\n let newPermissionFound = true;\n for (let j = 0; j < role.permissions.length; j++) {\n const existingPermission = role.permissions[j];\n if (existingPermission.name === newPermission.name) {\n newPermissionFound = false;\n break;\n }\n }\n\n if (newPermissionFound) {\n role.permissions.push(newPermission);\n }\n }\n\n }\n // else we create a new permissions set. \n else {\n role.permissions = newPermissions;\n }\n\n return await this.repo.save(role);\n }\n\n async removePermissionsFromRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {\n\n // load the role with the respective permissions.\n const role = await this.repo.findOne({\n where: {\n name: roleName\n },\n relations: {\n permissions: true\n }\n });\n\n if (!role) {\n throw new Error(ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));\n }\n\n // modify the permissions array.\n role.permissions = role.permissions.filter(permission => !permissionNames.includes(permission.name));\n\n return await this.repo.save(role);\n }\n\n private async preloadPermissionByName(name: string): Promise<PermissionMetadata> {\n const existingPermission = await this.permissionRepository.findOne({\n where: { name },\n });\n if (!existingPermission) {\n throw new NotFoundException(ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));\n }\n return existingPermission;\n }\n\n\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.service.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { IsNull, LessThanOrEqual } from 'typeorm';\n\nimport { Cron, CronExpression } from '@nestjs/schedule';\nimport { ScheduledJob } from 'src/entities/scheduled-job.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ScheduledJobRepository } from 'src/repository/scheduled-job.repository';\nimport { ISchedulerService } from './scheduler.interface';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class SchedulerServiceImpl implements ISchedulerService {\n private readonly logger = new Logger(SchedulerServiceImpl.name);\n private readonly runningJobs = new Set<string>();\n\n constructor(\n // @InjectRepository(ScheduledJob)\n // private readonly scheduledJobRepo: Repository<ScheduledJob>,\n private readonly scheduledJobRepo: ScheduledJobRepository,\n private readonly solidRegistry: SolidRegistry,\n ) { }\n\n @Cron(CronExpression.EVERY_MINUTE)\n async runScheduledJobs(): Promise<void> {\n const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || \"true\";\n if (solidSchedulerEnabled.toLowerCase() !== \"true\") {\n this.logger.debug('Solid scheduler is disabled via environment variable');\n return;\n }\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n if (solidCliRunning === \"true\") {\n return;\n }\n const jobsRegexToEnable = (process.env.SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE || '').trim();\n let jobsRegex: RegExp | null = null;\n if (jobsRegexToEnable && jobsRegexToEnable !== \"all\") {\n try {\n jobsRegex = new RegExp(jobsRegexToEnable);\n } catch (error) {\n this.logger.error(`Invalid SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE regex \"${jobsRegexToEnable}\". Scheduler loop will skip this run.`);\n return;\n }\n }\n\n const now = new Date();\n\n // this.logger.log(`[${now.getTime()}]: scheduler service started run...`);\n const dueJobs = await this.scheduledJobRepo.find({\n where: [\n {\n isActive: true,\n nextRunAt: LessThanOrEqual(now),\n },\n // Newly created jobs are also picked for examination \n {\n isActive: true,\n nextRunAt: IsNull(),\n },\n ],\n });\n\n // this.logger.log(`[${now.getTime()}]: scheduler service identified ${dueJobs.length} jobs to run...`);\n\n for (const job of dueJobs) {\n const jobKey = String(job.id ?? job.scheduleName ?? job.job);\n const jobName = String(job.job ?? '');\n\n if (jobsRegex && !jobsRegex.test(jobName)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${jobName} because it does not match SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE=${jobsRegexToEnable}`);\n continue;\n }\n\n if (this.runningJobs.has(jobKey)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);\n continue;\n }\n\n if (!this.shouldRunNow(job, now)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job}`);\n continue;\n }\n\n const handler = this.solidRegistry.getScheduledJobProviderInstance(job.job);\n if (!handler) {\n this.logger.warn(`[${now.getTime()}]: scheduler service skipping because job handler not found: ${job.job}`);\n continue;\n }\n\n this.runningJobs.add(jobKey);\n this.logger.log(`[${now.getTime()}]: scheduler service attempting to run job ${job.job}`);\n try {\n // this.logger.log(`[${now.getTime()}]: scheduler service about to run job ${job.job}`);\n await handler.execute(job);\n // this.logger.log(`[${now.getTime()}]: scheduler service finished running job ${job.job}`);\n\n job.isActive = true;\n const finishedAt = new Date();\n job.lastRunAt = finishedAt;\n job.nextRunAt = this.computeNextRunAt(job, finishedAt);\n this.logger.log(`[${now.getTime()}]: scheduler service coomputed next run for ${job.job} as ${job.nextRunAt}`);\n\n await this.scheduledJobRepo.save(job);\n this.logger.log(`[${now.getTime()}]: scheduler service finished running job: ${job.job}`);\n } catch (err) {\n this.logger.error(`[${now.getTime()}]: scheduler service failed to run job ${job.job}`, err.stack);\n } finally {\n this.runningJobs.delete(jobKey);\n }\n }\n }\n\n private shouldRunNow(job: ScheduledJob, now: Date): boolean {\n const today = new Date(now);\n today.setHours(0, 0, 0, 0);\n const timeNow = this.toHHMM(now); // hh:mm\n\n // 1. Check startDate / endDate\n const startDate = this.toDateOnly(job.startDate as unknown as Date | string | null);\n const endDate = this.toDateOnly(job.endDate as unknown as Date | string | null);\n if (startDate && today < startDate) return false;\n if (endDate && today > endDate) return false;\n\n // 2. Check startTime / endTime\n const jobStart = this.toHHMM(job.startTime as unknown as Date | string | null);\n const jobEnd = this.toHHMM(job.endTime as unknown as Date | string | null);\n if (jobStart && timeNow < jobStart) return false;\n if (jobEnd && timeNow > jobEnd) return false;\n\n // 3. Check custom frequency\n if (job.frequency.toLowerCase() === 'custom') {\n // Custom cron expressions handle their own scheduling logic\n // Just check if nextRunAt is due, which was already checked in the query\n return true;\n }\n\n // 3. Check dayOfWeek (for weekly)\n if (job.frequency.toLowerCase() === 'weekly' && job.dayOfWeek) {\n const todayName = now.toLocaleString('en-US', { weekday: 'long' }); // e.g., \"Monday\"\n const days = this.parseDayOfWeek(job.dayOfWeek);\n if (!days.includes(todayName)) return false;\n }\n\n // 4. Check dayOfMonth (for monthly)\n if (job.frequency.toLowerCase() === 'monthly' && job.dayOfMonth) {\n const dom = now.getDate();\n if (dom !== job.dayOfMonth) return false;\n }\n\n return true;\n }\n\n private parseDayOfWeek(dayOfWeek: string): string[] {\n try {\n const parsed = JSON.parse(dayOfWeek);\n return Array.isArray(parsed) ? parsed : [];\n } catch (error) {\n this.logger.warn(`Invalid dayOfWeek JSON '${dayOfWeek}'`, error as any);\n return [];\n }\n }\n\n private toDateOnly(value: Date | string | null | undefined): Date | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n const d = new Date(value);\n d.setHours(0, 0, 0, 0);\n return d;\n }\n\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return null;\n\n parsed.setHours(0, 0, 0, 0);\n return parsed;\n }\n\n private toHHMM(value: Date | string | null | undefined): string | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n return value.toTimeString().slice(0, 5);\n }\n\n if (typeof value === 'string') {\n const match = value.match(/^(\\d{2}):(\\d{2})/);\n if (match) return `${match[1]}:${match[2]}`;\n\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toTimeString().slice(0, 5);\n }\n }\n\n return null;\n }\n\n public computeNextRunForCustomCron(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n if (!job.cronExpression) {\n this.logger.error(`Custom frequency requires cronExpression for job ${job.scheduleName}`);\n // Fallback to daily if cron expression is missing\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n\n try {\n const interval = CronExpressionParser.parse(job.cronExpression, {\n currentDate: from,\n tz: 'UTC'\n });\n const nextRun = interval.next().toDate();\n const runAfterNext = interval.next().toDate();\n\n // Validate minimum 1 minute cadence between consecutive runs.\n // Comparing nextRun to \"from\" is incorrect near minute boundaries.\n if (runAfterNext.getTime() - nextRun.getTime() < 60000) {\n throw new Error('Cron expression interval must be at least 1 minute');\n }\n \n this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);\n return nextRun;\n } catch (error) {\n this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}. Reason: ${(error as Error).message}`);\n // Fallback to daily if cron parsing fails\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n\n public computeNextRunAt(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n switch (job.frequency.toLowerCase()) {\n // case 'once':\n // return null; // don't reschedule\n case 'every minute':\n return new Date(base.getTime() + 1 * 60 * 1000);\n case 'hourly':\n return new Date(base.getTime() + 60 * 60 * 1000);\n case 'daily':\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n case 'weekly':\n return new Date(base.getTime() + 7 * 24 * 60 * 60 * 1000);\n case 'monthly':\n const next = new Date(base);\n next.setMonth(base.getMonth() + 1);\n return next;\n case 'custom':\n return this.computeNextRunForCustomCron(job, from);\n default:\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scheduler.service.js","sourceRoot":"","sources":["../../../src/services/scheduled-jobs/scheduler.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,qCAAkD;AAElD,+CAAwD;AAExD,iEAA2D;AAC3D,wFAAiF;AAEjF,6CAAmD;AAG5C,IAAM,oBAAoB,4BAA1B,MAAM,oBAAoB;IAI7B,YAGqB,gBAAwC,EACxC,aAA4B;QAD5B,qBAAgB,GAAhB,gBAAgB,CAAwB;QACxC,kBAAa,GAAb,aAAa,CAAe;QAPhC,WAAM,GAAG,IAAI,eAAM,CAAC,sBAAoB,CAAC,IAAI,CAAC,CAAC;QAC/C,gBAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAO7C,CAAC;IAGC,AAAN,KAAK,CAAC,gBAAgB;QAClB,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,MAAM,CAAC;QAC5E,IAAI,qBAAqB,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,OAAO;QACX,CAAC;QACD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC;QACjE,IAAI,eAAe,KAAK,MAAM,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QACD,MAAM,iBAAiB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1F,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,IAAI,iBAAiB,IAAI,iBAAiB,KAAK,KAAK,EAAE,CAAC;YACnD,IAAI,CAAC;gBACD,SAAS,GAAG,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,iBAAiB,uCAAuC,CAAC,CAAC;gBACnI,OAAO;YACX,CAAC;QACL,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAGvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAC7C,KAAK,EAAE;gBACH;oBACI,QAAQ,EAAE,IAAI;oBACd,SAAS,EAAE,IAAA,yBAAe,EAAC,GAAG,CAAC;iBAClC;gBAED;oBACI,QAAQ,EAAE,IAAI;oBACd,SAAS,EAAE,IAAA,gBAAM,GAAE;iBACtB;aACJ;SACJ,CAAC,CAAC;QAIH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;YAEtC,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,qCAAqC,OAAO,mEAAmE,iBAAiB,EAAE,CAAC,CAAC;gBACrK,SAAS;YACb,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,qCAAqC,GAAG,CAAC,GAAG,uCAAuC,CAAC,CAAC;gBACtH,SAAS;YACb,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,qCAAqC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;gBACjF,SAAS;YACb,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,gEAAgE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC7G,SAAS;YACb,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,8CAA8C,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1F,IAAI,CAAC;gBAED,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAG3B,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACpB,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC9B,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC;gBAC3B,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;gBACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,+CAA+C,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;gBAE/G,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,8CAA8C,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC9F,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,0CAA0C,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YACvG,CAAC;oBAAS,CAAC;gBACP,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,GAAiB,EAAE,GAAS;QAC7C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAGjC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAA4C,CAAC,CAAC;QACpF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAA0C,CAAC,CAAC;QAChF,IAAI,SAAS,IAAI,KAAK,GAAG,SAAS;YAAE,OAAO,KAAK,CAAC;QACjD,IAAI,OAAO,IAAI,KAAK,GAAG,OAAO;YAAE,OAAO,KAAK,CAAC;QAG7C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAA4C,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAA0C,CAAC,CAAC;QAC3E,IAAI,QAAQ,IAAI,OAAO,GAAG,QAAQ;YAAE,OAAO,KAAK,CAAC;QACjD,IAAI,MAAM,IAAI,OAAO,GAAG,MAAM;YAAE,OAAO,KAAK,CAAC;QAG7C,IAAI,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;YAG3C,OAAO,IAAI,CAAC;QAChB,CAAC;QAGD,IAAI,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACnE,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChD,CAAC;QAGD,IAAI,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,GAAG,KAAK,GAAG,CAAC,UAAU;gBAAE,OAAO,KAAK,CAAC;QAC7C,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,cAAc,CAAC,SAAiB;QACpC,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACrC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,SAAS,GAAG,EAAE,KAAY,CAAC,CAAC;YACxE,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,KAAuC;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvB,OAAO,CAAC,CAAC;QACb,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QAEhD,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,MAAM,CAAC,KAAuC;QAClD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC9C,IAAI,KAAK;gBAAE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAE5C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;gBAClC,OAAO,MAAM,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,2BAA2B,CAAC,GAAiB,EAAE,IAAU;QAC5D,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5B,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YAE1F,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,kCAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE;gBAC5D,WAAW,EAAE,IAAI;gBACjB,EAAE,EAAE,KAAK;aACZ,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YAI9C,IAAI,YAAY,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;gBACrD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YAC1E,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,cAAc,eAAe,OAAO,EAAE,CAAC,CAAC;YAC5E,OAAO,OAAO,CAAC;QACnB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,cAAc,aAAc,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAErI,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAEM,gBAAgB,CAAC,GAAiB,EAAE,IAAU;QACjD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5B,QAAQ,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAGlC,KAAK,cAAc;gBACf,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YACpD,KAAK,QAAQ;gBACT,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YACrD,KAAK,OAAO;gBACR,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC1D,KAAK,QAAQ;gBACT,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC9D,KAAK,SAAS;gBACV,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;gBACnC,OAAO,IAAI,CAAC;YAChB,KAAK,QAAQ;gBACT,OAAO,IAAI,CAAC,2BAA2B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACvD;gBACI,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;CACJ,CAAA;AAlPY,oDAAoB;AAYvB;IADL,IAAA,eAAI,EAAC,yBAAc,CAAC,YAAY,CAAC;;;;4DAuFjC;+BAlGQ,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAQ8B,iDAAsB;QACzB,8BAAa;GARxC,oBAAoB,CAkPhC","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { IsNull, LessThanOrEqual } from 'typeorm';\n\nimport { Cron, CronExpression } from '@nestjs/schedule';\nimport { ScheduledJob } from 'src/entities/scheduled-job.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ScheduledJobRepository } from 'src/repository/scheduled-job.repository';\nimport { ISchedulerService } from './scheduler.interface';\nimport { CronExpressionParser } from 'cron-parser';\n\n@Injectable()\nexport class SchedulerServiceImpl implements ISchedulerService {\n private readonly logger = new Logger(SchedulerServiceImpl.name);\n private readonly runningJobs = new Set<string>();\n\n constructor(\n // @InjectRepository(ScheduledJob)\n // private readonly scheduledJobRepo: Repository<ScheduledJob>,\n private readonly scheduledJobRepo: ScheduledJobRepository,\n private readonly solidRegistry: SolidRegistry,\n ) { }\n\n @Cron(CronExpression.EVERY_MINUTE)\n async runScheduledJobs(): Promise<void> {\n const solidSchedulerEnabled = process.env.SOLID_SCHEDULER_ENABLED || \"true\";\n if (solidSchedulerEnabled.toLowerCase() !== \"true\") {\n this.logger.debug('Solid scheduler is disabled via environment variable');\n return;\n }\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n if (solidCliRunning === \"true\") {\n return;\n }\n const jobsRegexToEnable = (process.env.SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE || '').trim();\n let jobsRegex: RegExp | null = null;\n if (jobsRegexToEnable && jobsRegexToEnable !== \"all\") {\n try {\n jobsRegex = new RegExp(jobsRegexToEnable);\n } catch (error: any) {\n this.logger.error(`Invalid SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE regex \"${jobsRegexToEnable}\". Scheduler loop will skip this run.`);\n return;\n }\n }\n\n const now = new Date();\n\n // this.logger.log(`[${now.getTime()}]: scheduler service started run...`);\n const dueJobs = await this.scheduledJobRepo.find({\n where: [\n {\n isActive: true,\n nextRunAt: LessThanOrEqual(now),\n },\n // Newly created jobs are also picked for examination \n {\n isActive: true,\n nextRunAt: IsNull(),\n },\n ],\n });\n\n // this.logger.log(`[${now.getTime()}]: scheduler service identified ${dueJobs.length} jobs to run...`);\n\n for (const job of dueJobs) {\n const jobKey = String(job.id ?? job.scheduleName ?? job.job);\n const jobName = String(job.job ?? '');\n\n if (jobsRegex && !jobsRegex.test(jobName)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${jobName} because it does not match SOLID_SCHEDULER_JOBS_REGEX_TO_ENABLE=${jobsRegexToEnable}`);\n continue;\n }\n\n if (this.runningJobs.has(jobKey)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job} because a run is already in progress`);\n continue;\n }\n\n if (!this.shouldRunNow(job, now)) {\n this.logger.log(`[${now.getTime()}]: scheduler service skipping job ${job.job}`);\n continue;\n }\n\n const handler = this.solidRegistry.getScheduledJobProviderInstance(job.job);\n if (!handler) {\n this.logger.warn(`[${now.getTime()}]: scheduler service skipping because job handler not found: ${job.job}`);\n continue;\n }\n\n this.runningJobs.add(jobKey);\n this.logger.log(`[${now.getTime()}]: scheduler service attempting to run job ${job.job}`);\n try {\n // this.logger.log(`[${now.getTime()}]: scheduler service about to run job ${job.job}`);\n await handler.execute(job);\n // this.logger.log(`[${now.getTime()}]: scheduler service finished running job ${job.job}`);\n\n job.isActive = true;\n const finishedAt = new Date();\n job.lastRunAt = finishedAt;\n job.nextRunAt = this.computeNextRunAt(job, finishedAt);\n this.logger.log(`[${now.getTime()}]: scheduler service coomputed next run for ${job.job} as ${job.nextRunAt}`);\n\n await this.scheduledJobRepo.save(job);\n this.logger.log(`[${now.getTime()}]: scheduler service finished running job: ${job.job}`);\n } catch (err: any) {\n this.logger.error(`[${now.getTime()}]: scheduler service failed to run job ${job.job}`, err.stack);\n } finally {\n this.runningJobs.delete(jobKey);\n }\n }\n }\n\n private shouldRunNow(job: ScheduledJob, now: Date): boolean {\n const today = new Date(now);\n today.setHours(0, 0, 0, 0);\n const timeNow = this.toHHMM(now); // hh:mm\n\n // 1. Check startDate / endDate\n const startDate = this.toDateOnly(job.startDate as unknown as Date | string | null);\n const endDate = this.toDateOnly(job.endDate as unknown as Date | string | null);\n if (startDate && today < startDate) return false;\n if (endDate && today > endDate) return false;\n\n // 2. Check startTime / endTime\n const jobStart = this.toHHMM(job.startTime as unknown as Date | string | null);\n const jobEnd = this.toHHMM(job.endTime as unknown as Date | string | null);\n if (jobStart && timeNow < jobStart) return false;\n if (jobEnd && timeNow > jobEnd) return false;\n\n // 3. Check custom frequency\n if (job.frequency.toLowerCase() === 'custom') {\n // Custom cron expressions handle their own scheduling logic\n // Just check if nextRunAt is due, which was already checked in the query\n return true;\n }\n\n // 3. Check dayOfWeek (for weekly)\n if (job.frequency.toLowerCase() === 'weekly' && job.dayOfWeek) {\n const todayName = now.toLocaleString('en-US', { weekday: 'long' }); // e.g., \"Monday\"\n const days = this.parseDayOfWeek(job.dayOfWeek);\n if (!days.includes(todayName)) return false;\n }\n\n // 4. Check dayOfMonth (for monthly)\n if (job.frequency.toLowerCase() === 'monthly' && job.dayOfMonth) {\n const dom = now.getDate();\n if (dom !== job.dayOfMonth) return false;\n }\n\n return true;\n }\n\n private parseDayOfWeek(dayOfWeek: string): string[] {\n try {\n const parsed = JSON.parse(dayOfWeek);\n return Array.isArray(parsed) ? parsed : [];\n } catch (error: any) {\n this.logger.warn(`Invalid dayOfWeek JSON '${dayOfWeek}'`, error as any);\n return [];\n }\n }\n\n private toDateOnly(value: Date | string | null | undefined): Date | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n const d = new Date(value);\n d.setHours(0, 0, 0, 0);\n return d;\n }\n\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return null;\n\n parsed.setHours(0, 0, 0, 0);\n return parsed;\n }\n\n private toHHMM(value: Date | string | null | undefined): string | null {\n if (!value) return null;\n\n if (value instanceof Date) {\n return value.toTimeString().slice(0, 5);\n }\n\n if (typeof value === 'string') {\n const match = value.match(/^(\\d{2}):(\\d{2})/);\n if (match) return `${match[1]}:${match[2]}`;\n\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed.toTimeString().slice(0, 5);\n }\n }\n\n return null;\n }\n\n public computeNextRunForCustomCron(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n if (!job.cronExpression) {\n this.logger.error(`Custom frequency requires cronExpression for job ${job.scheduleName}`);\n // Fallback to daily if cron expression is missing\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n\n try {\n const interval = CronExpressionParser.parse(job.cronExpression, {\n currentDate: from,\n tz: 'UTC'\n });\n const nextRun = interval.next().toDate();\n const runAfterNext = interval.next().toDate();\n\n // Validate minimum 1 minute cadence between consecutive runs.\n // Comparing nextRun to \"from\" is incorrect near minute boundaries.\n if (runAfterNext.getTime() - nextRun.getTime() < 60000) {\n throw new Error('Cron expression interval must be at least 1 minute');\n }\n\n this.logger.log(`Custom cron '${job.cronExpression}' next run: ${nextRun}`);\n return nextRun;\n } catch (error: any) {\n this.logger.error(`Invalid cron expression for job ${job.scheduleName}: ${job.cronExpression}. Reason: ${(error as Error).message}`);\n // Fallback to daily if cron parsing fails\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n\n public computeNextRunAt(job: ScheduledJob, from: Date): Date {\n const base = new Date(from);\n\n switch (job.frequency.toLowerCase()) {\n // case 'once':\n // return null; // don't reschedule\n case 'every minute':\n return new Date(base.getTime() + 1 * 60 * 1000);\n case 'hourly':\n return new Date(base.getTime() + 60 * 60 * 1000);\n case 'daily':\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n case 'weekly':\n return new Date(base.getTime() + 7 * 24 * 60 * 60 * 1000);\n case 'monthly':\n const next = new Date(base);\n next.setMonth(base.getMonth() + 1);\n return next;\n case 'custom':\n return this.computeNextRunForCustomCron(job, from);\n default:\n return new Date(base.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n}\n"]}
|
|
@@ -15,11 +15,19 @@ declare const getSolidCoreSettings: (isProd: boolean) => [{
|
|
|
15
15
|
readonly key: "iamFacebookOAuthEnabled";
|
|
16
16
|
readonly value: false;
|
|
17
17
|
readonly level: SettingLevel.SystemAdminEditable;
|
|
18
|
+
readonly label: "Allow Login / Signup With Facebook";
|
|
19
|
+
readonly group: "authentication-settings";
|
|
20
|
+
readonly sortOrder: 50;
|
|
21
|
+
readonly controlType: "boolean";
|
|
18
22
|
}, {
|
|
19
23
|
readonly moduleName: "solid-core";
|
|
20
24
|
readonly key: "iamMicrosoftOAuthEnabled";
|
|
21
25
|
readonly value: false;
|
|
22
26
|
readonly level: SettingLevel.SystemAdminEditable;
|
|
27
|
+
readonly label: "Allow Login / Signup With Microsoft";
|
|
28
|
+
readonly group: "authentication-settings";
|
|
29
|
+
readonly sortOrder: 50;
|
|
30
|
+
readonly controlType: "boolean";
|
|
23
31
|
}, {
|
|
24
32
|
readonly moduleName: "solid-core";
|
|
25
33
|
readonly key: "authPagesLayout";
|
|
@@ -608,7 +616,14 @@ declare const getSolidCoreSettings: (isProd: boolean) => [{
|
|
|
608
616
|
readonly label: "Registration Validation Type";
|
|
609
617
|
readonly group: "authentication-settings";
|
|
610
618
|
readonly sortOrder: 30;
|
|
611
|
-
readonly controlType: "
|
|
619
|
+
readonly controlType: "selectionStatic";
|
|
620
|
+
readonly options: [{
|
|
621
|
+
readonly label: "Email";
|
|
622
|
+
readonly value: "email";
|
|
623
|
+
}, {
|
|
624
|
+
readonly label: "Mobile";
|
|
625
|
+
readonly value: "mobile";
|
|
626
|
+
}];
|
|
612
627
|
}, {
|
|
613
628
|
readonly moduleName: "solid-core";
|
|
614
629
|
readonly key: "passwordlessLoginValidateWhat";
|
|
@@ -617,7 +632,17 @@ declare const getSolidCoreSettings: (isProd: boolean) => [{
|
|
|
617
632
|
readonly label: "Login Validation Type";
|
|
618
633
|
readonly group: "authentication-settings";
|
|
619
634
|
readonly sortOrder: 40;
|
|
620
|
-
readonly controlType: "
|
|
635
|
+
readonly controlType: "selectionStatic";
|
|
636
|
+
readonly options: [{
|
|
637
|
+
readonly label: "Email";
|
|
638
|
+
readonly value: "email";
|
|
639
|
+
}, {
|
|
640
|
+
readonly label: "Mobile";
|
|
641
|
+
readonly value: "mobile";
|
|
642
|
+
}, {
|
|
643
|
+
readonly label: "Selectable";
|
|
644
|
+
readonly value: "selectable";
|
|
645
|
+
}];
|
|
621
646
|
}, {
|
|
622
647
|
readonly moduleName: "solid-core";
|
|
623
648
|
readonly key: "allowPublicRegistration";
|
|
@@ -747,12 +772,20 @@ declare const getSolidCoreSettings: (isProd: boolean) => [{
|
|
|
747
772
|
readonly moduleName: "solid-core";
|
|
748
773
|
readonly key: "sendWelcomeEmailOnSignup";
|
|
749
774
|
readonly value: boolean;
|
|
750
|
-
readonly level: SettingLevel.
|
|
775
|
+
readonly level: SettingLevel.SystemAdminEditable;
|
|
776
|
+
readonly label: "Send Welcome Email On Signup";
|
|
777
|
+
readonly group: "authentication-settings";
|
|
778
|
+
readonly sortOrder: 180;
|
|
779
|
+
readonly controlType: "boolean";
|
|
751
780
|
}, {
|
|
752
781
|
readonly moduleName: "solid-core";
|
|
753
782
|
readonly key: "sendWelcomeSmsOnSignup";
|
|
754
783
|
readonly value: boolean;
|
|
755
|
-
readonly level: SettingLevel.
|
|
784
|
+
readonly level: SettingLevel.SystemAdminEditable;
|
|
785
|
+
readonly label: "Send Welcome SMS On Signup";
|
|
786
|
+
readonly group: "authentication-settings";
|
|
787
|
+
readonly sortOrder: 190;
|
|
788
|
+
readonly controlType: "boolean";
|
|
756
789
|
}, {
|
|
757
790
|
readonly moduleName: "solid-core";
|
|
758
791
|
readonly key: "frontendLoginPageUrl";
|
|
@@ -984,11 +1017,19 @@ export declare class SolidCoreDefaultSettingsProvider implements ISettingsProvid
|
|
|
984
1017
|
readonly key: "iamFacebookOAuthEnabled";
|
|
985
1018
|
readonly value: false;
|
|
986
1019
|
readonly level: SettingLevel.SystemAdminEditable;
|
|
1020
|
+
readonly label: "Allow Login / Signup With Facebook";
|
|
1021
|
+
readonly group: "authentication-settings";
|
|
1022
|
+
readonly sortOrder: 50;
|
|
1023
|
+
readonly controlType: "boolean";
|
|
987
1024
|
}, {
|
|
988
1025
|
readonly moduleName: "solid-core";
|
|
989
1026
|
readonly key: "iamMicrosoftOAuthEnabled";
|
|
990
1027
|
readonly value: false;
|
|
991
1028
|
readonly level: SettingLevel.SystemAdminEditable;
|
|
1029
|
+
readonly label: "Allow Login / Signup With Microsoft";
|
|
1030
|
+
readonly group: "authentication-settings";
|
|
1031
|
+
readonly sortOrder: 50;
|
|
1032
|
+
readonly controlType: "boolean";
|
|
992
1033
|
}, {
|
|
993
1034
|
readonly moduleName: "solid-core";
|
|
994
1035
|
readonly key: "authPagesLayout";
|
|
@@ -1577,7 +1618,14 @@ export declare class SolidCoreDefaultSettingsProvider implements ISettingsProvid
|
|
|
1577
1618
|
readonly label: "Registration Validation Type";
|
|
1578
1619
|
readonly group: "authentication-settings";
|
|
1579
1620
|
readonly sortOrder: 30;
|
|
1580
|
-
readonly controlType: "
|
|
1621
|
+
readonly controlType: "selectionStatic";
|
|
1622
|
+
readonly options: [{
|
|
1623
|
+
readonly label: "Email";
|
|
1624
|
+
readonly value: "email";
|
|
1625
|
+
}, {
|
|
1626
|
+
readonly label: "Mobile";
|
|
1627
|
+
readonly value: "mobile";
|
|
1628
|
+
}];
|
|
1581
1629
|
}, {
|
|
1582
1630
|
readonly moduleName: "solid-core";
|
|
1583
1631
|
readonly key: "passwordlessLoginValidateWhat";
|
|
@@ -1586,7 +1634,17 @@ export declare class SolidCoreDefaultSettingsProvider implements ISettingsProvid
|
|
|
1586
1634
|
readonly label: "Login Validation Type";
|
|
1587
1635
|
readonly group: "authentication-settings";
|
|
1588
1636
|
readonly sortOrder: 40;
|
|
1589
|
-
readonly controlType: "
|
|
1637
|
+
readonly controlType: "selectionStatic";
|
|
1638
|
+
readonly options: [{
|
|
1639
|
+
readonly label: "Email";
|
|
1640
|
+
readonly value: "email";
|
|
1641
|
+
}, {
|
|
1642
|
+
readonly label: "Mobile";
|
|
1643
|
+
readonly value: "mobile";
|
|
1644
|
+
}, {
|
|
1645
|
+
readonly label: "Selectable";
|
|
1646
|
+
readonly value: "selectable";
|
|
1647
|
+
}];
|
|
1590
1648
|
}, {
|
|
1591
1649
|
readonly moduleName: "solid-core";
|
|
1592
1650
|
readonly key: "allowPublicRegistration";
|
|
@@ -1716,12 +1774,20 @@ export declare class SolidCoreDefaultSettingsProvider implements ISettingsProvid
|
|
|
1716
1774
|
readonly moduleName: "solid-core";
|
|
1717
1775
|
readonly key: "sendWelcomeEmailOnSignup";
|
|
1718
1776
|
readonly value: boolean;
|
|
1719
|
-
readonly level: SettingLevel.
|
|
1777
|
+
readonly level: SettingLevel.SystemAdminEditable;
|
|
1778
|
+
readonly label: "Send Welcome Email On Signup";
|
|
1779
|
+
readonly group: "authentication-settings";
|
|
1780
|
+
readonly sortOrder: 180;
|
|
1781
|
+
readonly controlType: "boolean";
|
|
1720
1782
|
}, {
|
|
1721
1783
|
readonly moduleName: "solid-core";
|
|
1722
1784
|
readonly key: "sendWelcomeSmsOnSignup";
|
|
1723
1785
|
readonly value: boolean;
|
|
1724
|
-
readonly level: SettingLevel.
|
|
1786
|
+
readonly level: SettingLevel.SystemAdminEditable;
|
|
1787
|
+
readonly label: "Send Welcome SMS On Signup";
|
|
1788
|
+
readonly group: "authentication-settings";
|
|
1789
|
+
readonly sortOrder: 190;
|
|
1790
|
+
readonly controlType: "boolean";
|
|
1725
1791
|
}, {
|
|
1726
1792
|
readonly moduleName: "solid-core";
|
|
1727
1793
|
readonly key: "frontendLoginPageUrl";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-settings-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/settings/default-settings-provider.service.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EAEjB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AACxD,eAAO,MAAM,8BAA8B,wBAAwB,CAAC;AAGpE,QAAA,MAAM,oBAAoB,GAAI,QAAQ,OAAO
|
|
1
|
+
{"version":3,"file":"default-settings-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/settings/default-settings-provider.service.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,iBAAiB,EAEjB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AACxD,eAAO,MAAM,8BAA8B,wBAAwB,CAAC;AAGpE,QAAA,MAAM,oBAAoB,GAAI,QAAQ,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+oCH,CAAC;AAG3C,MAAM,MAAM,gBAAgB,GAAG,UAAU,CACvC,OAAO,oBAAoB,CAC5B,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;AAGjB,qBAEa,gCAAiC,YAAW,iBAAiB;IACxE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIZ"}
|