itlab-internal-services 2.16.1 → 2.16.3

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 (201) hide show
  1. package/dist/classes/document/commentable-document.class.d.ts +200 -0
  2. package/dist/classes/document/commentable-document.class.js +24 -0
  3. package/dist/classes/document/content-document.class.d.ts +200 -0
  4. package/dist/classes/document/content-document.class.js +24 -0
  5. package/dist/classes/document/index.d.ts +4 -0
  6. package/dist/classes/document/index.js +11 -0
  7. package/dist/classes/document/likeable-document.class.d.ts +205 -0
  8. package/dist/classes/document/likeable-document.class.js +70 -0
  9. package/dist/classes/document/viewable-document.class.d.ts +205 -0
  10. package/dist/classes/document/viewable-document.class.js +67 -0
  11. package/dist/classes/document-updater.class.d.ts +40 -0
  12. package/dist/classes/document-updater.class.js +58 -0
  13. package/dist/classes/fetch-options/base-options.class.d.ts +18 -0
  14. package/dist/classes/fetch-options/base-options.class.js +81 -0
  15. package/dist/classes/fetch-options/comments-options.class.d.ts +6 -0
  16. package/dist/classes/fetch-options/comments-options.class.js +26 -0
  17. package/dist/classes/fetch-options/content-options.class.d.ts +7 -0
  18. package/dist/classes/fetch-options/content-options.class.js +32 -0
  19. package/dist/classes/fetch-options/drafted-options.class.d.ts +9 -0
  20. package/dist/classes/fetch-options/drafted-options.class.js +34 -0
  21. package/dist/classes/fetch-options/index.d.ts +6 -0
  22. package/dist/classes/fetch-options/index.js +15 -0
  23. package/dist/classes/fetch-options/liked-by-options.class.d.ts +8 -0
  24. package/dist/classes/fetch-options/liked-by-options.class.js +28 -0
  25. package/dist/classes/fetch-options/viewed-by-options.class.d.ts +9 -0
  26. package/dist/classes/fetch-options/viewed-by-options.class.js +28 -0
  27. package/dist/classes/index.d.ts +2 -2
  28. package/dist/classes/index.js +17 -3
  29. package/dist/classes/task-manager.class.d.ts +2 -2
  30. package/dist/classes/task-manager.class.js +4 -0
  31. package/dist/decorators/has-permission.decorator.d.ts +3 -0
  32. package/dist/decorators/has-permission.decorator.js +26 -0
  33. package/dist/decorators/index.d.ts +2 -0
  34. package/dist/decorators/index.js +2 -0
  35. package/dist/decorators/jwt.decorator.d.ts +1 -1
  36. package/dist/decorators/jwt.decorator.js +13 -11
  37. package/dist/decorators/schema-with-critical-keys.decorator.d.ts +12 -0
  38. package/dist/decorators/schema-with-critical-keys.decorator.js +16 -0
  39. package/dist/factories/index.d.ts +1 -0
  40. package/dist/factories/index.js +5 -0
  41. package/dist/factories/virtuals.factory.d.ts +80 -0
  42. package/dist/factories/virtuals.factory.js +172 -0
  43. package/dist/functions/create-schema.function.d.ts +3 -0
  44. package/dist/functions/create-schema.function.js +33 -0
  45. package/dist/functions/index.d.ts +1 -1
  46. package/dist/functions/index.js +3 -3
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.js +10 -0
  49. package/dist/likeable.interface.d.ts +42 -0
  50. package/dist/likeable.interface.js +48 -0
  51. package/dist/modules/_old/comment/comment.controller.d.ts +35 -0
  52. package/dist/modules/_old/comment/comment.controller.js +86 -0
  53. package/dist/modules/_old/comment/comment.model.d.ts +29 -0
  54. package/dist/modules/_old/comment/comment.model.js +43 -0
  55. package/dist/modules/_old/comment/comment.module-definition.d.ts +45 -0
  56. package/dist/modules/{comment → _old/comment}/comment.module-definition.js +2 -1
  57. package/dist/modules/_old/comment/comment.module.d.ts +22 -0
  58. package/dist/modules/_old/comment/comment.module.js +71 -0
  59. package/dist/modules/_old/comment/comment.service.d.ts +54 -0
  60. package/dist/modules/_old/comment/comment.service.js +133 -0
  61. package/dist/modules/_old/comment/index.d.ts +3 -0
  62. package/dist/modules/_old/comment/index.js +9 -0
  63. package/dist/modules/_old/content/content.module-definition.d.ts +5 -0
  64. package/dist/modules/_old/content/content.module-definition.js +8 -0
  65. package/dist/modules/_old/content/content.module.d.ts +31 -0
  66. package/dist/modules/_old/content/content.module.js +60 -0
  67. package/dist/modules/_old/content/content.service.d.ts +50 -0
  68. package/dist/modules/_old/content/content.service.js +145 -0
  69. package/dist/modules/_old/content/index.d.ts +2 -0
  70. package/dist/modules/_old/content/index.js +7 -0
  71. package/dist/modules/_old/database/database-module-options.interface.d.ts +41 -0
  72. package/dist/modules/_old/database/database.liveness-controller.d.ts +27 -0
  73. package/dist/modules/_old/database/database.liveness-controller.js +80 -0
  74. package/dist/modules/_old/database/database.module.d.ts +41 -0
  75. package/dist/modules/_old/database/database.module.js +97 -0
  76. package/dist/modules/_old/database/index.d.ts +6 -0
  77. package/dist/modules/_old/database/index.js +13 -0
  78. package/dist/modules/_old/database/lock-service/lock.schema.d.ts +38 -0
  79. package/dist/modules/_old/database/lock-service/lock.schema.js +51 -0
  80. package/dist/modules/_old/database/lock-service/lock.service.d.ts +53 -0
  81. package/dist/modules/_old/database/lock-service/lock.service.js +103 -0
  82. package/dist/modules/_old/database/model-service/dbs/hub-account.db.d.ts +28 -0
  83. package/dist/modules/_old/database/model-service/dbs/hub-account.db.js +44 -0
  84. package/dist/modules/_old/database/model-service/dbs/hub-books.db.d.ts +23 -0
  85. package/dist/modules/_old/database/model-service/dbs/hub-books.db.js +45 -0
  86. package/dist/modules/_old/database/model-service/dbs/hub-comments.db.d.ts +29 -0
  87. package/dist/modules/_old/database/model-service/dbs/hub-comments.db.js +68 -0
  88. package/dist/modules/_old/database/model-service/dbs/hub-content.db.d.ts +24 -0
  89. package/dist/modules/_old/database/model-service/dbs/hub-content.db.js +49 -0
  90. package/dist/modules/_old/database/model-service/dbs/hub-demo-hive.db.d.ts +23 -0
  91. package/dist/modules/_old/database/model-service/dbs/hub-demo-hive.db.js +45 -0
  92. package/dist/modules/_old/database/model-service/dbs/hub-events.db.d.ts +24 -0
  93. package/dist/modules/_old/database/model-service/dbs/hub-events.db.js +49 -0
  94. package/dist/modules/_old/database/model-service/dbs/hub-hackschool.db.d.ts +60 -0
  95. package/dist/modules/_old/database/model-service/dbs/hub-hackschool.db.js +106 -0
  96. package/dist/modules/_old/database/model-service/dbs/hub-newsroom.db.d.ts +25 -0
  97. package/dist/modules/_old/database/model-service/dbs/hub-newsroom.db.js +53 -0
  98. package/dist/modules/_old/database/model-service/dbs/hub-podcasts.db.d.ts +23 -0
  99. package/dist/modules/_old/database/model-service/dbs/hub-podcasts.db.js +45 -0
  100. package/dist/modules/_old/database/model-service/dbs/hub-team.db.d.ts +22 -0
  101. package/dist/modules/_old/database/model-service/dbs/hub-team.db.js +41 -0
  102. package/dist/modules/_old/database/model-service/dbs/hub-tech-radar.db.d.ts +42 -0
  103. package/dist/modules/_old/database/model-service/dbs/hub-tech-radar.db.js +81 -0
  104. package/dist/modules/_old/database/model-service/model.service.d.ts +8465 -0
  105. package/dist/modules/_old/database/model-service/model.service.js +136 -0
  106. package/dist/modules/_old/database/populate-service/populate.service.d.ts +73 -0
  107. package/dist/modules/_old/database/populate-service/populate.service.js +163 -0
  108. package/dist/modules/_old/database/service-mapper-service/service-mapper.service.d.ts +32 -0
  109. package/dist/modules/_old/database/service-mapper-service/service-mapper.service.js +73 -0
  110. package/dist/modules/_old/fetch/fetch.module.d.ts +31 -0
  111. package/dist/modules/_old/fetch/fetch.module.js +60 -0
  112. package/dist/modules/_old/fetch/fetch.service.d.ts +153 -0
  113. package/dist/modules/_old/fetch/fetch.service.js +274 -0
  114. package/dist/modules/_old/fetch/index.d.ts +2 -0
  115. package/dist/modules/_old/fetch/index.js +7 -0
  116. package/dist/modules/_old/index.d.ts +5 -0
  117. package/dist/modules/{comment → _old}/index.js +5 -2
  118. package/dist/modules/_old/like/index.d.ts +1 -0
  119. package/dist/modules/_old/like/index.js +5 -0
  120. package/dist/modules/_old/like/like.controller.d.ts +41 -0
  121. package/dist/modules/_old/like/like.controller.js +125 -0
  122. package/dist/modules/_old/like/like.module-definition.d.ts +20 -0
  123. package/dist/modules/_old/like/like.module-definition.js +8 -0
  124. package/dist/modules/_old/like/like.module.d.ts +21 -0
  125. package/dist/modules/_old/like/like.module.js +67 -0
  126. package/dist/modules/_old/like/like.service.d.ts +61 -0
  127. package/dist/modules/_old/like/like.service.js +103 -0
  128. package/dist/modules/authentication/guards/jwt-auth.guard.d.ts +1 -1
  129. package/dist/modules/authentication/guards/jwt-auth.guard.js +5 -3
  130. package/dist/modules/authentication/guards/permissions.guard.d.ts +1 -3
  131. package/dist/modules/authentication/guards/permissions.guard.js +2 -8
  132. package/dist/modules/authentication/guards/service-auth.guard.d.ts +0 -4
  133. package/dist/modules/authentication/guards/service-auth.guard.js +10 -13
  134. package/dist/modules/{comment/comment-module-options.interface.d.ts → comments/comments-module-options.interface.d.ts} +3 -2
  135. package/dist/modules/comments/comments-module-options.interface.js +2 -0
  136. package/dist/modules/{comment/comment.controller.d.ts → comments/comments.controller.d.ts} +7 -6
  137. package/dist/modules/{comment/comment.controller.js → comments/comments.controller.js} +14 -14
  138. package/dist/modules/comments/comments.module-definition.d.ts +4 -0
  139. package/dist/modules/comments/comments.module-definition.js +7 -0
  140. package/dist/modules/{comment/comment.module.d.ts → comments/comments.module.d.ts} +6 -6
  141. package/dist/modules/{comment/comment.module.js → comments/comments.module.js} +17 -16
  142. package/dist/modules/{comment/comment.service.d.ts → comments/comments.service.d.ts} +35 -9
  143. package/dist/modules/comments/comments.service.js +165 -0
  144. package/dist/modules/comments/index.d.ts +3 -0
  145. package/dist/modules/{services/providers/comments → comments}/index.js +2 -0
  146. package/dist/modules/index.d.ts +1 -1
  147. package/dist/modules/index.js +1 -1
  148. package/dist/modules/like/like-module-options.interface.d.ts +1 -0
  149. package/dist/modules/like/like.controller.d.ts +3 -2
  150. package/dist/modules/like/like.controller.js +4 -4
  151. package/dist/modules/like/like.module.js +1 -1
  152. package/dist/modules/like/like.service.d.ts +0 -16
  153. package/dist/modules/like/like.service.js +9 -28
  154. package/dist/modules/merge/merge-module-options.interface.d.ts +1 -0
  155. package/dist/modules/merge/merge.controller.d.ts +3 -2
  156. package/dist/modules/merge/merge.controller.js +4 -4
  157. package/dist/modules/merge/merge.module.js +1 -1
  158. package/dist/modules/services/providers/accounts.service.js +4 -0
  159. package/dist/modules/services/providers/index.d.ts +0 -1
  160. package/dist/modules/services/providers/index.js +0 -1
  161. package/dist/modules/services/services.module.js +0 -1
  162. package/dist/pipes/index.d.ts +1 -0
  163. package/dist/pipes/index.js +1 -0
  164. package/dist/pipes/restricted-fields.pipe.d.ts +35 -0
  165. package/dist/pipes/restricted-fields.pipe.js +83 -0
  166. package/dist/properties/content-return-type.property.d.ts +4 -0
  167. package/dist/properties/content-return-type.property.js +12 -7
  168. package/dist/properties/content.property.d.ts +7 -2
  169. package/dist/properties/content.property.js +11 -3
  170. package/dist/properties/index.d.ts +2 -4
  171. package/dist/properties/index.js +5 -5
  172. package/dist/transform/index.d.ts +2 -0
  173. package/dist/transform/index.js +2 -0
  174. package/dist/transform/mongo-id.transform.d.ts +4 -0
  175. package/dist/transform/mongo-id.transform.js +13 -0
  176. package/dist/transform/mongo-ids.transform.d.ts +4 -0
  177. package/dist/transform/mongo-ids.transform.js +16 -0
  178. package/dist/types/duplicable-model.type.d.ts +10 -0
  179. package/dist/types/duplicable-model.type.js +2 -0
  180. package/dist/types/index.d.ts +1 -0
  181. package/dist/types/index.js +1 -0
  182. package/dist/types/likeable.type.d.ts +4 -3
  183. package/dist/types/viewable.type.d.ts +4 -3
  184. package/dist/viewable.interface.d.ts +42 -0
  185. package/dist/viewable.interface.js +48 -0
  186. package/package.json +1 -1
  187. package/dist/classes/schema-builder.class.d.ts +0 -75
  188. package/dist/classes/schema-builder.class.js +0 -109
  189. package/dist/modules/comment/comment.module-definition.d.ts +0 -4
  190. package/dist/modules/comment/comment.service.js +0 -99
  191. package/dist/modules/comment/index.d.ts +0 -2
  192. package/dist/modules/services/providers/comments/comments.service-definition.d.ts +0 -1
  193. package/dist/modules/services/providers/comments/comments.service-definition.js +0 -4
  194. package/dist/modules/services/providers/comments/comments.service.d.ts +0 -60
  195. package/dist/modules/services/providers/comments/comments.service.js +0 -139
  196. package/dist/modules/services/providers/comments/index.d.ts +0 -1
  197. package/dist/properties/likeable.properties.d.ts +0 -1
  198. package/dist/properties/likeable.properties.js +0 -66
  199. package/dist/properties/viewable.properties.d.ts +0 -1
  200. package/dist/properties/viewable.properties.js +0 -66
  201. /package/dist/modules/{comment/comment-module-options.interface.js → _old/database/database-module-options.interface.js} +0 -0
@@ -2,29 +2,33 @@ import { ConfigService } from '@nestjs/config';
2
2
  import { LabComment, LabContentRichtext } from 'itlab-functions';
3
3
  import { Connection } from 'mongoose';
4
4
  import { AuthenticationModuleOptions } from '../authentication';
5
+ import { CacheService } from '../cache';
5
6
  import { BaseHttpService } from '../services/base-http.service';
6
- import { CommentModuleOptions } from './comment-module-options.interface';
7
+ import { CommentsModuleOptions } from './comments-module-options.interface';
7
8
  /**
8
- * CommentService manages persistence and business logic
9
+ * CommentsService manages persistence and business logic
9
10
  * for adding, comments on resource entities.
10
11
  *
11
12
  * Why: Encapsulates MongoDB operations and ensures consistent handling
12
13
  * of comment-related behavior across all resources that support comments.
13
14
  */
14
- export declare class CommentService extends BaseHttpService {
15
- private readonly moduleOptions;
16
- private readonly connection;
17
- private readonly commentModel;
15
+ export declare class CommentsService extends BaseHttpService {
16
+ private readonly options;
17
+ private readonly connection?;
18
+ private readonly cacheService?;
18
19
  /**
19
- * Constructs the CommentService with a configured model instance.
20
+ * Constructs the CommentsService with a configured model instance.
20
21
  *
21
22
  * Why: Using the provided Mongoose connection and model options ensures
22
23
  * that comments are tied to the correct resource collection dynamically.
23
24
  *
24
- * @param {CommentModuleOptions} moduleOptions - Config for the commentable resource model.
25
+ * @param {CommentsModuleOptions} options - Config for the commentable resource model.
25
26
  * @param {Connection} connection - Mongoose database connection.
26
27
  */
27
- constructor(moduleOptions: CommentModuleOptions<any>, connection: Connection, authenticationOptions: AuthenticationModuleOptions, configService: ConfigService);
28
+ constructor(authenticationOptions: AuthenticationModuleOptions, options: CommentsModuleOptions<any>, configService: ConfigService, connection?: Connection, cacheService?: CacheService);
29
+ private get commentModel();
30
+ private cacheKey;
31
+ private clearCache;
28
32
  /**
29
33
  * Posts a comment to a given resource, optionally attaching ownership metadata.
30
34
  *
@@ -41,4 +45,26 @@ export declare class CommentService extends BaseHttpService {
41
45
  * @throws {HttpException} If the internal service call fails.
42
46
  */
43
47
  postComment(resourceId: string, accountId: string, richtext: LabContentRichtext): Promise<LabComment>;
48
+ /**
49
+ * Deletes all comments for a given resource.
50
+ * Logs success or failure. Does not throw to avoid disrupting cleanup flows.
51
+ *
52
+ * @param resourceId Unique identifier of the resource whose comments will be deleted.
53
+ */
54
+ deleteComments(resourceId: string): void;
55
+ /**
56
+ * Retrieves comments from the backend.
57
+ * Provides default values if comments retrieval fails.
58
+ *
59
+ * @param resourceId Unique identifier of the resource.
60
+ * @returns Retrieved comments.
61
+ */
62
+ getPopulatedComments(resourceId: string): Promise<LabComment[]>;
63
+ /**
64
+ * Retrieves comments from the cache if available; otherwise fetches from the backend.
65
+ *
66
+ * @param resourceId Unique identifier of the resource.
67
+ * @returns Cached or freshly retrieved comments.
68
+ */
69
+ getCachedPopulatedComments(resourceId: string): Promise<LabComment[]>;
44
70
  }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CommentsService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const config_1 = require("@nestjs/config");
18
+ const mongoose_1 = require("@nestjs/mongoose");
19
+ const mongoose_2 = require("mongoose");
20
+ const authentication_1 = require("../authentication");
21
+ const cache_1 = require("../cache");
22
+ const base_http_service_1 = require("../services/base-http.service");
23
+ const base_urls_1 = require("../services/base-urls");
24
+ const comments_module_definition_1 = require("./comments.module-definition");
25
+ /**
26
+ * CommentsService manages persistence and business logic
27
+ * for adding, comments on resource entities.
28
+ *
29
+ * Why: Encapsulates MongoDB operations and ensures consistent handling
30
+ * of comment-related behavior across all resources that support comments.
31
+ */
32
+ let CommentsService = class CommentsService extends base_http_service_1.BaseHttpService {
33
+ /**
34
+ * Constructs the CommentsService with a configured model instance.
35
+ *
36
+ * Why: Using the provided Mongoose connection and model options ensures
37
+ * that comments are tied to the correct resource collection dynamically.
38
+ *
39
+ * @param {CommentsModuleOptions} options - Config for the commentable resource model.
40
+ * @param {Connection} connection - Mongoose database connection.
41
+ */
42
+ constructor(authenticationOptions, options, configService, connection, cacheService) {
43
+ super('Comment', base_urls_1.BaseUrls.CommentsService, authenticationOptions, configService);
44
+ this.options = options;
45
+ this.connection = connection;
46
+ this.cacheService = cacheService;
47
+ this.cacheKey = (resourceId) => {
48
+ return `${this.options.resource}.${resourceId}.populatedComments`;
49
+ };
50
+ }
51
+ get commentModel() {
52
+ if (!this.connection) {
53
+ this.logger.debug("Couldn't load comment Model... Not connected to the database");
54
+ return undefined;
55
+ }
56
+ return this.connection.model(this.options.model.name, this.options.model.schema);
57
+ }
58
+ clearCache(resourceId) {
59
+ if (this.cacheService) {
60
+ const cacheKey = this.cacheKey(resourceId);
61
+ this.cacheService.remove(cacheKey).then(() => {
62
+ this.logger.log(`Comments cache for ${this.options.resource} ${resourceId} cleared.`);
63
+ });
64
+ }
65
+ }
66
+ /**
67
+ * Posts a comment to a given resource, optionally attaching ownership metadata.
68
+ *
69
+ * Why:
70
+ * - Ensures that the resource exists before attempting to save a comment.
71
+ * - Optionally extracts `ownerId` or `ownerIds` for downstream authorization or notifications.
72
+ * - Wraps the internal HTTP call in a promise with proper error handling and logging.
73
+ *
74
+ * @param {string} resourceId - MongoDB ObjectId of the resource being commented on.
75
+ * @param {string} accountId - Authenticated user ID posting the comment.
76
+ * @param {LabContentRichtext} richtext - Comment content in rich-text format.
77
+ * @returns {Promise<LabComment>} Resolves with the saved comment or throws an HTTP exception.
78
+ * @throws {NotFoundException} If the resource does not exist.
79
+ * @throws {HttpException} If the internal service call fails.
80
+ */
81
+ async postComment(resourceId, accountId, richtext) {
82
+ var _a;
83
+ const resourceType = this.options.model.name.toLowerCase();
84
+ // Verify that the resource exists before posting a comment.
85
+ const resource = await ((_a = this.commentModel) === null || _a === void 0 ? void 0 : _a.findOne({ _id: resourceId }));
86
+ if (!resource) {
87
+ this.logger.error(`Cannot post comment: ${resourceType} ${resourceId} not found`);
88
+ throw new common_1.NotFoundException('Kommentar konnte nicht erstellt werden');
89
+ }
90
+ // Extract ownership metadata if configured for downstream use.
91
+ const ownerId = this.options.ownerIdField ? resource[this.options.ownerIdField] : undefined;
92
+ const ownerIds = this.options.ownerIdsField ? resource[this.options.ownerIdsField] : undefined;
93
+ const endpoint = `internal/${this.options.resource}/${resourceId}/${accountId}`;
94
+ this.logger.log(`Account ${accountId} is posting a comment on ${resourceType} resource ${resourceId}`);
95
+ try {
96
+ const { data } = await this.client.post(endpoint, richtext, {
97
+ params: { ownerId, ownerIds },
98
+ });
99
+ this.logger.log(`Account ${accountId} successfully posted a comment on ${resourceType} resource ${resourceId}`);
100
+ this.clearCache(resourceId);
101
+ return data;
102
+ }
103
+ catch (error) {
104
+ const { status, data, message } = this.parseError(error);
105
+ this.logger.error(`Account ${accountId} failed to post comment on ${resourceType} resource ${resourceId}: ${message}`);
106
+ throw new common_1.HttpException(data, status);
107
+ }
108
+ }
109
+ /**
110
+ * Deletes all comments for a given resource.
111
+ * Logs success or failure. Does not throw to avoid disrupting cleanup flows.
112
+ *
113
+ * @param resourceId Unique identifier of the resource whose comments will be deleted.
114
+ */
115
+ deleteComments(resourceId) {
116
+ const endpoint = `internal/${this.options.resource}/${resourceId}`;
117
+ this.logger.log(`Deleting all comments for ${this.options.resource} ${resourceId}...`);
118
+ this.client
119
+ .delete(endpoint)
120
+ .then(() => {
121
+ this.logger.log(`All comments for ${this.options.resource} ${resourceId} deleted successfully.`);
122
+ this.clearCache(resourceId);
123
+ })
124
+ .catch((error) => {
125
+ const { message } = this.parseError(error);
126
+ this.logger.error(`Failed to delete comments for ${this.options.resource} ${resourceId}: ${message}`);
127
+ });
128
+ }
129
+ /**
130
+ * Retrieves comments from the backend.
131
+ * Provides default values if comments retrieval fails.
132
+ *
133
+ * @param resourceId Unique identifier of the resource.
134
+ * @returns Retrieved comments.
135
+ */
136
+ async getPopulatedComments(resourceId) {
137
+ return this.fetchResourceCollection(`internal/${this.options.resource}/${resourceId}/populated`);
138
+ }
139
+ /**
140
+ * Retrieves comments from the cache if available; otherwise fetches from the backend.
141
+ *
142
+ * @param resourceId Unique identifier of the resource.
143
+ * @returns Cached or freshly retrieved comments.
144
+ */
145
+ async getCachedPopulatedComments(resourceId) {
146
+ const fetchPopulatedComments = () => this.getPopulatedComments(resourceId);
147
+ if (this.cacheService) {
148
+ const cacheKey = this.cacheKey(resourceId);
149
+ return this.cacheService.fetchOrStore(cacheKey, fetchPopulatedComments, 60000); // 1 Minute
150
+ }
151
+ return fetchPopulatedComments();
152
+ }
153
+ };
154
+ exports.CommentsService = CommentsService;
155
+ exports.CommentsService = CommentsService = __decorate([
156
+ (0, common_1.Injectable)(),
157
+ __param(0, (0, authentication_1.InjectAuthenticationOptions)()),
158
+ __param(1, (0, common_1.Inject)(comments_module_definition_1.COMMENTS_MODULE_OPTIONS_TOKEN)),
159
+ __param(3, (0, common_1.Optional)()),
160
+ __param(3, (0, mongoose_1.InjectConnection)()),
161
+ __param(4, (0, common_1.Optional)()),
162
+ __metadata("design:paramtypes", [Object, Object, config_1.ConfigService,
163
+ mongoose_2.Connection,
164
+ cache_1.CacheService])
165
+ ], CommentsService);
@@ -0,0 +1,3 @@
1
+ export * from './comments-module-options.interface';
2
+ export * from './comments.module';
3
+ export * from './comments.service';
@@ -14,4 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./comments-module-options.interface"), exports);
18
+ __exportStar(require("./comments.module"), exports);
17
19
  __exportStar(require("./comments.service"), exports);
@@ -1,6 +1,6 @@
1
1
  export * from './authentication';
2
2
  export * from './cache';
3
- export * from './comment';
3
+ export * from './comments';
4
4
  export * from './database';
5
5
  export * from './like';
6
6
  export * from './merge';
@@ -16,7 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./authentication"), exports);
18
18
  __exportStar(require("./cache"), exports);
19
- __exportStar(require("./comment"), exports);
19
+ __exportStar(require("./comments"), exports);
20
20
  __exportStar(require("./database"), exports);
21
21
  __exportStar(require("./like"), exports);
22
22
  __exportStar(require("./merge"), exports);
@@ -18,4 +18,5 @@ export type LikeModuleOptions = {
18
18
  * For example, setting this to "news" will expose routes like `/like/news/:id`.
19
19
  */
20
20
  routeSuffix: string;
21
+ version: string;
21
22
  };
@@ -1,3 +1,4 @@
1
+ import { LikeModuleOptions } from './like-module-options.interface';
1
2
  import { LikeService } from './like.service';
2
3
  /**
3
4
  * Factory function for creating a LikeController bound to a specific route suffix.
@@ -6,10 +7,10 @@ import { LikeService } from './like.service';
6
7
  * we generate one dynamically. This ensures DRY principles while still
7
8
  * supporting custom routes (e.g. `/like/news` or `/like/event`).
8
9
  *
9
- * @param {string} [routeSuffix] - Suffix appended to the "like" route.
10
+ * @param {LikeModuleOptions} options -
10
11
  * @returns A dynamically generated controller class.
11
12
  */
12
- export declare function createLikeController(routeSuffix: string): {
13
+ export declare function createLikeController(options: LikeModuleOptions): {
13
14
  new (likeService: LikeService): {
14
15
  readonly likeService: LikeService;
15
16
  /**
@@ -26,12 +26,12 @@ const like_service_1 = require("./like.service");
26
26
  * we generate one dynamically. This ensures DRY principles while still
27
27
  * supporting custom routes (e.g. `/like/news` or `/like/event`).
28
28
  *
29
- * @param {string} [routeSuffix] - Suffix appended to the "like" route.
29
+ * @param {LikeModuleOptions} options -
30
30
  * @returns A dynamically generated controller class.
31
31
  */
32
- function createLikeController(routeSuffix) {
32
+ function createLikeController(options) {
33
33
  // Normalize route path, removing duplicate/trailing slashes
34
- const normalizedRoute = `like/${routeSuffix}`.replace(/\/{2,}/g, '/').replace(/\/$/, '');
34
+ const normalizedRoute = `like/${options.routeSuffix}`.replace(/\/{2,}/g, '/').replace(/\/$/, '');
35
35
  let LikeController = class LikeController {
36
36
  constructor(likeService) {
37
37
  this.likeService = likeService;
@@ -133,7 +133,7 @@ function createLikeController(routeSuffix) {
133
133
  LikeController = __decorate([
134
134
  (0, authentication_1.RequireJwtAuth)(),
135
135
  (0, swagger_1.ApiTags)('Like'),
136
- (0, common_1.Controller)(normalizedRoute),
136
+ (0, common_1.Controller)({ path: normalizedRoute, version: options.version }),
137
137
  __metadata("design:paramtypes", [like_service_1.LikeService])
138
138
  ], LikeController);
139
139
  return LikeController;
@@ -30,7 +30,7 @@ let LikeModule = LikeModule_1 = class LikeModule {
30
30
  * @returns {DynamicModule} The dynamically created module definition.
31
31
  */
32
32
  static forFeature(options) {
33
- const LikeController = (0, like_controller_1.createLikeController)(options.routeSuffix);
33
+ const LikeController = (0, like_controller_1.createLikeController)(options);
34
34
  return {
35
35
  module: LikeModule_1,
36
36
  providers: [like_service_1.LikeService, { provide: like_module_definition_1.LIKE_MODULE_OPTIONS_TOKEN, useValue: options }],
@@ -22,19 +22,9 @@ export declare class LikeService {
22
22
  * @param {Connection} connection - Mongoose database connection.
23
23
  */
24
24
  constructor(moduleOptions: LikeModuleOptions, connection: Connection);
25
- /**
26
- * Safely retrieves the number of likes from a resource document.
27
- *
28
- * @param {Document & Likeable} [resource] - The resource document.
29
- * @returns {number} Count of likes, or zero if not available.
30
- */
31
- private countLikes;
32
25
  /**
33
26
  * Adds a like from the specified account to a resource.
34
27
  *
35
- * Why: `$addToSet` prevents duplicates, ensuring data integrity
36
- * when users attempt to like a resource multiple times.
37
- *
38
28
  * @param {string} resourceId - The resource’s ID.
39
29
  * @param {string} accountId - The account ID adding the like.
40
30
  * @returns {Promise<number>} The updated like count.
@@ -43,9 +33,6 @@ export declare class LikeService {
43
33
  /**
44
34
  * Removes a like from the specified account on a resource.
45
35
  *
46
- * Why: `$pull` ensures the account is removed cleanly
47
- * without affecting other users’ likes.
48
- *
49
36
  * @param {string} resourceId - The resource’s ID.
50
37
  * @param {string} accountId - The account ID removing the like.
51
38
  * @returns {Promise<number>} The updated like count.
@@ -54,9 +41,6 @@ export declare class LikeService {
54
41
  /**
55
42
  * Verifies whether a given account has liked a resource.
56
43
  *
57
- * Why: Checking directly with MongoDB avoids fetching the full document,
58
- * making it efficient for large `_likedBy` arrays.
59
- *
60
44
  * @param {string} resourceId - The resource ID.
61
45
  * @param {string} accountId - The account ID to check.
62
46
  * @returns {Promise<boolean>} True if the account has liked the resource.
@@ -42,63 +42,44 @@ let LikeService = LikeService_1 = class LikeService {
42
42
  const { name, schema } = this.moduleOptions.model;
43
43
  this.likeModel = this.connection.model(name, schema);
44
44
  }
45
- /**
46
- * Safely retrieves the number of likes from a resource document.
47
- *
48
- * @param {Document & Likeable} [resource] - The resource document.
49
- * @returns {number} Count of likes, or zero if not available.
50
- */
51
- countLikes(resource) {
52
- var _a, _b;
53
- return (_b = (_a = resource === null || resource === void 0 ? void 0 : resource._likedBy) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
54
- }
55
45
  /**
56
46
  * Adds a like from the specified account to a resource.
57
47
  *
58
- * Why: `$addToSet` prevents duplicates, ensuring data integrity
59
- * when users attempt to like a resource multiple times.
60
- *
61
48
  * @param {string} resourceId - The resource’s ID.
62
49
  * @param {string} accountId - The account ID adding the like.
63
50
  * @returns {Promise<number>} The updated like count.
64
51
  */
65
52
  async addLike(resourceId, accountId) {
53
+ var _a;
66
54
  this.logger.debug(`Account ${accountId} liked ${this.likeModel.name.toLowerCase()} resource ${resourceId}`);
67
- const updatedResource = await this.likeModel.findOneAndUpdate({ _id: resourceId }, { $addToSet: { _likedBy: accountId } }, { new: true, upsert: false, timestamps: false });
68
- return this.countLikes(updatedResource);
55
+ const resource = await this.likeModel.findOne({ _id: resourceId });
56
+ return (_a = resource === null || resource === void 0 ? void 0 : resource.addLike(accountId)) !== null && _a !== void 0 ? _a : 0;
69
57
  }
70
58
  /**
71
59
  * Removes a like from the specified account on a resource.
72
60
  *
73
- * Why: `$pull` ensures the account is removed cleanly
74
- * without affecting other users’ likes.
75
- *
76
61
  * @param {string} resourceId - The resource’s ID.
77
62
  * @param {string} accountId - The account ID removing the like.
78
63
  * @returns {Promise<number>} The updated like count.
79
64
  */
80
65
  async removeLike(resourceId, accountId) {
66
+ var _a;
81
67
  this.logger.debug(`Account ${accountId} unliked ${this.likeModel.name.toLowerCase()} resource ${resourceId}`);
82
- const updatedResource = await this.likeModel.findOneAndUpdate({ _id: resourceId }, { $pull: { _likedBy: accountId } }, { new: true, upsert: false, timestamps: false });
83
- return this.countLikes(updatedResource);
68
+ const resource = await this.likeModel.findOne({ _id: resourceId });
69
+ return (_a = resource === null || resource === void 0 ? void 0 : resource.removeLike(accountId)) !== null && _a !== void 0 ? _a : 0;
84
70
  }
85
71
  /**
86
72
  * Verifies whether a given account has liked a resource.
87
73
  *
88
- * Why: Checking directly with MongoDB avoids fetching the full document,
89
- * making it efficient for large `_likedBy` arrays.
90
- *
91
74
  * @param {string} resourceId - The resource ID.
92
75
  * @param {string} accountId - The account ID to check.
93
76
  * @returns {Promise<boolean>} True if the account has liked the resource.
94
77
  */
95
78
  async hasLiked(resourceId, accountId) {
79
+ var _a;
96
80
  this.logger.log(`Checking like status for account ${accountId} on ${this.likeModel.name.toLowerCase()} resource ${resourceId}`);
97
- const resource = await this.likeModel.findOne({
98
- _id: resourceId,
99
- _likedBy: { $in: [accountId] },
100
- });
101
- return !!resource;
81
+ const resource = await this.likeModel.findOne({ _id: resourceId });
82
+ return (_a = resource === null || resource === void 0 ? void 0 : resource.hasLiked(accountId)) !== null && _a !== void 0 ? _a : false;
102
83
  }
103
84
  };
104
85
  exports.LikeService = LikeService;
@@ -18,4 +18,5 @@ export interface MergeModuleOptions {
18
18
  * Defaults to just `/merge`.
19
19
  */
20
20
  routeSuffix?: string;
21
+ version: string;
21
22
  }
@@ -1,4 +1,5 @@
1
1
  import { InjectionToken } from '@nestjs/common';
2
+ import { MergeModuleOptions } from './merge-module-options.interface';
2
3
  import { MergeModuleService } from './merge.service.interface';
3
4
  /**
4
5
  * Factory function for creating a MergeController bound to a specific route suffix.
@@ -8,10 +9,10 @@ import { MergeModuleService } from './merge.service.interface';
8
9
  * supporting custom routes (e.g. `/merge/news` or `/merge/event`).
9
10
  *
10
11
  * @param {InjectionToken} serviceToken - Token used for service injection.
11
- * @param {string} [routeSuffix] - Optional suffix appended to the "merge" route.
12
+ * @param {MergeModuleOptions} options -
12
13
  * @returns A dynamically generated controller class.
13
14
  */
14
- export declare function createMergeController(serviceToken: InjectionToken, routeSuffix?: string): {
15
+ export declare function createMergeController(serviceToken: InjectionToken, options: MergeModuleOptions): {
15
16
  new (mergeService: MergeModuleService): {
16
17
  readonly mergeService: MergeModuleService;
17
18
  /**
@@ -25,12 +25,12 @@ const authentication_1 = require("../authentication");
25
25
  * supporting custom routes (e.g. `/merge/news` or `/merge/event`).
26
26
  *
27
27
  * @param {InjectionToken} serviceToken - Token used for service injection.
28
- * @param {string} [routeSuffix] - Optional suffix appended to the "merge" route.
28
+ * @param {MergeModuleOptions} options -
29
29
  * @returns A dynamically generated controller class.
30
30
  */
31
- function createMergeController(serviceToken, routeSuffix) {
31
+ function createMergeController(serviceToken, options) {
32
32
  // Normalize route path, removing duplicate/trailing slashes
33
- const normalizedRoute = `merge/${routeSuffix || ''}`.replace(/\/{2,}/g, '/').replace(/\/$/, '');
33
+ const normalizedRoute = `merge/${options.routeSuffix || ''}`.replace(/\/{2,}/g, '/').replace(/\/$/, '');
34
34
  let MergeController = class MergeController {
35
35
  constructor(mergeService) {
36
36
  this.mergeService = mergeService;
@@ -68,7 +68,7 @@ function createMergeController(serviceToken, routeSuffix) {
68
68
  MergeController = __decorate([
69
69
  (0, authentication_1.RequireServiceAuth)(),
70
70
  (0, swagger_1.ApiTags)('Merge'),
71
- (0, common_1.Controller)(normalizedRoute),
71
+ (0, common_1.Controller)({ path: normalizedRoute, version: options.version }),
72
72
  __param(0, (0, common_1.Inject)(serviceToken)),
73
73
  __metadata("design:paramtypes", [Object])
74
74
  ], MergeController);
@@ -26,7 +26,7 @@ let MergeModule = MergeModule_1 = class MergeModule {
26
26
  */
27
27
  static forFeature(options) {
28
28
  const serviceToken = Symbol('MERGE_MODULE_SERVICE_TOKEN');
29
- const MergeController = (0, merge_controller_1.createMergeController)(serviceToken, options.routeSuffix);
29
+ const MergeController = (0, merge_controller_1.createMergeController)(serviceToken, options);
30
30
  return {
31
31
  module: MergeModule_1,
32
32
  imports: options.imports,
@@ -55,6 +55,8 @@ let AccountsService = class AccountsService extends base_http_service_1.BaseHttp
55
55
  * @returns {Promise<Account[]>} Resolves to an array of account objects (empty if none found).
56
56
  */
57
57
  async getAccountCollection(accountIds) {
58
+ if (accountIds.length === 0)
59
+ return [];
58
60
  return this.fetchResourceCollection(`internal/accounts`, { params: { ids: accountIds } });
59
61
  }
60
62
  /**
@@ -73,6 +75,8 @@ let AccountsService = class AccountsService extends base_http_service_1.BaseHttp
73
75
  * @returns {Promise<User[]>} Resolves to a list of users (empty array if none found).
74
76
  */
75
77
  async getUserCollection(userIds) {
78
+ if (userIds.length === 0)
79
+ return [];
76
80
  return this.fetchResourceCollection(`internal/users`, { params: { ids: userIds } });
77
81
  }
78
82
  };
@@ -11,7 +11,6 @@ export * from './team.service';
11
11
  export * from './tech-radar.service';
12
12
  export * from './accounts.service';
13
13
  export * from './changelog.service';
14
- export * from './comments';
15
14
  export * from './mail';
16
15
  export * from './notification';
17
16
  export * from './search';
@@ -27,7 +27,6 @@ __exportStar(require("./team.service"), exports);
27
27
  __exportStar(require("./tech-radar.service"), exports);
28
28
  __exportStar(require("./accounts.service"), exports);
29
29
  __exportStar(require("./changelog.service"), exports);
30
- __exportStar(require("./comments"), exports);
31
30
  __exportStar(require("./mail"), exports);
32
31
  __exportStar(require("./notification"), exports);
33
32
  __exportStar(require("./search"), exports);
@@ -26,7 +26,6 @@ const serviceProviders = [
26
26
  providers_1.LunchRouletteService,
27
27
  // Utils
28
28
  providers_1.AccountsService,
29
- providers_1.CommentsService,
30
29
  providers_1.NotificationService,
31
30
  providers_1.MailService,
32
31
  providers_1.SearchService,
@@ -1,2 +1,3 @@
1
1
  export * from './params';
2
2
  export * from './queries';
3
+ export * from './restricted-fields.pipe';
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./params"), exports);
18
18
  __exportStar(require("./queries"), exports);
19
+ __exportStar(require("./restricted-fields.pipe"), exports);
@@ -0,0 +1,35 @@
1
+ import { ArgumentMetadata, PipeTransform } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { Request } from 'express';
4
+ import { Account } from '../models';
5
+ import { AuthenticationModuleOptions } from '../modules';
6
+ /**
7
+ * @Restricted Decorator
8
+ *
9
+ * Marks a DTO property as restricted to specific permissions.
10
+ * When a request passes through the global `RestrictedFieldsPipe`,
11
+ * these properties will be removed if the requesting account does not
12
+ * have all required permissions.
13
+ *
14
+ * @param {...string[]} perms - One or more permissions required to retain this field.
15
+ */
16
+ export declare function Restricted(perms?: string | string[]): PropertyDecorator;
17
+ /**
18
+ * RestrictedFieldsPipe
19
+ *
20
+ * Global pipe that inspects incoming DTOs for properties decorated with `@Restricted`.
21
+ * If the current request's account lacks the required permissions,
22
+ * the corresponding properties are stripped from the DTO.
23
+ *
24
+ * This ensures that sensitive fields are never accidentally
25
+ * processed further down the request lifecycle.
26
+ */
27
+ export declare class RestrictedFieldsPipe implements PipeTransform {
28
+ private readonly request;
29
+ private readonly authenticationOptions;
30
+ private readonly reflector;
31
+ constructor(request: Request & {
32
+ account?: Account;
33
+ }, authenticationOptions: AuthenticationModuleOptions, reflector: Reflector);
34
+ transform(value: unknown, metadata: ArgumentMetadata): any;
35
+ }