@solidxai/core 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/dist/dtos/create-saved-filters.dto.d.ts.map +1 -1
  2. package/dist/dtos/create-saved-filters.dto.js.map +1 -1
  3. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  4. package/dist/entities/chatter-message.entity.js +2 -0
  5. package/dist/entities/chatter-message.entity.js.map +1 -1
  6. package/dist/helpers/schematic.service.d.ts.map +1 -1
  7. package/dist/helpers/schematic.service.js +5 -1
  8. package/dist/helpers/schematic.service.js.map +1 -1
  9. package/dist/jobs/api-email-queue-options.d.ts.map +1 -1
  10. package/dist/jobs/api-email-queue-options.js +2 -2
  11. package/dist/jobs/api-email-queue-options.js.map +1 -1
  12. package/dist/jobs/chatter-queue-options.js +2 -2
  13. package/dist/jobs/chatter-queue-options.js.map +1 -1
  14. package/dist/jobs/computed-field-evaluation-queue-options.js +2 -2
  15. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
  16. package/dist/jobs/database/api-email-queue-options-database.js +2 -2
  17. package/dist/jobs/database/api-email-queue-options-database.js.map +1 -1
  18. package/dist/jobs/database/computed-field-evaluation-queue-options-database.js +2 -2
  19. package/dist/jobs/database/computed-field-evaluation-queue-options-database.js.map +1 -1
  20. package/dist/jobs/database/generate-code-queue-options-database.js +2 -2
  21. package/dist/jobs/database/generate-code-queue-options-database.js.map +1 -1
  22. package/dist/jobs/database/msg91-sms-queue-database-options.d.ts.map +1 -1
  23. package/dist/jobs/database/msg91-sms-queue-database-options.js +2 -2
  24. package/dist/jobs/database/msg91-sms-queue-database-options.js.map +1 -1
  25. package/dist/jobs/database/msg91-whatsapp-queue-options-database.js +2 -2
  26. package/dist/jobs/database/msg91-whatsapp-queue-options-database.js.map +1 -1
  27. package/dist/jobs/database/otp-queue-options-database.d.ts.map +1 -1
  28. package/dist/jobs/database/otp-queue-options-database.js +2 -2
  29. package/dist/jobs/database/otp-queue-options-database.js.map +1 -1
  30. package/dist/jobs/database/smtp-email-queue-options-database.js +1 -1
  31. package/dist/jobs/database/smtp-email-queue-options-database.js.map +1 -1
  32. package/dist/jobs/database/test-queue-options-database.js +2 -2
  33. package/dist/jobs/database/test-queue-options-database.js.map +1 -1
  34. package/dist/jobs/database/three60-whatsapp-queue-options-database.js +2 -2
  35. package/dist/jobs/database/three60-whatsapp-queue-options-database.js.map +1 -1
  36. package/dist/jobs/database/trigger-mcp-client-queue-options.js +2 -2
  37. package/dist/jobs/database/trigger-mcp-client-queue-options.js.map +1 -1
  38. package/dist/jobs/database/twilio-sms-queue-database-options.js +2 -2
  39. package/dist/jobs/database/twilio-sms-queue-database-options.js.map +1 -1
  40. package/dist/jobs/generate-code-queue-options.js +2 -2
  41. package/dist/jobs/generate-code-queue-options.js.map +1 -1
  42. package/dist/jobs/msg91-otp-queue-options.d.ts.map +1 -1
  43. package/dist/jobs/msg91-otp-queue-options.js +2 -2
  44. package/dist/jobs/msg91-otp-queue-options.js.map +1 -1
  45. package/dist/jobs/msg91-sms-queue-options.d.ts.map +1 -1
  46. package/dist/jobs/msg91-sms-queue-options.js +2 -2
  47. package/dist/jobs/msg91-sms-queue-options.js.map +1 -1
  48. package/dist/jobs/msg91-whatsapp-queue-options.d.ts.map +1 -1
  49. package/dist/jobs/msg91-whatsapp-queue-options.js +2 -2
  50. package/dist/jobs/msg91-whatsapp-queue-options.js.map +1 -1
  51. package/dist/jobs/smtp-email-queue-options.d.ts.map +1 -1
  52. package/dist/jobs/smtp-email-queue-options.js +1 -1
  53. package/dist/jobs/smtp-email-queue-options.js.map +1 -1
  54. package/dist/jobs/test-queue-options.d.ts.map +1 -1
  55. package/dist/jobs/test-queue-options.js +2 -2
  56. package/dist/jobs/test-queue-options.js.map +1 -1
  57. package/dist/jobs/three60-whatsapp-queue-options.d.ts.map +1 -1
  58. package/dist/jobs/three60-whatsapp-queue-options.js +2 -2
  59. package/dist/jobs/three60-whatsapp-queue-options.js.map +1 -1
  60. package/dist/jobs/three60-whatsapp-subscriber.service.js +2 -2
  61. package/dist/jobs/three60-whatsapp-subscriber.service.js.map +1 -1
  62. package/dist/jobs/trigger-mcp-client-queue-options.js +2 -2
  63. package/dist/jobs/trigger-mcp-client-queue-options.js.map +1 -1
  64. package/dist/jobs/twilio-sms-queue-options.js +2 -2
  65. package/dist/jobs/twilio-sms-queue-options.js.map +1 -1
  66. package/dist/services/chatter-message.service.d.ts.map +1 -1
  67. package/dist/services/chatter-message.service.js +8 -1
  68. package/dist/services/chatter-message.service.js.map +1 -1
  69. package/dist/services/crud-helper.service.js.map +1 -1
  70. package/dist/services/queues/database-publisher.service.js +0 -1
  71. package/dist/services/queues/database-publisher.service.js.map +1 -1
  72. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  73. package/dist/services/queues/database-subscriber.service.js +14 -1
  74. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  75. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  76. package/dist/services/queues/rabbitmq-subscriber.service.js +18 -3
  77. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  78. package/dist/services/scheduled-jobs/scheduler.service.d.ts +1 -0
  79. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  80. package/dist/services/scheduled-jobs/scheduler.service.js +26 -10
  81. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  82. package/dist/tsconfig.tsbuildinfo +1 -1
  83. package/package.json +1 -1
  84. package/src/dtos/create-saved-filters.dto.ts +10 -1
  85. package/src/entities/chatter-message.entity.ts +11 -1
  86. package/src/helpers/schematic.service.ts +5 -1
  87. package/src/jobs/api-email-queue-options.ts +2 -6
  88. package/src/jobs/chatter-queue-options.ts +2 -2
  89. package/src/jobs/computed-field-evaluation-queue-options.ts +2 -2
  90. package/src/jobs/database/api-email-queue-options-database.ts +2 -2
  91. package/src/jobs/database/computed-field-evaluation-queue-options-database.ts +2 -2
  92. package/src/jobs/database/generate-code-queue-options-database.ts +2 -2
  93. package/src/jobs/database/msg91-sms-queue-database-options.ts +3 -2
  94. package/src/jobs/database/msg91-whatsapp-queue-options-database.ts +2 -2
  95. package/src/jobs/database/otp-queue-options-database.ts +3 -2
  96. package/src/jobs/database/smtp-email-queue-options-database.ts +1 -1
  97. package/src/jobs/database/test-queue-options-database.ts +2 -2
  98. package/src/jobs/database/three60-whatsapp-queue-options-database.ts +2 -2
  99. package/src/jobs/database/trigger-mcp-client-queue-options.ts +2 -2
  100. package/src/jobs/database/twilio-sms-queue-database-options.ts +2 -2
  101. package/src/jobs/generate-code-queue-options.ts +2 -2
  102. package/src/jobs/msg91-otp-queue-options.ts +3 -8
  103. package/src/jobs/msg91-sms-queue-options.ts +3 -6
  104. package/src/jobs/msg91-whatsapp-queue-options.ts +4 -7
  105. package/src/jobs/smtp-email-queue-options.ts +1 -6
  106. package/src/jobs/test-queue-options.ts +2 -6
  107. package/src/jobs/three60-whatsapp-queue-options.ts +4 -7
  108. package/src/jobs/three60-whatsapp-subscriber.service.ts +1 -1
  109. package/src/jobs/trigger-mcp-client-queue-options.ts +2 -2
  110. package/src/jobs/twilio-sms-queue-options.ts +3 -3
  111. package/src/services/chatter-message.service.ts +32 -26
  112. package/src/services/crud-helper.service.ts +1 -1
  113. package/src/services/queues/database-publisher.service.ts +1 -1
  114. package/src/services/queues/database-subscriber.service.ts +17 -28
  115. package/src/services/queues/rabbitmq-subscriber.service.ts +21 -5
  116. package/src/services/scheduled-jobs/scheduler.service.ts +31 -14
@@ -1 +1 @@
1
- {"version":3,"file":"crud-helper.service.js","sourceRoot":"","sources":["../../src/services/crud-helper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets, SelectQueryBuilder, WhereExpressionBuilder } from \"typeorm\";\nimport { BasicFilterDto } from \"../dtos/basic-filters.dto\";\nimport { classify } from \"@angular-devkit/core/src/utils/strings\";\nimport { ActiveUserData } from \"src/interfaces/active-user-data.interface\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\nimport { Logger } from \"@nestjs/common\";\nimport { ERROR_MESSAGES } from \"src/constants/error-messages\";\n\nexport enum FilterCombinator {\n AND = '$and',\n OR = '$or'\n}\n\nexport enum UserIdFields {\n CREATED_BY = 'createdBy',\n UPDATED_BY = 'updatedBy'\n}\n\nexport class CrudHelperService {\n constructor(\n ) { }\n private readonly logger = new Logger(CrudHelperService.name);\n\n private orderOptions(sort: any[] = []) {\n const orderOptions = {};\n sort.forEach((s: string) => {\n const parts = s.split(':');\n let order: string | undefined;\n let field: string;\n if (parts.length > 1) {\n order = parts.pop();\n field = parts.join(':');\n } else {\n field = parts[0];\n }\n const normalizedOrder = order ? order.toUpperCase() : 'ASC';\n if (!['ASC', 'DESC'].includes(normalizedOrder)) {\n throw new Error(`Invalid sort order provided: ${order}`);\n }\n orderOptions[field] = normalizedOrder;\n });\n return orderOptions;\n }\n\n applyFilters(qb: WhereExpressionBuilder, filters: any, alias: string = 'entity', selectQb: SelectQueryBuilder<any>) {\n const normalizedFilters = this.normalizeObjectKeys(filters);\n if (normalizedFilters.$and) {\n normalizedFilters.$and.forEach((andFilter: any) => {\n qb.andWhere(\n new Brackets(subQb => {\n this.applyFilters(subQb, andFilter, alias, selectQb);\n })\n );\n });\n } else if (normalizedFilters.$or) {\n normalizedFilters.$or.forEach((orFilter: any) => {\n qb.orWhere(new Brackets(subQb => {\n this.applyFilters(subQb, orFilter, alias, selectQb);\n }));\n });\n } else {\n // For individual conditions\n Object.keys(normalizedFilters).forEach(key => {\n const primaryFilterObj = normalizedFilters[key];\n const normalizedPrimaryFilterObj = this.normalizeObjectKeys(primaryFilterObj);\n\n // Get the operator or field from the key\n const operatorOrField = Object.keys(normalizedPrimaryFilterObj)[0];\n // if the key is an operator, then build the query based on the operator\n if (operatorOrField.startsWith('$')) {\n const operator = operatorOrField;\n this.buildOperatorQuery(qb, alias, key, normalizedPrimaryFilterObj, operator);\n return;\n }\n else { // Recursively call the applyFilters method to handle nested conditions\n const joinField = `${alias}.${key}`;\n if (!this.isRelationJoined(selectQb, joinField)) selectQb.leftJoin(joinField, key);\n this.applyFilters(qb, primaryFilterObj, key, selectQb);\n }\n });\n }\n }\n\n private buildOperatorQuery(qb: any, alias: string, field: string, normalizedPrimaryOperatorObj: any, operator: string) {\n const uniqueFieldAlias = `${alias}_${field}_${Math.floor(Math.random() * 1000)}`;\n switch (operator) {\n case '$eq':\n qb.andWhere(`${alias}.${field} = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eq });\n break;\n case '$eqi':\n qb.andWhere(`LOWER(${alias}.${field}) = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eqi.toLowerCase() });\n break;\n case '$ne':\n qb.andWhere(`${alias}.${field} != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$ne });\n break;\n case '$nei':\n qb.andWhere(`LOWER(${alias}.${field}) != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$nei.toLowerCase() });\n break;\n case '$gt':\n qb.andWhere(`${alias}.${field} > :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$gt });\n break;\n case '$gte':\n qb.andWhere(`${alias}.${field} >= :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$gte });\n break;\n case '$lt':\n qb.andWhere(`${alias}.${field} < :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$lt });\n break;\n case '$lte':\n qb.andWhere(`${alias}.${field} <= :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$lte });\n break;\n case '$in':\n qb.andWhere(`${alias}.${field} IN (:...${uniqueFieldAlias})`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$in });\n break;\n case '$notIn':\n qb.andWhere(`${alias}.${field} NOT IN (:...${uniqueFieldAlias})`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$notIn });\n break;\n case '$contains':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$contains}%` });\n break;\n case '$notContains':\n qb.andWhere(`${alias}.${field} NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContains}%` });\n break;\n case '$containsi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$containsi.toLowerCase()}%` });\n break;\n case '$notContainsi':\n qb.andWhere(`LOWER(${alias}.${field}) NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContainsi.toLowerCase()}%` });\n break;\n case '$null':\n qb.andWhere(`${alias}.${field} IS NULL`);\n break;\n case '$notNull':\n qb.andWhere(`${alias}.${field} IS NOT NULL`);\n break;\n case '$between':\n qb.andWhere(`${alias}.${field} BETWEEN :${uniqueFieldAlias}0 AND :${uniqueFieldAlias}1`, { [`${uniqueFieldAlias}0`]: normalizedPrimaryOperatorObj.$between[0], [`${uniqueFieldAlias}1`]: normalizedPrimaryOperatorObj.$between[1] });\n break;\n case '$startsWith':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWith}%` });\n break;\n case '$startsWithi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWithi.toLowerCase()}%` });\n break;\n case '$endsWith':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWith}` });\n break;\n case '$endsWithi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWithi.toLowerCase()}` });\n break;\n default:\n throw new Error(`Operator ${operator} is not supported`);\n }\n }\n\n // Normalize the primary operator object by removing the surrounding brackets in the keys e.g [$eq] => $eq\n private normalizeObjectKeys(obj: any): any {\n return Object.keys(obj).reduce((acc, key) => {\n // Transform the key by removing surrounding brackets\n const newKey = key.replace(/^\\[(.*)\\]$/, '$1');\n // Assign the value to the transformed key in the accumulator object\n acc[newKey] = obj[key];\n return acc;\n }, {});\n }\n\n normalize(value: string | string[]): string[] {\n if (!value) return [];// if the value is nullish, then return an empty array\n return Array.isArray(value) ? value : [value]; // if the value is an array, return it as is, otherwise return it as an array\n }\n\n private normalizeAndFilterPopulateAttributes(value: string | string[]): string[] {\n // Normalize and remove the userId fields from the populate filter, since they are handled separately\n const normalized = this.normalize(value);\n return normalized.filter(item => item !== UserIdFields.CREATED_BY && item !== UserIdFields.UPDATED_BY);\n }\n\n extractUserIdFieldsFromPopulate(value: string | string[]): UserIdFields[] {\n const normalized = this.normalize(value);\n return normalized.filter(item => item === UserIdFields.CREATED_BY || item === UserIdFields.UPDATED_BY);\n }\n\n private isRelationJoined(queryBuilder: SelectQueryBuilder<any>, joinProperty: string): boolean {\n return queryBuilder.expressionMap.joinAttributes.some(join => join.entityOrProperty === joinProperty);\n }\n\n private hasJoins(queryBuilder: SelectQueryBuilder<any>): boolean {\n return queryBuilder.expressionMap.joinAttributes.length > 0;\n }\n\n buildFilterQuery(\n qb: SelectQueryBuilder<any>,\n basicFilterDto: BasicFilterDto,\n entityAlias: string,\n internationalisation?: boolean,\n draftPublishWorkflow?: boolean,\n moduleRef?: any,\n filterCombinator: FilterCombinator = FilterCombinator.AND,\n applyPagination: boolean = true,\n applySorting: boolean = true\n ): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any\n let { limit, offset, showSoftDeleted, filters } = basicFilterDto;\n const { fields, sort, populate = [], populateMedia = [], locale, status } = basicFilterDto;\n\n // Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)\n const normalizedFields = this.normalize(fields);\n const normalizedAndFilteredPopulateAttributes = this.normalizeAndFilterPopulateAttributes(populate);\n const normalizedPopulateMedia = this.normalize(populateMedia);\n\n // if normalizedPopulateMedia, has any nested media paths, then add then to populate excluding the last part\n const additionalPopulate = this.additionalRelationsRequiredForMediaPopulation(normalizedPopulateMedia);\n // Add the additional populate relations to the normalizedPopulate, if they are not already present\n normalizedAndFilteredPopulateAttributes.push(...additionalPopulate.filter((relation) => !normalizedAndFilteredPopulateAttributes.includes(relation)));\n\n const normalizedSort = this.normalize(sort);\n\n // Depending upon the populate option, apply the join clause\n if (normalizedAndFilteredPopulateAttributes && normalizedAndFilteredPopulateAttributes.length) {\n this.buildPopulateQuery(normalizedAndFilteredPopulateAttributes, entityAlias, qb);\n }\n\n if (filters) {\n if (filterCombinator === FilterCombinator.AND) {\n qb.andWhere(new Brackets(whereQb => {\n this.applyFilters(whereQb, filters, entityAlias, qb);\n }));\n } else if (filterCombinator === FilterCombinator.OR) {\n qb.orWhere(new Brackets(whereQb => {\n this.applyFilters(whereQb, filters, entityAlias, qb);\n }));\n }\n }\n\n let finalLocale = locale\n if (internationalisation) {\n // If locale is not provided in the filter dto, then assume it is the default locale to be used. \n if (!finalLocale) {\n //Get default locale from registry\n const solidRegistry = moduleRef.get(SolidRegistry, { strict: false });\n const defaultLocale = solidRegistry.getDefaultLocale();\n if(defaultLocale){\n finalLocale = defaultLocale.locale;\n }else{\n finalLocale = 'en';\n }\n }\n qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });\n }\n\n if (draftPublishWorkflow && status) {\n if (basicFilterDto.status === 'published') {\n qb.andWhere(`${entityAlias}.publishedAt IS NOT NULL`);\n } else if (basicFilterDto.status === 'draft') {\n qb.andWhere(`${entityAlias}.publishedAt IS NULL`);\n }\n }\n // Depending upon the select option, apply the select clause\n if (normalizedFields && normalizedFields.length) {\n qb.select(normalizedFields.map(field => {\n // If the field contains a (, do not prefix the entity alias\n return this.wrapFieldWithAlias(field, entityAlias);\n }));\n }\n\n // Depending upon the order option, apply the order by clause\n if (applySorting && normalizedSort && normalizedSort.length) {\n const orderOptions = this.orderOptions(normalizedSort);\n if (orderOptions) {\n const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;\n orderOptionKeys.forEach((key) => {\n const value = orderOptions[key] as 'ASC' | 'DESC';\n qb.addOrderBy(`${entityAlias}.${key}`, value);\n });\n }\n }\n\n\n if (showSoftDeleted === 'inclusive') {\n qb.withDeleted();\n }\n\n if (showSoftDeleted === 'exclusive') {\n qb.withDeleted();\n qb.where(`${entityAlias}.deletedAt IS NOT NULL`);\n }\n\n // Apply the pagination options & handle the case when the query has joins\n if (applyPagination) {\n if (limit) this.hasJoins(qb) ? qb.take(limit) : qb.limit(limit);\n if (offset) this.hasJoins(qb) ? qb.skip(offset) : qb.offset(offset);\n }\n return qb;\n }\n\n additionalRelationsRequiredForMediaPopulation(normalizedPopulateMedia: string[]) {\n // Populate relations containing the media field\n return normalizedPopulateMedia\n .filter(pm => pm.includes(\".\"))\n .map((pm) => {\n const mediaPathParts = pm.split('.');\n if (mediaPathParts.length <= 1) return pm;\n return mediaPathParts.slice(0, -1).join('.');\n });\n }\n\n private buildPopulateQuery(normalizedPopulate: string[], entityAlias: string, qb: SelectQueryBuilder<any>) {\n normalizedPopulate.forEach((relation) => {\n this.buildJoinQueryForRelation(qb, entityAlias, relation);\n });\n return qb;\n }\n\n private sanitizeAlias(alias: string) {\n return alias.replace(/[^a-zA-Z0-9_]/g, '_');\n }\n\n private isAliasJoined(queryBuilder: SelectQueryBuilder<any>, alias: string): boolean {\n return queryBuilder.expressionMap.joinAttributes.some(join => join.alias?.name === alias);\n }\n\n private getExistingJoinAlias(qb: SelectQueryBuilder<any>, joinProperty: string): string | undefined {\n const existingJoin = qb.expressionMap.joinAttributes.find(join => join.entityOrProperty === joinProperty);\n return existingJoin?.alias?.name;\n }\n\n private ensureRelationPathJoined(qb: SelectQueryBuilder<any>, rootAlias: string, pathParts: string[]) {\n const mainAlias =\n qb.expressionMap?.mainAlias?.name ||\n qb.expressionMap?.aliases?.find(a => a.metadata)?.name ||\n qb.expressionMap?.aliases?.[0]?.name;\n let parentAlias = mainAlias || rootAlias;\n for (let i = 0; i < pathParts.length - 1; i++) {\n const part = pathParts[i];\n const joinProperty = `${parentAlias}.${part}`;\n const existingAlias = this.getExistingJoinAlias(qb, joinProperty);\n const joinAlias = existingAlias ?? this.sanitizeAlias(`${parentAlias}_${part}`);\n if (!existingAlias && !this.isRelationJoined(qb, joinProperty) && !this.isAliasJoined(qb, joinAlias)) {\n qb.leftJoin(joinProperty, joinAlias);\n }\n parentAlias = joinAlias;\n }\n return { alias: parentAlias, property: pathParts[pathParts.length - 1] };\n }\n\n private getDriver(qb: SelectQueryBuilder<any>) {\n return qb.connection.options.type as string;\n }\n\n private buildDateGranularityExpression(driver: string, columnExpr: string, granularity: string) {\n switch (driver) {\n case 'postgres':\n case 'cockroachdb':\n return `DATE_TRUNC('${granularity}', ${columnExpr})`;\n case 'mysql':\n case 'mariadb':\n switch (granularity) {\n case 'day': return `DATE(${columnExpr})`;\n case 'week': return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;\n case 'month': return `DATE_FORMAT(${columnExpr}, '%Y-%m-01')`;\n case 'year': return `DATE_FORMAT(${columnExpr}, '%Y-01-01')`;\n default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);\n }\n case 'mssql':\n case 'sqlserver':\n switch (granularity) {\n case 'day': return `CONVERT(date, ${columnExpr})`;\n case 'week': return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;\n case 'month': return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;\n case 'year': return `DATEFROMPARTS(YEAR(${columnExpr}), 1, 1)`;\n default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);\n }\n default:\n throw new Error(`Granularity not supported for driver ${driver}`);\n }\n }\n\n private buildGroupByExpression(qb: SelectQueryBuilder<any>, rootAlias: string, field: string) {\n const parts = field.split(':');\n const rawField = parts[0];\n const granularity = parts[1];\n const format = parts[2];\n const pathParts = rawField.split('.');\n const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);\n const columnExpr = `${alias}.${property}`;\n const groupExpr = granularity ? this.buildDateGranularityExpression(this.getDriver(qb), columnExpr, granularity) : columnExpr;\n const selectAlias = this.sanitizeAlias(`${rawField.replace(/\\./g, '_')}${granularity ? '_' + granularity : ''}`);\n return { groupExpr, selectAlias, sourceKey: field, format };\n }\n\n applyGroupBySelections(\n qb: SelectQueryBuilder<any>,\n groupBy: string[],\n entityAlias: string\n ) {\n const aliasMap: Record<string, string> = {};\n const formatMap: Record<string, string | undefined> = {};\n const expressionMap: Record<string, string> = {};\n qb.select([]);\n groupBy.forEach((field) => {\n const { groupExpr, selectAlias, sourceKey, format } = this.buildGroupByExpression(qb, entityAlias, field);\n qb.addSelect(groupExpr, selectAlias);\n qb.addGroupBy(groupExpr);\n aliasMap[sourceKey] = selectAlias;\n formatMap[selectAlias] = format;\n expressionMap[selectAlias] = groupExpr;\n });\n return { aliasMap, formatMap, expressionMap };\n }\n\n private buildAggregateExpression(qb: SelectQueryBuilder<any>, rootAlias: string, aggregate: string) {\n const [rawField, rawFn] = aggregate.split(':');\n const fn = (rawFn || 'count').toLowerCase();\n if ((!rawField || rawField.toLowerCase() === 'count') && fn === 'count') {\n return { expression: 'COUNT(*)', selectAlias: 'count' };\n }\n if (!rawField) throw new Error(`Invalid aggregate specification: ${aggregate}`);\n const pathParts = rawField.split('.');\n const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);\n const columnExpr = `${alias}.${property}`;\n const selectAlias = this.sanitizeAlias(`${rawField.replace(/\\./g, '_')}_${fn}`);\n let expression = '';\n switch (fn) {\n case 'count': expression = `COUNT(${columnExpr})`; break;\n case 'count_distinct': expression = `COUNT(DISTINCT ${columnExpr})`; break;\n case 'sum': expression = `SUM(${columnExpr})`; break;\n case 'avg': expression = `AVG(${columnExpr})`; break;\n case 'min': expression = `MIN(${columnExpr})`; break;\n case 'max': expression = `MAX(${columnExpr})`; break;\n default: throw new Error(`Unsupported aggregate function ${fn}`);\n }\n return { expression, selectAlias, sourceKey: aggregate };\n }\n\n applyAggregates(\n qb: SelectQueryBuilder<any>,\n aggregates: string[] | undefined,\n entityAlias: string\n ) {\n const aggregateList = this.normalize(aggregates);\n const aggregateAliasMap: Record<string, string> = {};\n if (!aggregateList.length) {\n qb.addSelect('COUNT(*)', 'count');\n aggregateAliasMap['count'] = 'count';\n return aggregateAliasMap;\n }\n aggregateList.forEach((agg) => {\n const { expression, selectAlias, sourceKey } = this.buildAggregateExpression(qb, entityAlias, agg);\n qb.addSelect(expression, selectAlias);\n aggregateAliasMap[sourceKey] = selectAlias;\n });\n return aggregateAliasMap;\n }\n\n applyGroupSortingAndPagination(\n qb: SelectQueryBuilder<any>,\n sort: string[] | undefined,\n aliasMap: Record<string, string>,\n limit?: number,\n offset?: number\n ) {\n const normalizedSort = this.normalize(sort);\n if (normalizedSort.length) {\n const orderOptions = this.orderOptions(normalizedSort);\n const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;\n orderOptionKeys.forEach((key) => {\n const resolvedKey = aliasMap[key] || key as string;\n const value = orderOptions[key] as 'ASC' | 'DESC';\n qb.addOrderBy(`\"${resolvedKey}\"`, value);\n });\n }\n const hasLimit = limit !== undefined && limit !== null;\n const hasOffset = offset !== undefined && offset !== null;\n\n // Use both take/skip and limit/offset to ensure pagination is applied even when joins are present.\n if (hasLimit) {\n qb.take(limit);\n qb.limit(limit);\n }\n if (hasOffset) {\n qb.skip(offset);\n qb.offset(offset);\n }\n }\n\n async countGroups(qb: SelectQueryBuilder<any>) {\n const clone = qb.clone();\n clone.limit(undefined).offset(undefined).take(undefined).skip(undefined);\n const rows = await clone.getRawMany();\n return rows.length;\n }\n\n private buildJoinQueryForRelation(qb: SelectQueryBuilder<any>, entityAlias: string, relation: string) {\n // We split the joinProperty to get the alias of the entity we are joining\n const relationParts = relation.split('.');\n let parentAlias = entityAlias;\n relationParts.forEach((part, i) => {\n const joinProperty = `${parentAlias}.${part}`;\n // Check if the relation is already joined, if not then join it\n if (!this.isRelationJoined(qb, joinProperty)) {\n const joinAlias = relationParts.slice(0, i + 1).join('_');\n qb.leftJoinAndSelect(joinProperty, joinAlias);\n }\n else {\n // Since in populate, we are create a unique alias based on the relation path\n //If the join is already present, it is probably because of the relation being passed in the where filter i.e applyFilters method\n qb.addSelect(`${part}`);\n }\n parentAlias = part; // Update the parent alias for the next iteration\n });\n return qb;\n }\n\n private wrapFieldWithAlias(field: string, entityAlias: string): string {\n if (!this.isAggregateField(field)) return `${entityAlias}.${field}`;\n // For aggregate fields, extract the field name from the aggregate function & wrap it with the entity alias, if it is not already wrapped\n const fieldParts = field.split('(');\n const aggregateFunction = fieldParts[0];\n const fieldName = fieldParts[1].replace(')', '');\n return `${aggregateFunction}(${entityAlias}.${fieldName})`;\n }\n\n isAggregateField(field: string): boolean {\n return field.includes('(');\n }\n\n isAggregateFieldKey(key: string, aggregateAliases: Set<string>): boolean {\n return aggregateAliases.has(key);\n }\n\n getFieldFromQueryFieldKey(queryFieldKey: string, alias: string): string {\n return queryFieldKey.replace(`${alias}_`, '');\n }\n\n buildGroupByRecordsQuery(\n qb: SelectQueryBuilder<any>,\n group: any,\n alias: string,\n groupAliasMap: Record<string, string> = {},\n aggregateAliasMap: Record<string, string> = {},\n groupExpressionMap: Record<string, string> = {}\n ): SelectQueryBuilder<any> {\n const rootAlias = qb.expressionMap?.mainAlias?.name\n ?? qb.expressionMap?.aliases?.find(a => a.metadata)?.name\n ?? qb.expressionMap?.aliases?.[0]?.name\n ?? (qb as any).alias\n ?? alias;\n qb.andWhere(new Brackets(qb => {\n const aggregateAliasSet = new Set(Object.values(aggregateAliasMap));\n const reverseGroupAliasMap = Object.entries(groupAliasMap).reduce((acc, [sourceKey, aliasKey]) => {\n acc[aliasKey] = sourceKey;\n return acc;\n }, {} as Record<string, string>);\n for (const key in group) {\n if (group.hasOwnProperty(key) && !this.isAggregateFieldKey(key, aggregateAliasSet)) {\n const value = group[key];\n const sourceField = reverseGroupAliasMap[key] || key;\n const cleanedField = sourceField.split(':')[0];\n const pathParts = cleanedField.split('.');\n const { alias: resolvedAlias, property } = this.ensureRelationPathJoined(qb as any, rootAlias, pathParts);\n const paramKey = this.sanitizeAlias(`${resolvedAlias}_${property}_${key}`);\n const expr = (sourceField.includes(':') && groupExpressionMap[key])\n ? groupExpressionMap[key]\n : `${resolvedAlias}.${property}`;\n qb.andWhere(`${expr} = :${paramKey}`, { [paramKey]: value });\n }\n }\n }));\n return qb;\n }\n\n private formatGroupValue(value: any, format?: string) {\n if (!format) return value;\n if (value === null || value === undefined) return value;\n const dateVal = value instanceof Date ? value : new Date(value);\n if (isNaN(dateVal.getTime())) return value;\n switch (format) {\n case 'MMM':\n return dateVal.toLocaleString('en', { month: 'short' });\n case 'MMMM':\n return dateVal.toLocaleString('en', { month: 'long' });\n case 'YYYY':\n return dateVal.getFullYear();\n case 'YYYY-MM':\n return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}`;\n case 'YYYY-MM-DD':\n return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}-${String(dateVal.getDate()).padStart(2, '0')}`;\n default:\n return value;\n }\n }\n\n getGroupName(\n group: any,\n aggregateAliases: Set<string>,\n groupByFields: string[],\n groupAliasMap: Record<string, string>,\n groupFormatMap: Record<string, string | undefined>\n ): string {\n const orderedValues = groupByFields\n .map(field => {\n const alias = groupAliasMap[field] ?? this.sanitizeAlias(field.replace(/\\./g, '_'));\n const rawVal = group[alias] ?? group[field] ?? group[field.replace(/\\./g, '_')];\n return this.formatGroupValue(rawVal, groupFormatMap[alias]);\n })\n .filter(v => v !== undefined && v !== null);\n\n if (orderedValues.length === 0) {\n return Object.keys(group)\n .filter(key => !this.isAggregateFieldKey(key, aggregateAliases))\n .map(key => group[key])\n .join('_');\n }\n\n return orderedValues.join('_');\n }\n\n createGroupRecords(group: any, aggregateAliases: Set<string>, groupData: any, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {\n const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);\n return {\n groupName,\n groupData\n }\n }\n createGroupMeta(group: any, aggregateAliases: Set<string>, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {\n const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);\n const groupAggregateValues = {}\n for (const key in group) {\n if (group.hasOwnProperty(key) && this.isAggregateFieldKey(key, aggregateAliases)) {\n const value = group[key];\n groupAggregateValues[key] = value;\n }\n }\n return {\n groupName,\n ...groupAggregateValues\n };\n }\n\n async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any\n const { limit, offset, ...rest } = basicFilterDto;\n const filteredDto = { ...rest, limit: undefined, offset: undefined };\n\n const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, undefined, undefined, undefined, FilterCombinator.AND, false, false);\n\n const groupByFields = this.normalize(filteredDto.groupBy);\n\n if (!groupByFields || groupByFields.length === 0) {\n throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);\n }\n\n this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);\n this.applyAggregates(filteredQB, ['count'], entityAlias);\n filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);\n\n const rawResults = await filteredQB.getRawMany();\n return rawResults.length;\n }\n\n hasReadPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.findOne`, `${classify(modelName)}Controller.findMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasWritePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.create`, `${classify(modelName)}Controller.insertMany`, `${classify(modelName)}Controller.update`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasUpdatePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.update`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasPublishPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.publish`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasUnpublishPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.publish`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasDeletePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.delete`, `${classify(modelName)}Controller.deleteMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n hasCreatePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.create`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n hasRecoverPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.recover`, `${classify(modelName)}Controller.recoverMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n\n\n}\n"]}
1
+ {"version":3,"file":"crud-helper.service.js","sourceRoot":"","sources":["../../src/services/crud-helper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Brackets, SelectQueryBuilder, WhereExpressionBuilder } from \"typeorm\";\nimport { BasicFilterDto } from \"../dtos/basic-filters.dto\";\nimport { classify } from \"@angular-devkit/core/src/utils/strings\";\nimport { ActiveUserData } from \"src/interfaces/active-user-data.interface\";\nimport { SolidRegistry } from \"src/helpers/solid-registry\";\nimport { Logger } from \"@nestjs/common\";\nimport { ERROR_MESSAGES } from \"src/constants/error-messages\";\n\nexport enum FilterCombinator {\n AND = '$and',\n OR = '$or'\n}\n\nexport enum UserIdFields {\n CREATED_BY = 'createdBy',\n UPDATED_BY = 'updatedBy'\n}\n\nexport class CrudHelperService {\n constructor(\n ) { }\n private readonly logger = new Logger(CrudHelperService.name);\n\n private orderOptions(sort: any[] = []) {\n const orderOptions = {};\n sort.forEach((s: string) => {\n const parts = s.split(':');\n let order: string | undefined;\n let field: string;\n if (parts.length > 1) {\n order = parts.pop();\n field = parts.join(':');\n } else {\n field = parts[0];\n }\n const normalizedOrder = order ? order.toUpperCase() : 'ASC';\n if (!['ASC', 'DESC'].includes(normalizedOrder)) {\n throw new Error(`Invalid sort order provided: ${order}`);\n }\n orderOptions[field] = normalizedOrder;\n });\n return orderOptions;\n }\n\n applyFilters(qb: WhereExpressionBuilder, filters: any, alias: string = 'entity', selectQb: SelectQueryBuilder<any>) {\n const normalizedFilters = this.normalizeObjectKeys(filters);\n if (normalizedFilters.$and) {\n normalizedFilters.$and.forEach((andFilter: any) => {\n qb.andWhere(\n new Brackets(subQb => {\n this.applyFilters(subQb, andFilter, alias, selectQb);\n })\n );\n });\n } else if (normalizedFilters.$or) {\n normalizedFilters.$or.forEach((orFilter: any) => {\n qb.orWhere(new Brackets(subQb => {\n this.applyFilters(subQb, orFilter, alias, selectQb);\n }));\n });\n } else {\n // For individual conditions\n Object.keys(normalizedFilters).forEach(key => {\n const primaryFilterObj = normalizedFilters[key];\n const normalizedPrimaryFilterObj = this.normalizeObjectKeys(primaryFilterObj);\n\n // Get the operator or field from the key\n const operatorOrField = Object.keys(normalizedPrimaryFilterObj)[0];\n // if the key is an operator, then build the query based on the operator\n if (operatorOrField.startsWith('$')) {\n const operator = operatorOrField;\n this.buildOperatorQuery(qb, alias, key, normalizedPrimaryFilterObj, operator);\n return;\n }\n else { // Recursively call the applyFilters method to handle nested conditions\n const joinField = `${alias}.${key}`;\n if (!this.isRelationJoined(selectQb, joinField)) selectQb.leftJoin(joinField, key);\n this.applyFilters(qb, primaryFilterObj, key, selectQb);\n }\n });\n }\n }\n\n private buildOperatorQuery(qb: any, alias: string, field: string, normalizedPrimaryOperatorObj: any, operator: string) {\n const uniqueFieldAlias = `${alias}_${field}_${Math.floor(Math.random() * 1000)}`;\n switch (operator) {\n case '$eq':\n qb.andWhere(`${alias}.${field} = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eq });\n break;\n case '$eqi':\n qb.andWhere(`LOWER(${alias}.${field}) = :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$eqi.toLowerCase() });\n break;\n case '$ne':\n qb.andWhere(`${alias}.${field} != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$ne });\n break;\n case '$nei':\n qb.andWhere(`LOWER(${alias}.${field}) != :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$nei.toLowerCase() });\n break;\n case '$gt':\n qb.andWhere(`${alias}.${field} > :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$gt });\n break;\n case '$gte':\n qb.andWhere(`${alias}.${field} >= :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$gte });\n break;\n case '$lt':\n qb.andWhere(`${alias}.${field} < :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$lt });\n break;\n case '$lte':\n qb.andWhere(`${alias}.${field} <= :${uniqueFieldAlias}`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$lte });\n break;\n case '$in':\n qb.andWhere(`${alias}.${field} IN (:...${uniqueFieldAlias})`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$in });\n break;\n case '$notIn':\n qb.andWhere(`${alias}.${field} NOT IN (:...${uniqueFieldAlias})`, { [uniqueFieldAlias]: normalizedPrimaryOperatorObj.$notIn });\n break;\n case '$contains':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$contains}%` });\n break;\n case '$notContains':\n qb.andWhere(`${alias}.${field} NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContains}%` });\n break;\n case '$containsi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$containsi.toLowerCase()}%` });\n break;\n case '$notContainsi':\n qb.andWhere(`LOWER(${alias}.${field}) NOT LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$notContainsi.toLowerCase()}%` });\n break;\n case '$null':\n qb.andWhere(`${alias}.${field} IS NULL`);\n break;\n case '$notNull':\n qb.andWhere(`${alias}.${field} IS NOT NULL`);\n break;\n case '$between':\n qb.andWhere(`${alias}.${field} BETWEEN :${uniqueFieldAlias}0 AND :${uniqueFieldAlias}1`, { [`${uniqueFieldAlias}0`]: normalizedPrimaryOperatorObj.$between[0], [`${uniqueFieldAlias}1`]: normalizedPrimaryOperatorObj.$between[1] });\n break;\n case '$startsWith':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWith}%` });\n break;\n case '$startsWithi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `${normalizedPrimaryOperatorObj.$startsWithi.toLowerCase()}%` });\n break;\n case '$endsWith':\n qb.andWhere(`${alias}.${field} LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWith}` });\n break;\n case '$endsWithi':\n qb.andWhere(`LOWER(${alias}.${field}) LIKE :${uniqueFieldAlias}`, { [uniqueFieldAlias]: `%${normalizedPrimaryOperatorObj.$endsWithi.toLowerCase()}` });\n break;\n default:\n throw new Error(`Operator ${operator} is not supported`);\n }\n }\n\n // Normalize the primary operator object by removing the surrounding brackets in the keys e.g [$eq] => $eq\n private normalizeObjectKeys(obj: any): any {\n return Object.keys(obj).reduce((acc, key) => {\n // Transform the key by removing surrounding brackets\n const newKey = key.replace(/^\\[(.*)\\]$/, '$1');\n // Assign the value to the transformed key in the accumulator object\n acc[newKey] = obj[key];\n return acc;\n }, {});\n }\n\n normalize(value: string | string[]): string[] {\n if (!value) return []; // if the value is nullish, then return an empty array\n return Array.isArray(value) ? value : [value]; // if the value is an array, return it as is, otherwise return it as an array\n }\n\n private normalizeAndFilterPopulateAttributes(value: string | string[]): string[] {\n // Normalize and remove the userId fields from the populate filter, since they are handled separately\n const normalized = this.normalize(value);\n return normalized.filter(item => item !== UserIdFields.CREATED_BY && item !== UserIdFields.UPDATED_BY);\n }\n\n extractUserIdFieldsFromPopulate(value: string | string[]): UserIdFields[] {\n const normalized = this.normalize(value);\n return normalized.filter(item => item === UserIdFields.CREATED_BY || item === UserIdFields.UPDATED_BY);\n }\n\n private isRelationJoined(queryBuilder: SelectQueryBuilder<any>, joinProperty: string): boolean {\n return queryBuilder.expressionMap.joinAttributes.some(join => join.entityOrProperty === joinProperty);\n }\n\n private hasJoins(queryBuilder: SelectQueryBuilder<any>): boolean {\n return queryBuilder.expressionMap.joinAttributes.length > 0;\n }\n\n buildFilterQuery(\n qb: SelectQueryBuilder<any>,\n basicFilterDto: BasicFilterDto,\n entityAlias: string,\n internationalisation?: boolean,\n draftPublishWorkflow?: boolean,\n moduleRef?: any,\n filterCombinator: FilterCombinator = FilterCombinator.AND,\n applyPagination: boolean = true,\n applySorting: boolean = true\n ): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any\n let { limit, offset, showSoftDeleted, filters } = basicFilterDto;\n const { fields, sort, populate = [], populateMedia = [], locale, status } = basicFilterDto;\n\n // Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)\n const normalizedFields = this.normalize(fields);\n const normalizedAndFilteredPopulateAttributes = this.normalizeAndFilterPopulateAttributes(populate);\n const normalizedPopulateMedia = this.normalize(populateMedia);\n\n // if normalizedPopulateMedia, has any nested media paths, then add then to populate excluding the last part\n const additionalPopulate = this.additionalRelationsRequiredForMediaPopulation(normalizedPopulateMedia);\n // Add the additional populate relations to the normalizedPopulate, if they are not already present\n normalizedAndFilteredPopulateAttributes.push(...additionalPopulate.filter((relation) => !normalizedAndFilteredPopulateAttributes.includes(relation)));\n\n const normalizedSort = this.normalize(sort);\n\n // Depending upon the populate option, apply the join clause\n if (normalizedAndFilteredPopulateAttributes && normalizedAndFilteredPopulateAttributes.length) {\n this.buildPopulateQuery(normalizedAndFilteredPopulateAttributes, entityAlias, qb);\n }\n\n if (filters) {\n if (filterCombinator === FilterCombinator.AND) {\n qb.andWhere(new Brackets(whereQb => {\n this.applyFilters(whereQb, filters, entityAlias, qb);\n }));\n } else if (filterCombinator === FilterCombinator.OR) {\n qb.orWhere(new Brackets(whereQb => {\n this.applyFilters(whereQb, filters, entityAlias, qb);\n }));\n }\n }\n\n let finalLocale = locale\n if (internationalisation) {\n // If locale is not provided in the filter dto, then assume it is the default locale to be used. \n if (!finalLocale) {\n //Get default locale from registry\n const solidRegistry = moduleRef.get(SolidRegistry, { strict: false });\n const defaultLocale = solidRegistry.getDefaultLocale();\n if(defaultLocale){\n finalLocale = defaultLocale.locale;\n }else{\n finalLocale = 'en';\n }\n }\n qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });\n }\n\n if (draftPublishWorkflow && status) {\n if (basicFilterDto.status === 'published') {\n qb.andWhere(`${entityAlias}.publishedAt IS NOT NULL`);\n } else if (basicFilterDto.status === 'draft') {\n qb.andWhere(`${entityAlias}.publishedAt IS NULL`);\n }\n }\n // Depending upon the select option, apply the select clause\n if (normalizedFields && normalizedFields.length) {\n qb.select(normalizedFields.map(field => {\n // If the field contains a (, do not prefix the entity alias\n return this.wrapFieldWithAlias(field, entityAlias);\n }));\n }\n\n // Depending upon the order option, apply the order by clause\n if (applySorting && normalizedSort && normalizedSort.length) {\n const orderOptions = this.orderOptions(normalizedSort);\n if (orderOptions) {\n const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;\n orderOptionKeys.forEach((key) => {\n const value = orderOptions[key] as 'ASC' | 'DESC';\n qb.addOrderBy(`${entityAlias}.${key}`, value);\n });\n }\n }\n\n\n if (showSoftDeleted === 'inclusive') {\n qb.withDeleted();\n }\n\n if (showSoftDeleted === 'exclusive') {\n qb.withDeleted();\n qb.where(`${entityAlias}.deletedAt IS NOT NULL`);\n }\n\n // Apply the pagination options & handle the case when the query has joins\n if (applyPagination) {\n if (limit) this.hasJoins(qb) ? qb.take(limit) : qb.limit(limit);\n if (offset) this.hasJoins(qb) ? qb.skip(offset) : qb.offset(offset);\n }\n return qb;\n }\n\n additionalRelationsRequiredForMediaPopulation(normalizedPopulateMedia: string[]) {\n // Populate relations containing the media field\n return normalizedPopulateMedia\n .filter(pm => pm.includes(\".\"))\n .map((pm) => {\n const mediaPathParts = pm.split('.');\n if (mediaPathParts.length <= 1) return pm;\n return mediaPathParts.slice(0, -1).join('.');\n });\n }\n\n private buildPopulateQuery(normalizedPopulate: string[], entityAlias: string, qb: SelectQueryBuilder<any>) {\n normalizedPopulate.forEach((relation) => {\n this.buildJoinQueryForRelation(qb, entityAlias, relation);\n });\n return qb;\n }\n\n private sanitizeAlias(alias: string) {\n return alias.replace(/[^a-zA-Z0-9_]/g, '_');\n }\n\n private isAliasJoined(queryBuilder: SelectQueryBuilder<any>, alias: string): boolean {\n return queryBuilder.expressionMap.joinAttributes.some(join => join.alias?.name === alias);\n }\n\n private getExistingJoinAlias(qb: SelectQueryBuilder<any>, joinProperty: string): string | undefined {\n const existingJoin = qb.expressionMap.joinAttributes.find(join => join.entityOrProperty === joinProperty);\n return existingJoin?.alias?.name;\n }\n\n private ensureRelationPathJoined(qb: SelectQueryBuilder<any>, rootAlias: string, pathParts: string[]) {\n const mainAlias =\n qb.expressionMap?.mainAlias?.name ||\n qb.expressionMap?.aliases?.find(a => a.metadata)?.name ||\n qb.expressionMap?.aliases?.[0]?.name;\n let parentAlias = mainAlias || rootAlias;\n for (let i = 0; i < pathParts.length - 1; i++) {\n const part = pathParts[i];\n const joinProperty = `${parentAlias}.${part}`;\n const existingAlias = this.getExistingJoinAlias(qb, joinProperty);\n const joinAlias = existingAlias ?? this.sanitizeAlias(`${parentAlias}_${part}`);\n if (!existingAlias && !this.isRelationJoined(qb, joinProperty) && !this.isAliasJoined(qb, joinAlias)) {\n qb.leftJoin(joinProperty, joinAlias);\n }\n parentAlias = joinAlias;\n }\n return { alias: parentAlias, property: pathParts[pathParts.length - 1] };\n }\n\n private getDriver(qb: SelectQueryBuilder<any>) {\n return qb.connection.options.type as string;\n }\n\n private buildDateGranularityExpression(driver: string, columnExpr: string, granularity: string) {\n switch (driver) {\n case 'postgres':\n case 'cockroachdb':\n return `DATE_TRUNC('${granularity}', ${columnExpr})`;\n case 'mysql':\n case 'mariadb':\n switch (granularity) {\n case 'day': return `DATE(${columnExpr})`;\n case 'week': return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;\n case 'month': return `DATE_FORMAT(${columnExpr}, '%Y-%m-01')`;\n case 'year': return `DATE_FORMAT(${columnExpr}, '%Y-01-01')`;\n default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);\n }\n case 'mssql':\n case 'sqlserver':\n switch (granularity) {\n case 'day': return `CONVERT(date, ${columnExpr})`;\n case 'week': return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;\n case 'month': return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;\n case 'year': return `DATEFROMPARTS(YEAR(${columnExpr}), 1, 1)`;\n default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);\n }\n default:\n throw new Error(`Granularity not supported for driver ${driver}`);\n }\n }\n\n private buildGroupByExpression(qb: SelectQueryBuilder<any>, rootAlias: string, field: string) {\n const parts = field.split(':');\n const rawField = parts[0];\n const granularity = parts[1];\n const format = parts[2];\n const pathParts = rawField.split('.');\n const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);\n const columnExpr = `${alias}.${property}`;\n const groupExpr = granularity ? this.buildDateGranularityExpression(this.getDriver(qb), columnExpr, granularity) : columnExpr;\n const selectAlias = this.sanitizeAlias(`${rawField.replace(/\\./g, '_')}${granularity ? '_' + granularity : ''}`);\n return { groupExpr, selectAlias, sourceKey: field, format };\n }\n\n applyGroupBySelections(\n qb: SelectQueryBuilder<any>,\n groupBy: string[],\n entityAlias: string\n ) {\n const aliasMap: Record<string, string> = {};\n const formatMap: Record<string, string | undefined> = {};\n const expressionMap: Record<string, string> = {};\n qb.select([]);\n groupBy.forEach((field) => {\n const { groupExpr, selectAlias, sourceKey, format } = this.buildGroupByExpression(qb, entityAlias, field);\n qb.addSelect(groupExpr, selectAlias);\n qb.addGroupBy(groupExpr);\n aliasMap[sourceKey] = selectAlias;\n formatMap[selectAlias] = format;\n expressionMap[selectAlias] = groupExpr;\n });\n return { aliasMap, formatMap, expressionMap };\n }\n\n private buildAggregateExpression(qb: SelectQueryBuilder<any>, rootAlias: string, aggregate: string) {\n const [rawField, rawFn] = aggregate.split(':');\n const fn = (rawFn || 'count').toLowerCase();\n if ((!rawField || rawField.toLowerCase() === 'count') && fn === 'count') {\n return { expression: 'COUNT(*)', selectAlias: 'count' };\n }\n if (!rawField) throw new Error(`Invalid aggregate specification: ${aggregate}`);\n const pathParts = rawField.split('.');\n const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);\n const columnExpr = `${alias}.${property}`;\n const selectAlias = this.sanitizeAlias(`${rawField.replace(/\\./g, '_')}_${fn}`);\n let expression = '';\n switch (fn) {\n case 'count': expression = `COUNT(${columnExpr})`; break;\n case 'count_distinct': expression = `COUNT(DISTINCT ${columnExpr})`; break;\n case 'sum': expression = `SUM(${columnExpr})`; break;\n case 'avg': expression = `AVG(${columnExpr})`; break;\n case 'min': expression = `MIN(${columnExpr})`; break;\n case 'max': expression = `MAX(${columnExpr})`; break;\n default: throw new Error(`Unsupported aggregate function ${fn}`);\n }\n return { expression, selectAlias, sourceKey: aggregate };\n }\n\n applyAggregates(\n qb: SelectQueryBuilder<any>,\n aggregates: string[] | undefined,\n entityAlias: string\n ) {\n const aggregateList = this.normalize(aggregates);\n const aggregateAliasMap: Record<string, string> = {};\n if (!aggregateList.length) {\n qb.addSelect('COUNT(*)', 'count');\n aggregateAliasMap['count'] = 'count';\n return aggregateAliasMap;\n }\n aggregateList.forEach((agg) => {\n const { expression, selectAlias, sourceKey } = this.buildAggregateExpression(qb, entityAlias, agg);\n qb.addSelect(expression, selectAlias);\n aggregateAliasMap[sourceKey] = selectAlias;\n });\n return aggregateAliasMap;\n }\n\n applyGroupSortingAndPagination(\n qb: SelectQueryBuilder<any>,\n sort: string[] | undefined,\n aliasMap: Record<string, string>,\n limit?: number,\n offset?: number\n ) {\n const normalizedSort = this.normalize(sort);\n if (normalizedSort.length) {\n const orderOptions = this.orderOptions(normalizedSort);\n const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;\n orderOptionKeys.forEach((key) => {\n const resolvedKey = aliasMap[key] || key as string;\n const value = orderOptions[key] as 'ASC' | 'DESC';\n qb.addOrderBy(`\"${resolvedKey}\"`, value);\n });\n }\n const hasLimit = limit !== undefined && limit !== null;\n const hasOffset = offset !== undefined && offset !== null;\n\n // Use both take/skip and limit/offset to ensure pagination is applied even when joins are present.\n if (hasLimit) {\n qb.take(limit);\n qb.limit(limit);\n }\n if (hasOffset) {\n qb.skip(offset);\n qb.offset(offset);\n }\n }\n\n async countGroups(qb: SelectQueryBuilder<any>) {\n const clone = qb.clone();\n clone.limit(undefined).offset(undefined).take(undefined).skip(undefined);\n const rows = await clone.getRawMany();\n return rows.length;\n }\n\n private buildJoinQueryForRelation(qb: SelectQueryBuilder<any>, entityAlias: string, relation: string) {\n // We split the joinProperty to get the alias of the entity we are joining\n const relationParts = relation.split('.');\n let parentAlias = entityAlias;\n relationParts.forEach((part, i) => {\n const joinProperty = `${parentAlias}.${part}`;\n // Check if the relation is already joined, if not then join it\n if (!this.isRelationJoined(qb, joinProperty)) {\n const joinAlias = relationParts.slice(0, i + 1).join('_');\n qb.leftJoinAndSelect(joinProperty, joinAlias);\n }\n else {\n // Since in populate, we are create a unique alias based on the relation path\n //If the join is already present, it is probably because of the relation being passed in the where filter i.e applyFilters method\n qb.addSelect(`${part}`);\n }\n parentAlias = part; // Update the parent alias for the next iteration\n });\n return qb;\n }\n\n private wrapFieldWithAlias(field: string, entityAlias: string): string {\n if (!this.isAggregateField(field)) return `${entityAlias}.${field}`;\n // For aggregate fields, extract the field name from the aggregate function & wrap it with the entity alias, if it is not already wrapped\n const fieldParts = field.split('(');\n const aggregateFunction = fieldParts[0];\n const fieldName = fieldParts[1].replace(')', '');\n return `${aggregateFunction}(${entityAlias}.${fieldName})`;\n }\n\n isAggregateField(field: string): boolean {\n return field.includes('(');\n }\n\n isAggregateFieldKey(key: string, aggregateAliases: Set<string>): boolean {\n return aggregateAliases.has(key);\n }\n\n getFieldFromQueryFieldKey(queryFieldKey: string, alias: string): string {\n return queryFieldKey.replace(`${alias}_`, '');\n }\n\n buildGroupByRecordsQuery(\n qb: SelectQueryBuilder<any>,\n group: any,\n alias: string,\n groupAliasMap: Record<string, string> = {},\n aggregateAliasMap: Record<string, string> = {},\n groupExpressionMap: Record<string, string> = {}\n ): SelectQueryBuilder<any> {\n const rootAlias = qb.expressionMap?.mainAlias?.name\n ?? qb.expressionMap?.aliases?.find(a => a.metadata)?.name\n ?? qb.expressionMap?.aliases?.[0]?.name\n ?? (qb as any).alias\n ?? alias;\n qb.andWhere(new Brackets(qb => {\n const aggregateAliasSet = new Set(Object.values(aggregateAliasMap));\n const reverseGroupAliasMap = Object.entries(groupAliasMap).reduce((acc, [sourceKey, aliasKey]) => {\n acc[aliasKey] = sourceKey;\n return acc;\n }, {} as Record<string, string>);\n for (const key in group) {\n if (group.hasOwnProperty(key) && !this.isAggregateFieldKey(key, aggregateAliasSet)) {\n const value = group[key];\n const sourceField = reverseGroupAliasMap[key] || key;\n const cleanedField = sourceField.split(':')[0];\n const pathParts = cleanedField.split('.');\n const { alias: resolvedAlias, property } = this.ensureRelationPathJoined(qb as any, rootAlias, pathParts);\n const paramKey = this.sanitizeAlias(`${resolvedAlias}_${property}_${key}`);\n const expr = (sourceField.includes(':') && groupExpressionMap[key])\n ? groupExpressionMap[key]\n : `${resolvedAlias}.${property}`;\n qb.andWhere(`${expr} = :${paramKey}`, { [paramKey]: value });\n }\n }\n }));\n return qb;\n }\n\n private formatGroupValue(value: any, format?: string) {\n if (!format) return value;\n if (value === null || value === undefined) return value;\n const dateVal = value instanceof Date ? value : new Date(value);\n if (isNaN(dateVal.getTime())) return value;\n switch (format) {\n case 'MMM':\n return dateVal.toLocaleString('en', { month: 'short' });\n case 'MMMM':\n return dateVal.toLocaleString('en', { month: 'long' });\n case 'YYYY':\n return dateVal.getFullYear();\n case 'YYYY-MM':\n return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}`;\n case 'YYYY-MM-DD':\n return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}-${String(dateVal.getDate()).padStart(2, '0')}`;\n default:\n return value;\n }\n }\n\n getGroupName(\n group: any,\n aggregateAliases: Set<string>,\n groupByFields: string[],\n groupAliasMap: Record<string, string>,\n groupFormatMap: Record<string, string | undefined>\n ): string {\n const orderedValues = groupByFields\n .map(field => {\n const alias = groupAliasMap[field] ?? this.sanitizeAlias(field.replace(/\\./g, '_'));\n const rawVal = group[alias] ?? group[field] ?? group[field.replace(/\\./g, '_')];\n return this.formatGroupValue(rawVal, groupFormatMap[alias]);\n })\n .filter(v => v !== undefined && v !== null);\n\n if (orderedValues.length === 0) {\n return Object.keys(group)\n .filter(key => !this.isAggregateFieldKey(key, aggregateAliases))\n .map(key => group[key])\n .join('_');\n }\n\n return orderedValues.join('_');\n }\n\n createGroupRecords(group: any, aggregateAliases: Set<string>, groupData: any, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {\n const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);\n return {\n groupName,\n groupData\n }\n }\n createGroupMeta(group: any, aggregateAliases: Set<string>, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {\n const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);\n const groupAggregateValues = {}\n for (const key in group) {\n if (group.hasOwnProperty(key) && this.isAggregateFieldKey(key, aggregateAliases)) {\n const value = group[key];\n groupAggregateValues[key] = value;\n }\n }\n return {\n groupName,\n ...groupAggregateValues\n };\n }\n\n async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any\n const { limit, offset, ...rest } = basicFilterDto;\n const filteredDto = { ...rest, limit: undefined, offset: undefined };\n\n const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, undefined, undefined, undefined, FilterCombinator.AND, false, false);\n\n const groupByFields = this.normalize(filteredDto.groupBy);\n\n if (!groupByFields || groupByFields.length === 0) {\n throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);\n }\n\n this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);\n this.applyAggregates(filteredQB, ['count'], entityAlias);\n filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);\n\n const rawResults = await filteredQB.getRawMany();\n return rawResults.length;\n }\n\n hasReadPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.findOne`, `${classify(modelName)}Controller.findMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasWritePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.create`, `${classify(modelName)}Controller.insertMany`, `${classify(modelName)}Controller.update`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasUpdatePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.update`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasPublishPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.publish`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasUnpublishPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.publish`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n hasDeletePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.delete`, `${classify(modelName)}Controller.deleteMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n hasCreatePermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.create`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n hasRecoverPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {\n const permissionNames = [`${classify(modelName)}Controller.recover`, `${classify(modelName)}Controller.recoverMany`];\n const matchingPermssions = activeUser.permissions.filter((p) => permissionNames.includes(p));\n return matchingPermssions.length > 0\n }\n\n\n\n}\n"]}
@@ -12,7 +12,6 @@ class DatabasePublisher {
12
12
  if (!this.serviceRole) {
13
13
  this.logger.debug('Queue service Role is not defined in the environment variables');
14
14
  }
15
- this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);
16
15
  }
17
16
  async publish(message) {
18
17
  if (!this.serviceRole) {
@@ -1 +1 @@
1
- {"version":3,"file":"database-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-publisher.service.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,+BAAoC;AAMpC,MAAsB,iBAAiB;IAKnC,YACuB,gBAAkC,EAClC,qBAA4C;QAD5C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QANlD,WAAM,GAAG,IAAI,eAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAQzD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5G,CAAC;IAID,KAAK,CAAC,OAAO,CAAC,OAAwB;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAElG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,aAAa;YAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;QAGzD,OAAO,CAAC,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;QAG7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAGjD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,OAAwB;QAEvE,IAAI,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAGhF,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAC/B,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI;gBAClC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,gBAAgB,EAAE,cAAc,CAAC,EAAE;aACtC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IAEL,CAAC;CACJ;AAvED,8CAuEC","sourcesContent":["import { Logger } from '@nestjs/common';\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';\n\nexport abstract class DatabasePublisher<T> implements QueuePublisher<T> {\n private readonly logger = new Logger(DatabasePublisher.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract options(): QueuesModuleOptions;\n\n async publish(message: QueueMessage<T>): Promise<string> {\n if (!this.serviceRole) {\n this.logger.error('Queue service Role is not defined in the environment variables');\n throw new Error('Queue service Role is not defined in the environment variables');\n }\n if (this.serviceRole === 'subscriber') {\n this.logger.error('Queue service Role is subscriber, cannot publish messages');\n throw new Error('Queue service Role is subscriber, cannot publish messages');\n }\n\n this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}`);\n\n const options = this.options();\n\n const queueName = options.queueName;\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n\n // generate a new message id \n message.messageId = uuidv4();\n\n // Save the message to the DB so that we can then change its status in the subscriber...\n await this.persistToDatabase(queueName, message);\n\n // return the newly created message id.\n return message.messageId;\n }\n\n private async persistToDatabase(queueName: string, message: QueueMessage<T>) {\n // make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);\n\n // 2. Next create an entry in the mqMessage table. \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 }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n}\n"]}
1
+ {"version":3,"file":"database-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-publisher.service.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,+BAAoC;AAMpC,MAAsB,iBAAiB;IAKnC,YACuB,gBAAkC,EAClC,qBAA4C;QAD5C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QANlD,WAAM,GAAG,IAAI,eAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAQzD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACxF,CAAC;IAEL,CAAC;IAID,KAAK,CAAC,OAAO,CAAC,OAAwB;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAElG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,aAAa;YAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;QAGzD,OAAO,CAAC,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;QAG7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAGjD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,OAAwB;QAEvE,IAAI,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAGhF,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAC/B,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI;gBAClC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,gBAAgB,EAAE,cAAc,CAAC,EAAE;aACtC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IAEL,CAAC;CACJ;AAvED,8CAuEC","sourcesContent":["import { Logger } from '@nestjs/common';\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';\n\nexport abstract class DatabasePublisher<T> implements QueuePublisher<T> {\n private readonly logger = new Logger(DatabasePublisher.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract options(): QueuesModuleOptions;\n\n async publish(message: QueueMessage<T>): Promise<string> {\n if (!this.serviceRole) {\n this.logger.error('Queue service Role is not defined in the environment variables');\n throw new Error('Queue service Role is not defined in the environment variables');\n }\n if (this.serviceRole === 'subscriber') {\n this.logger.error('Queue service Role is subscriber, cannot publish messages');\n throw new Error('Queue service Role is subscriber, cannot publish messages');\n }\n\n this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}`);\n\n const options = this.options();\n\n const queueName = options.queueName;\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n\n // generate a new message id \n message.messageId = uuidv4();\n\n // Save the message to the DB so that we can then change its status in the subscriber...\n await this.persistToDatabase(queueName, message);\n\n // return the newly created message id.\n return message.messageId;\n }\n\n private async persistToDatabase(queueName: string, message: QueueMessage<T>) {\n // make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);\n\n // 2. Next create an entry in the mqMessage table. \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 }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,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;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAP5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa;IAS5C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IAsEnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBnC,eAAe;cASC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
1
+ {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,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;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAP5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa;IAS5C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IA6CnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAoCnC,eAAe;cASC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
@@ -12,7 +12,6 @@ class DatabaseSubscriber {
12
12
  if (!this.serviceRole) {
13
13
  this.logger.debug('Queue service Role is not defined in the environment variables');
14
14
  }
15
- this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);
16
15
  }
17
16
  async processNext(queueName) {
18
17
  const job = await this.mqMessageService.lockNextPendingMessage(queueName);
@@ -52,9 +51,23 @@ class DatabaseSubscriber {
52
51
  async onModuleInit() {
53
52
  const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';
54
53
  const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
54
+ const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
55
55
  if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === "false") {
56
56
  const options = this.options();
57
57
  const queueName = options.queueName;
58
+ if (queueNameRegex && queueNameRegex !== "all") {
59
+ try {
60
+ const regex = new RegExp(queueNameRegex);
61
+ if (!regex.test(queueName)) {
62
+ this.logger.log(`DatabaseSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);
63
+ return;
64
+ }
65
+ }
66
+ catch (error) {
67
+ this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex "${queueNameRegex}". Subscriber for queue ${queueName} will not start.`);
68
+ return;
69
+ }
70
+ }
58
71
  this.poller.start(queueName, (q) => this.processNext(q), {
59
72
  baseDelayMs: 1000,
60
73
  maxDelayMs: 30_000,
@@ -1 +1 @@
1
- {"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { PollerService } from '../poller.service';\n\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private readonly logger = new Logger(DatabaseSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n protected readonly poller: PollerService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n // async onModuleInit(): Promise<void> {\n // // we will start subscriber only if the current service role is subscriber. \n // if (['both', 'subscriber'].includes(this.serviceRole)) {\n\n // const options = this.options();\n\n // const queueName = options.queueName;\n // // setInterval(() => this.processNext(queueName), 1000);\n // const poll = async () => {\n // try {\n // await this.processNext(queueName);\n // } catch (err) {\n // this.logger.error(`Polling error: ${err.message}`);\n // } finally {\n // setTimeout(poll, 1000); // Wait 1s *after* processing finishes\n // }\n // };\n\n // // start the loop\n // poll();\n\n // this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n // }\n // }\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\n // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === \"false\") {\n\n const options = this.options();\n\n const queueName = options.queueName;\n\n this.poller.start(queueName, (q) => this.processNext(q), {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n timeoutPerIterationMs: 5 * 60_000,\n jitter: true,\n });\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n onModuleDestroy() {\n const options = this.options();\n const queueName = options.queueName;\n this.poller.stop(queueName);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\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') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"database-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\nimport { PollerService } from '../poller.service';\n\n\nexport abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {\n private readonly logger = new Logger(DatabaseSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n protected readonly poller: PollerService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n private async processNext(queueName: string) {\n // this.logger.debug(`#### DatabaseSubscriber processing next message from queue: ${queueName}`);\n const job = await this.mqMessageService.lockNextPendingMessage(queueName);\n if (!job) {\n return;\n }\n\n const messageContentString = job.input.toString();\n // this.logger.debug(`DatabaseSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n // Discard the message after max retries\n await this.updateStatusInDatabase('failed', message, error.message, '');\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n }\n }\n }\n // this.logger.debug(`#### DatabaseSubscriber finished processing message from queue: ${queueName}`);\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of DatabaseSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\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 // we will start subscriber only if the current service role is subscriber. \n if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database' && solidCliRunning === \"false\") {\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(`DatabaseSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n this.poller.start(queueName, (q) => this.processNext(q), {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n timeoutPerIterationMs: 5 * 60_000,\n jitter: true,\n });\n\n this.logger.log(`DatabaseSubscriber ready to consume messages: ${JSON.stringify(this.options())}`);\n }\n }\n\n onModuleDestroy() {\n const options = this.options();\n const queueName = options.queueName;\n this.poller.stop(queueName);\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>) {\n try {\n await this.processMessage(message);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message);\n }, message.retryInterval);\n } else {\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n try {\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${message.messageId}`);\n\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n this.logger.debug(`Found message in database: ${JSON.stringify(mqMessage.messageId)}`);\n this.logger.debug(`Updating message status in database: ${stage} for messageId: ${mqMessage.id}`);\n\n const updatedFields = {\n stage: stage\n };\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') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n this.logger.debug(`Message status updated to ${stage} for messageId: ${mqMessage.id}`);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"rabbitmq-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,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,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IANnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAanE,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;IAEjC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAqB/C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cA4FnB,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB9E,YAAY;YA0BZ,sBAAsB;CAkCvC"}
1
+ {"version":3,"file":"rabbitmq-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,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,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IANnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB;IAanE,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;IAEjC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAqB/C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;cA4GnB,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,KAAA,EAAE,OAAO,KAAA,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB9E,YAAY;YA0BZ,sBAAsB;CAkCvC"}
@@ -63,8 +63,25 @@ class RabbitMqSubscriber {
63
63
  return connection;
64
64
  }
65
65
  async onModuleInit() {
66
+ const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';
66
67
  const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
67
- if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === "false") {
68
+ const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
69
+ if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === "false" && defaultBroker === 'rabbitmq') {
70
+ const options = this.options();
71
+ const queueName = options.queueName;
72
+ if (queueNameRegex && queueNameRegex !== "all") {
73
+ try {
74
+ const regex = new RegExp(queueNameRegex);
75
+ if (!regex.test(queueName)) {
76
+ this.logger.log(`RabbitMqSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);
77
+ return;
78
+ }
79
+ }
80
+ catch (error) {
81
+ this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex "${queueNameRegex}". Subscriber for queue ${queueName} will not start.`);
82
+ return;
83
+ }
84
+ }
68
85
  let connection;
69
86
  try {
70
87
  connection = await this.establishConnection();
@@ -74,8 +91,6 @@ class RabbitMqSubscriber {
74
91
  throw err;
75
92
  }
76
93
  const channel = await connection.createChannel();
77
- const options = this.options();
78
- const queueName = options.queueName;
79
94
  const exchangeName = `${queueName}.exchange`;
80
95
  const routingKey = `${queueName}.routing-key`;
81
96
  await channel.assertExchange(exchangeName, 'direct', {});
@@ -1 +1 @@
1
- {"version":3,"file":"rabbitmq-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAsD;AACtD,8CAAgC;AAOhC,MAAsB,kBAAkB;IAKpC,YACuB,gBAAkC,EAClC,qBAA4C;QAD5C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QANlD,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAQ1D,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACxF,CAAC;IAEL,CAAC;IAMD,KAAK,CAAC,mBAAmB;QAErB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAO9B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;YAClC,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;YACvC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1C,QAAQ,EAAE,MAAM;SACnB,CAAC,CAAC;QAEH,OAAO,UAAU,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,YAAY;QACd,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC;QAGjE,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;YAK/F,IAAI,UAAU,CAAC;YACf,IAAI,CAAC;gBACD,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAElD,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,EAAG,GAAa,CAAC,KAAK,CAAC,CAAC;gBACpG,MAAM,GAAG,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,aAAa,EAAE,CAAC;YAGjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;YACpC,MAAM,YAAY,GAAG,GAAG,SAAS,WAAW,CAAC;YAC7C,MAAM,UAAU,GAAG,GAAG,SAAS,cAAc,CAAC;YAE9C,MAAM,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YAGzD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAGvD,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;YAI/D,OAAO,CAAC,OAAO,CACX,KAAK,CAAC,KAAK,EACX,KAAK,EAAE,UAAU,EAAE,EAAE;gBACjB,IAAI,UAAU,EAAE,CAAC;oBACb,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBAG3D,IAAI,OAAO,GAAoB,IAAI,CAAC;oBAEpC,IAAI,CAAC;wBACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAoB,CAAC;wBAG9D,IAAI,CAAC,OAAO,CAAC,UAAU;4BAAE,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;wBAChD,IAAI,CAAC,OAAO,CAAC,aAAa;4BAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;wBACzD,IAAI,CAAC,OAAO,CAAC,YAAY;4BAAE,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC;wBAEpD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;oBAC5D,CAAC;oBACD,OAAO,KAAK,EAAE,CAAC;wBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;wBAGhE,IAAI,OAAO,EAAE,CAAC;4BACV,IAAI,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;gCAC5C,MAAM,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gCAEvD,OAAO,CAAC,YAAY,EAAE,CAAC;gCACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,WAAW,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC;gCACtH,UAAU,CAAC,GAAG,EAAE;oCACZ,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;gCACpD,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;4BAC9B,CAAC;iCAAM,CAAC;gCACJ,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gCAExE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,CAAC,UAAU,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gCAC3F,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;4BAC5B,CAAC;wBACL,CAAC;oBAEL,CAAC;gBACL,CAAC;YACL,CAAC,EAED,EAAE,CACL,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iDAAiD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,aAAa,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5H,CAAC;IACL,CAAC;IAKS,KAAK,CAAC,cAAc,CAAC,OAAwB,EAAE,UAAU,EAAE,OAAO;QACxE,MAAM,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAGtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAG7C,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAGxB,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAE/G,CAAC;IAKO,KAAK,CAAC,YAAY,CAAC,OAAwB,EAAE,UAAU,EAAE,OAAO;QACpE,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC5C,MAAM,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAEvD,OAAO,CAAC,YAAY,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,UAAU,WAAW,OAAO,CAAC,aAAa,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACxI,UAAU,CAAC,GAAG,EAAE;oBACZ,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;gBACpD,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBAEJ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,CAAC,UAAU,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAG3F,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAGxB,MAAM,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAE5E,CAAC;QACL,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,KAAa,EAAE,OAAwB,EAAE,QAAgB,EAAE,EAAE,SAAiB,EAAE;QAGjH,IAAI,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;gBACvD,KAAK,EAAE;oBACH,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC/B;aACJ,CAAC,CAAC;YAEH,IAAI,SAAS,EAAE,CAAC;gBACZ,MAAM,aAAa,GAAG;oBAClB,KAAK,EAAE,KAAK;iBACf,CAAC;gBACF,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;oBAC9C,aAAa,CAAC,YAAY,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;oBACzC,aAAa,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC3G,CAAC;gBACD,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;oBACxB,aAAa,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;gBACrC,CAAC;gBACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACrB,aAAa,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;gBACnC,CAAC;gBACD,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;YACzE,CAAC;QACL,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IAEL,CAAC;CAEJ;AAtND,gDAsNC","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport * as amqp from 'amqplib';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\n\n\nexport abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility\n private readonly logger = new Logger(RabbitMqSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.url = process.env.QUEUES_RABBIT_MQ_URL;\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.url) {\n this.logger.debug('RabbitMqPublisher url is not defined in the environment variables');\n }\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n async establishConnection(): Promise<amqp.Connection> {\n\n const url = new URL(this.url);\n\n // this.logger.debug(`user: ${url.username}`);\n // // just for local debug, don’t log in prod\n // this.logger.debug(`pass: ${url.password}`);\n // this.logger.debug(`path (vhost): ${url.pathname}`);\n\n const connection = await amqp.connect({\n protocol: url.protocol.replace(':', ''),\n hostname: url.hostname,\n port: parseInt(url.port),\n username: url.username,\n password: decodeURIComponent(url.password),\n frameMax: 131072,\n });\n\n return connection\n }\n\n async onModuleInit(): Promise<void> {\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n\n // we will start subscriber only if the current service role is subscriber. \n if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === \"false\") {\n\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n // const connection = await amqp.connect(this.url);\n\n let connection;\n try {\n connection = await this.establishConnection();\n // this.logger.debug(`RabbitMqSubscriber connection established: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ: ${(err as Error).message}`, (err as Error).stack);\n throw err;\n }\n\n const channel = await connection.createChannel();\n // this.logger.debug(`RabbitMqSubscriber channel created: ${JSON.stringify(this.options())} and url: ${url}`);\n\n const options = this.options();\n\n const queueName = options.queueName;\n const exchangeName = `${queueName}.exchange`;\n const routingKey = `${queueName}.routing-key`;\n\n await channel.assertExchange(exchangeName, 'direct', {});\n // this.logger.debug(`RabbitMqSubscriber channel asserted: ${JSON.stringify(this.options())} and url: ${url}`);\n\n const queue = await channel.assertQueue(queueName, {});\n // this.logger.debug(`RabbitMqSubscriber queue asserted: ${JSON.stringify(this.options())} and url: ${url}`);\n\n await channel.bindQueue(queue.queue, exchangeName, routingKey);\n // this.logger.debug(`RabbitMqSubscriber queue bound: ${JSON.stringify(this.options())} and url: ${url}`);\n\n // Consume messages from the queue\n channel.consume(\n queue.queue,\n async (rawMessage) => {\n if (rawMessage) {\n const messageContentString = rawMessage.content.toString();\n // this.logger.debug(`RabbitMqSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message, rawMessage, channel);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message, rawMessage, channel);\n }, message.retryInterval);\n } else {\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n channel.ack(rawMessage); // Discard the message after max retries\n }\n }\n\n }\n }\n },\n // { noAck: true },\n {},\n );\n\n this.logger.log(`RabbitMqSubscriber ready to consume messages: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // Ack the message. \n channel.ack(rawMessage);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>, rawMessage, channel) {\n try {\n await this.processMessage(message, rawMessage, channel);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message, rawMessage, channel);\n }, message.retryInterval);\n } else {\n\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // Discard the message after max retries\n channel.ack(rawMessage);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n\n // TODO: make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n const updatedFields = {\n stage: stage\n };\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') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n\n}"]}
1
+ {"version":3,"file":"rabbitmq-subscriber.service.js","sourceRoot":"","sources":["../../../src/services/queues/rabbitmq-subscriber.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger, OnModuleInit } from '@nestjs/common';\nimport * as amqp from 'amqplib';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueueSubscriber } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\n\n\nexport abstract class RabbitMqSubscriber<T> implements OnModuleInit, QueueSubscriber<T> { // TODO This can be made a generic type for better type visibility\n private readonly logger = new Logger(RabbitMqSubscriber.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.url = process.env.QUEUES_RABBIT_MQ_URL;\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.url) {\n this.logger.debug('RabbitMqPublisher url is not defined in the environment variables');\n }\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n\n abstract subscribe(message: QueueMessage<T>);\n\n abstract options(): QueuesModuleOptions;\n\n async establishConnection(): Promise<amqp.Connection> {\n\n const url = new URL(this.url);\n\n // this.logger.debug(`user: ${url.username}`);\n // // just for local debug, don’t log in prod\n // this.logger.debug(`pass: ${url.password}`);\n // this.logger.debug(`path (vhost): ${url.pathname}`);\n\n const connection = await amqp.connect({\n protocol: url.protocol.replace(':', ''),\n hostname: url.hostname,\n port: parseInt(url.port),\n username: url.username,\n password: decodeURIComponent(url.password),\n frameMax: 131072,\n });\n\n return connection\n }\n\n async onModuleInit(): Promise<void> {\n // Not using SettingService here as that will necessitate all implementors of RabbitMqSubscriber to also inject SettingService which is not ideal. \n // Instead we directly read the environment variables here.\n const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'rabbitmq';\n const solidCliRunning = process.env.SOLID_CLI_RUNNING || \"false\";\n const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();\n\n // we will start subscriber only if the current service role is subscriber. \n if (this.url && ['both', 'subscriber'].includes(this.serviceRole) && solidCliRunning === \"false\" && defaultBroker === 'rabbitmq') {\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(`RabbitMqSubscriber for queue ${queueName} is disabled because it does not match QUEUES_QUEUE_NAME_REGEX_TO_ENABLE=${queueNameRegex}`);\n return;\n }\n } catch (error) {\n this.logger.error(`Invalid QUEUES_QUEUE_NAME_REGEX_TO_ENABLE regex \"${queueNameRegex}\". Subscriber for queue ${queueName} will not start.`);\n return;\n }\n }\n\n // this.logger.debug(`RabbitMqSubscriber instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n // const connection = await amqp.connect(this.url);\n\n let connection;\n try {\n connection = await this.establishConnection();\n // this.logger.debug(`RabbitMqSubscriber connection established: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n catch (err) {\n this.logger.error(`Failed to connect to RabbitMQ: ${(err as Error).message}`, (err as Error).stack);\n throw err;\n }\n\n const channel = await connection.createChannel();\n // this.logger.debug(`RabbitMqSubscriber channel created: ${JSON.stringify(this.options())} and url: ${url}`);\n\n const exchangeName = `${queueName}.exchange`;\n const routingKey = `${queueName}.routing-key`;\n\n await channel.assertExchange(exchangeName, 'direct', {});\n // this.logger.debug(`RabbitMqSubscriber channel asserted: ${JSON.stringify(this.options())} and url: ${url}`);\n\n const queue = await channel.assertQueue(queueName, {});\n // this.logger.debug(`RabbitMqSubscriber queue asserted: ${JSON.stringify(this.options())} and url: ${url}`);\n\n await channel.bindQueue(queue.queue, exchangeName, routingKey);\n // this.logger.debug(`RabbitMqSubscriber queue bound: ${JSON.stringify(this.options())} and url: ${url}`);\n\n // Consume messages from the queue\n channel.consume(\n queue.queue,\n async (rawMessage) => {\n if (rawMessage) {\n const messageContentString = rawMessage.content.toString();\n // this.logger.debug(`RabbitMqSubscriber Received raw message: ${messageContentString}`);\n\n let message: QueueMessage<T> = null;\n\n try {\n message = JSON.parse(messageContentString) as QueueMessage<T>;\n\n // this is the first time we are receiving the message so we set the currentRetry to 0\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n if (!message.currentRetry) message.currentRetry = 0;\n\n await this.processMessage(message, rawMessage, channel);\n }\n catch (error) {\n this.logger.error(`Error processing message: ${error.message}`);\n\n // if an error occurs then if retryCount is set we start retrying. \n if (message) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms`);\n setTimeout(() => {\n this.retryMessage(message, rawMessage, channel);\n }, message.retryInterval);\n } else {\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n channel.ack(rawMessage); // Discard the message after max retries\n }\n }\n\n }\n }\n },\n // { noAck: true },\n {},\n );\n\n this.logger.log(`RabbitMqSubscriber ready to consume messages: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n }\n\n /**\n * Abstract method for message processing logic.\n */\n protected async processMessage(message: QueueMessage<T>, rawMessage, channel): Promise<void> {\n await this.updateStatusInDatabase('started', message);\n\n // Capture the results of handling the task.\n const result = await this.subscribe(message);\n\n // Ack the message. \n channel.ack(rawMessage);\n\n // TODO: Update the database to indicate that the task is finished.\n await this.updateStatusInDatabase('succeeded', message, '', result ? JSON.stringify(result, null, 2) : '');\n\n }\n\n /**\n * Retry the message by invoking the processing logic again.\n */\n private async retryMessage(message: QueueMessage<T>, rawMessage, channel) {\n try {\n await this.processMessage(message, rawMessage, channel);\n } catch (error) {\n if (message.currentRetry < message.retryCount) {\n await this.updateStatusInDatabase('retrying', message);\n\n message.currentRetry++;\n this.logger.warn(`Retrying message (${message.currentRetry}/${message.retryCount}) after ${message.retryInterval}ms: ${error.message}`);\n setTimeout(() => {\n this.retryMessage(message, rawMessage, channel);\n }, message.retryInterval);\n } else {\n\n this.logger.error(`Message failed after ${message.retryCount} attempts: ${error.message}`);\n\n // Discard the message after max retries\n channel.ack(rawMessage);\n\n // TODO: Store the error in the database and update the status accordingly.\n await this.updateStatusInDatabase('failed', message, error.message, '');\n\n }\n }\n }\n\n private async updateStatusInDatabase(stage: string, message: QueueMessage<T>, error: string = '', result: string = '') {\n\n // TODO: make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessage = await this.mqMessageService.repo.findOne({\n where: {\n messageId: message.messageId,\n }\n });\n\n if (mqMessage) {\n const updatedFields = {\n stage: stage\n };\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') {\n updatedFields['output'] = result;\n }\n if (stage === 'failed') {\n updatedFields['error'] = error;\n }\n await this.mqMessageService.repo.update(mqMessage.id, updatedFields);\n }\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n\n}\n"]}
@@ -5,6 +5,7 @@ export declare class SchedulerServiceImpl implements ISchedulerService {
5
5
  private readonly scheduledJobRepo;
6
6
  private readonly solidRegistry;
7
7
  private readonly logger;
8
+ private readonly runningJobs;
8
9
  constructor(scheduledJobRepo: ScheduledJobRepository, solidRegistry: SolidRegistry);
9
10
  runScheduledJobs(): Promise<void>;
10
11
  private shouldRunNow;