@intlayer/backend 7.5.9 → 7.5.11

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 (247) hide show
  1. package/README.md +9 -2
  2. package/dist/assets/utils/AI/askDocQuestion/PROMPT.md +1 -1
  3. package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/ci.json +3080 -0
  4. package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/cli/list_projects.json +1 -0
  5. package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/intlayer_with_fastify.json +9 -0
  6. package/dist/esm/controllers/ai.controller.mjs +95 -128
  7. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  8. package/dist/esm/controllers/bitbucket.controller.mjs +77 -0
  9. package/dist/esm/controllers/bitbucket.controller.mjs.map +1 -0
  10. package/dist/esm/controllers/dictionary.controller.mjs +106 -198
  11. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  12. package/dist/esm/controllers/eventListener.controller.mjs +13 -19
  13. package/dist/esm/controllers/eventListener.controller.mjs.map +1 -1
  14. package/dist/esm/controllers/github.controller.mjs +77 -0
  15. package/dist/esm/controllers/github.controller.mjs.map +1 -0
  16. package/dist/esm/controllers/gitlab.controller.mjs +77 -0
  17. package/dist/esm/controllers/gitlab.controller.mjs.map +1 -0
  18. package/dist/esm/controllers/newsletter.controller.mjs +30 -60
  19. package/dist/esm/controllers/newsletter.controller.mjs.map +1 -1
  20. package/dist/esm/controllers/oAuth2.controller.mjs +11 -8
  21. package/dist/esm/controllers/oAuth2.controller.mjs.map +1 -1
  22. package/dist/esm/controllers/organization.controller.mjs +100 -225
  23. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  24. package/dist/esm/controllers/project.controller.mjs +194 -204
  25. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  26. package/dist/esm/controllers/projectAccessKey.controller.mjs +38 -71
  27. package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
  28. package/dist/esm/controllers/search.controller.mjs +3 -3
  29. package/dist/esm/controllers/search.controller.mjs.map +1 -1
  30. package/dist/esm/controllers/stripe.controller.mjs +34 -67
  31. package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
  32. package/dist/esm/controllers/tag.controller.mjs +51 -113
  33. package/dist/esm/controllers/tag.controller.mjs.map +1 -1
  34. package/dist/esm/controllers/user.controller.mjs +64 -113
  35. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  36. package/dist/esm/export.mjs +4 -1
  37. package/dist/esm/index.mjs +105 -41
  38. package/dist/esm/index.mjs.map +1 -1
  39. package/dist/esm/middlewares/oAuth2.middleware.mjs +19 -14
  40. package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
  41. package/dist/esm/middlewares/sessionAuth.middleware.mjs +6 -7
  42. package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
  43. package/dist/esm/routes/ai.routes.mjs +19 -15
  44. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  45. package/dist/esm/routes/bitbucket.routes.mjs +43 -0
  46. package/dist/esm/routes/bitbucket.routes.mjs.map +1 -0
  47. package/dist/esm/routes/dictionary.routes.mjs +10 -10
  48. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  49. package/dist/esm/routes/eventListener.routes.mjs +3 -3
  50. package/dist/esm/routes/eventListener.routes.mjs.map +1 -1
  51. package/dist/esm/routes/github.routes.mjs +43 -0
  52. package/dist/esm/routes/github.routes.mjs.map +1 -0
  53. package/dist/esm/routes/gitlab.routes.mjs +43 -0
  54. package/dist/esm/routes/gitlab.routes.mjs.map +1 -0
  55. package/dist/esm/routes/newsletter.routes.mjs +5 -5
  56. package/dist/esm/routes/newsletter.routes.mjs.map +1 -1
  57. package/dist/esm/routes/organization.routes.mjs +11 -11
  58. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  59. package/dist/esm/routes/project.routes.mjs +38 -14
  60. package/dist/esm/routes/project.routes.mjs.map +1 -1
  61. package/dist/esm/routes/search.routes.mjs +3 -3
  62. package/dist/esm/routes/search.routes.mjs.map +1 -1
  63. package/dist/esm/routes/stripe.routes.mjs +5 -5
  64. package/dist/esm/routes/stripe.routes.mjs.map +1 -1
  65. package/dist/esm/routes/tags.routes.mjs +6 -6
  66. package/dist/esm/routes/tags.routes.mjs.map +1 -1
  67. package/dist/esm/routes/user.routes.mjs +9 -9
  68. package/dist/esm/routes/user.routes.mjs.map +1 -1
  69. package/dist/esm/schemas/project.schema.mjs +70 -1
  70. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  71. package/dist/esm/services/bitbucket.service.mjs +173 -0
  72. package/dist/esm/services/bitbucket.service.mjs.map +1 -0
  73. package/dist/esm/services/ci.service.mjs +134 -0
  74. package/dist/esm/services/ci.service.mjs.map +1 -0
  75. package/dist/esm/services/email.service.mjs +1 -1
  76. package/dist/esm/services/email.service.mjs.map +1 -1
  77. package/dist/esm/services/github.service.mjs +218 -0
  78. package/dist/esm/services/github.service.mjs.map +1 -0
  79. package/dist/esm/services/gitlab.service.mjs +217 -0
  80. package/dist/esm/services/gitlab.service.mjs.map +1 -0
  81. package/dist/esm/services/oAuth2.service.mjs +1 -1
  82. package/dist/esm/services/subscription.service.mjs +1 -1
  83. package/dist/esm/services/subscription.service.mjs.map +1 -1
  84. package/dist/esm/services/webhook.service.mjs +164 -0
  85. package/dist/esm/services/webhook.service.mjs.map +1 -0
  86. package/dist/esm/utils/auth/getAuth.mjs +28 -16
  87. package/dist/esm/utils/auth/getAuth.mjs.map +1 -1
  88. package/dist/esm/utils/cors.mjs +15 -5
  89. package/dist/esm/utils/cors.mjs.map +1 -1
  90. package/dist/esm/utils/errors/ErrorHandler.mjs +32 -4
  91. package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
  92. package/dist/esm/utils/errors/ErrorsClass.mjs +1 -1
  93. package/dist/esm/utils/errors/ErrorsClass.mjs.map +1 -1
  94. package/dist/esm/utils/errors/errorCodes.mjs +234 -0
  95. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  96. package/dist/esm/utils/filtersAndPagination/getDictionaryFiltersAndPagination.mjs +3 -2
  97. package/dist/esm/utils/filtersAndPagination/getDictionaryFiltersAndPagination.mjs.map +1 -1
  98. package/dist/esm/utils/filtersAndPagination/getDiscussionFiltersAndPagination.mjs +1 -1
  99. package/dist/esm/utils/filtersAndPagination/getDiscussionFiltersAndPagination.mjs.map +1 -1
  100. package/dist/esm/utils/filtersAndPagination/getFiltersAndPaginationFromBody.mjs +1 -1
  101. package/dist/esm/utils/filtersAndPagination/getFiltersAndPaginationFromBody.mjs.map +1 -1
  102. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs +3 -2
  103. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
  104. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs +3 -2
  105. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
  106. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs +3 -2
  107. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -1
  108. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs +3 -2
  109. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
  110. package/dist/esm/utils/mapper/project.mjs +28 -1
  111. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  112. package/dist/esm/utils/mongoDB/connectDB.mjs +1 -1
  113. package/dist/esm/utils/rateLimiter.mjs +40 -30
  114. package/dist/esm/utils/rateLimiter.mjs.map +1 -1
  115. package/dist/esm/webhooks/stripe.webhook.mjs +2 -2
  116. package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -1
  117. package/dist/types/controllers/ai.controller.d.ts +29 -12
  118. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  119. package/dist/types/controllers/bitbucket.controller.d.ts +62 -0
  120. package/dist/types/controllers/bitbucket.controller.d.ts.map +1 -0
  121. package/dist/types/controllers/dictionary.controller.d.ts +23 -13
  122. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  123. package/dist/types/controllers/eventListener.controller.d.ts +4 -2
  124. package/dist/types/controllers/eventListener.controller.d.ts.map +1 -1
  125. package/dist/types/controllers/github.controller.d.ts +63 -0
  126. package/dist/types/controllers/github.controller.d.ts.map +1 -0
  127. package/dist/types/controllers/gitlab.controller.d.ts +67 -0
  128. package/dist/types/controllers/gitlab.controller.d.ts.map +1 -0
  129. package/dist/types/controllers/newsletter.controller.d.ts +8 -7
  130. package/dist/types/controllers/newsletter.controller.d.ts.map +1 -1
  131. package/dist/types/controllers/oAuth2.controller.d.ts +4 -2
  132. package/dist/types/controllers/oAuth2.controller.d.ts.map +1 -1
  133. package/dist/types/controllers/organization.controller.d.ts +28 -12
  134. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  135. package/dist/types/controllers/project.controller.d.ts +60 -17
  136. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  137. package/dist/types/controllers/projectAccessKey.controller.d.ts +10 -5
  138. package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
  139. package/dist/types/controllers/search.controller.d.ts +4 -2
  140. package/dist/types/controllers/search.controller.d.ts.map +1 -1
  141. package/dist/types/controllers/stripe.controller.d.ts +11 -12
  142. package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
  143. package/dist/types/controllers/tag.controller.d.ts +14 -9
  144. package/dist/types/controllers/tag.controller.d.ts.map +1 -1
  145. package/dist/types/controllers/user.controller.d.ts +22 -9
  146. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  147. package/dist/types/emails/InviteUserEmail.d.ts +4 -4
  148. package/dist/types/emails/MagicLinkEmail.d.ts +4 -4
  149. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +4 -4
  150. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts.map +1 -1
  151. package/dist/types/emails/PasswordChangeConfirmation.d.ts +4 -4
  152. package/dist/types/emails/ResetUserPassword.d.ts +4 -4
  153. package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
  154. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +4 -4
  155. package/dist/types/emails/SubscriptionPaymentError.d.ts +4 -4
  156. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +4 -4
  157. package/dist/types/emails/ValidateUserEmail.d.ts +4 -4
  158. package/dist/types/emails/Welcome.d.ts +4 -4
  159. package/dist/types/export.d.ts +11 -5
  160. package/dist/types/middlewares/oAuth2.middleware.d.ts +9 -4
  161. package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
  162. package/dist/types/middlewares/sessionAuth.middleware.d.ts +13 -3
  163. package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
  164. package/dist/types/models/discussion.model.d.ts +3 -3
  165. package/dist/types/models/oAuth2.model.d.ts +3 -3
  166. package/dist/types/routes/ai.routes.d.ts +2 -2
  167. package/dist/types/routes/ai.routes.d.ts.map +1 -1
  168. package/dist/types/routes/bitbucket.routes.d.ts +35 -0
  169. package/dist/types/routes/bitbucket.routes.d.ts.map +1 -0
  170. package/dist/types/routes/dictionary.routes.d.ts +2 -2
  171. package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
  172. package/dist/types/routes/eventListener.routes.d.ts +2 -2
  173. package/dist/types/routes/eventListener.routes.d.ts.map +1 -1
  174. package/dist/types/routes/github.routes.d.ts +35 -0
  175. package/dist/types/routes/github.routes.d.ts.map +1 -0
  176. package/dist/types/routes/gitlab.routes.d.ts +35 -0
  177. package/dist/types/routes/gitlab.routes.d.ts.map +1 -0
  178. package/dist/types/routes/newsletter.routes.d.ts +2 -2
  179. package/dist/types/routes/newsletter.routes.d.ts.map +1 -1
  180. package/dist/types/routes/organization.routes.d.ts +2 -2
  181. package/dist/types/routes/organization.routes.d.ts.map +1 -1
  182. package/dist/types/routes/project.routes.d.ts +22 -2
  183. package/dist/types/routes/project.routes.d.ts.map +1 -1
  184. package/dist/types/routes/search.routes.d.ts +2 -2
  185. package/dist/types/routes/search.routes.d.ts.map +1 -1
  186. package/dist/types/routes/stripe.routes.d.ts +2 -2
  187. package/dist/types/routes/stripe.routes.d.ts.map +1 -1
  188. package/dist/types/routes/tags.routes.d.ts +2 -2
  189. package/dist/types/routes/tags.routes.d.ts.map +1 -1
  190. package/dist/types/routes/user.routes.d.ts +2 -2
  191. package/dist/types/routes/user.routes.d.ts.map +1 -1
  192. package/dist/types/schemas/dictionary.schema.d.ts +6 -6
  193. package/dist/types/schemas/discussion.schema.d.ts +6 -6
  194. package/dist/types/schemas/oAuth2.schema.d.ts +5 -5
  195. package/dist/types/schemas/oAuth2.schema.d.ts.map +1 -1
  196. package/dist/types/schemas/plans.schema.d.ts +6 -6
  197. package/dist/types/schemas/project.schema.d.ts +6 -6
  198. package/dist/types/schemas/project.schema.d.ts.map +1 -1
  199. package/dist/types/schemas/session.schema.d.ts +6 -6
  200. package/dist/types/schemas/tag.schema.d.ts +6 -6
  201. package/dist/types/schemas/user.schema.d.ts +6 -6
  202. package/dist/types/schemas/user.schema.d.ts.map +1 -1
  203. package/dist/types/services/bitbucket.service.d.ts +71 -0
  204. package/dist/types/services/bitbucket.service.d.ts.map +1 -0
  205. package/dist/types/services/ci.service.d.ts +27 -0
  206. package/dist/types/services/ci.service.d.ts.map +1 -0
  207. package/dist/types/services/github.service.d.ts +40 -0
  208. package/dist/types/services/github.service.d.ts.map +1 -0
  209. package/dist/types/services/gitlab.service.d.ts +58 -0
  210. package/dist/types/services/gitlab.service.d.ts.map +1 -0
  211. package/dist/types/services/webhook.service.d.ts +19 -0
  212. package/dist/types/services/webhook.service.d.ts.map +1 -0
  213. package/dist/types/types/project.types.d.ts +46 -5
  214. package/dist/types/types/project.types.d.ts.map +1 -1
  215. package/dist/types/types/session.types.d.ts +1 -1
  216. package/dist/types/types/user.types.d.ts +1 -1
  217. package/dist/types/utils/AI/auditTag/index.d.ts +1 -1
  218. package/dist/types/utils/auth/getAuth.d.ts.map +1 -1
  219. package/dist/types/utils/cors.d.ts +2 -2
  220. package/dist/types/utils/errors/ErrorHandler.d.ts +31 -3
  221. package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
  222. package/dist/types/utils/errors/ErrorsClass.d.ts +1 -1
  223. package/dist/types/utils/errors/errorCodes.d.ts +234 -0
  224. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  225. package/dist/types/utils/filtersAndPagination/getDictionaryFiltersAndPagination.d.ts +8 -4
  226. package/dist/types/utils/filtersAndPagination/getDictionaryFiltersAndPagination.d.ts.map +1 -1
  227. package/dist/types/utils/filtersAndPagination/getDiscussionFiltersAndPagination.d.ts +6 -3
  228. package/dist/types/utils/filtersAndPagination/getDiscussionFiltersAndPagination.d.ts.map +1 -1
  229. package/dist/types/utils/filtersAndPagination/getFiltersAndPaginationFromBody.d.ts +6 -2
  230. package/dist/types/utils/filtersAndPagination/getFiltersAndPaginationFromBody.d.ts.map +1 -1
  231. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts +8 -4
  232. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
  233. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts +6 -2
  234. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
  235. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +8 -4
  236. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -1
  237. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts +6 -2
  238. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
  239. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  240. package/dist/types/utils/permissions.d.ts +1 -1
  241. package/dist/types/utils/rateLimiter.d.ts +4 -2
  242. package/dist/types/utils/rateLimiter.d.ts.map +1 -1
  243. package/package.json +24 -28
  244. package/dist/esm/middlewares/request.middleware.mjs +0 -17
  245. package/dist/esm/middlewares/request.middleware.mjs.map +0 -1
  246. package/dist/types/middlewares/request.middleware.d.ts +0 -7
  247. package/dist/types/middlewares/request.middleware.d.ts.map +0 -1
@@ -5,32 +5,23 @@ import { countTags, createTag, deleteTagById, findTags, getTagById, updateTagByI
5
5
  import { hasPermission } from "../utils/permissions.mjs";
6
6
  import { getTagFiltersAndPagination } from "../utils/filtersAndPagination/getTagFiltersAndPagination.mjs";
7
7
  import { mapTagToAPI, mapTagsToAPI } from "../utils/mapper/tag.mjs";
8
- import { t } from "express-intlayer";
8
+ import { t } from "fastify-intlayer";
9
9
 
10
10
  //#region src/controllers/tag.controller.ts
11
11
  /**
12
12
  * Retrieves a list of tags based on filters and pagination.
13
13
  */
14
- const getTags = async (req, res, _next) => {
15
- const { user, organization, roles } = res.locals;
16
- const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getTagFiltersAndPagination(req, res);
17
- if (!user) {
18
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
19
- return;
20
- }
21
- if (!organization) {
22
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
23
- return;
24
- }
14
+ const getTags = async (request, reply) => {
15
+ const { user, organization, roles } = request.locals || {};
16
+ const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getTagFiltersAndPagination(request);
17
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
18
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
25
19
  try {
26
20
  const tags = await findTags(filters, skip, pageSize, sortOptions);
27
- if (!hasPermission(roles, "tag:read")({
28
- ...res.locals,
21
+ if (!hasPermission(roles || [], "tag:read")({
22
+ ...request.locals,
29
23
  targetTags: tags
30
- })) {
31
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
32
- return;
33
- }
24
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
34
25
  const totalItems = await countTags(filters);
35
26
  const responseData = formatPaginatedResponse({
36
27
  data: mapTagsToAPI(tags),
@@ -39,45 +30,31 @@ const getTags = async (req, res, _next) => {
39
30
  totalPages: getNumberOfPages(totalItems),
40
31
  totalItems
41
32
  });
42
- res.json(responseData);
43
- return;
33
+ return reply.send(responseData);
44
34
  } catch (error) {
45
- ErrorHandler.handleAppErrorResponse(res, error);
46
- return;
35
+ return ErrorHandler.handleAppErrorResponse(reply, error);
47
36
  }
48
37
  };
49
38
  /**
50
39
  * Adds a new tag to the database.
51
40
  */
52
- const addTag = async (req, res, _next) => {
53
- const { organization, project, user, roles } = res.locals;
54
- const tagData = req.body;
55
- if (!user) {
56
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
57
- return;
58
- }
59
- if (!organization) {
60
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
61
- return;
62
- }
63
- if (!project) {
64
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
65
- return;
66
- }
67
- if (!tagData) ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
41
+ const addTag = async (request, reply) => {
42
+ const { organization, project, user, roles } = request.locals || {};
43
+ const tagData = request.body;
44
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
45
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
46
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
47
+ if (!tagData) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_DATA_NOT_FOUND");
68
48
  const tag = {
69
49
  creatorId: user.id,
70
50
  organizationId: organization.id,
71
51
  projectId: project.id,
72
52
  ...tagData
73
53
  };
74
- if (!hasPermission(roles, "tag:admin")({
75
- ...res.locals,
54
+ if (!hasPermission(roles || [], "tag:admin")({
55
+ ...request.locals,
76
56
  targetTags: [tag]
77
- })) {
78
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
79
- return;
80
- }
57
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
81
58
  try {
82
59
  const formattedTag = mapTagToAPI(await createTag(tag));
83
60
  const responseData = formatResponse({
@@ -93,47 +70,33 @@ const addTag = async (req, res, _next) => {
93
70
  }),
94
71
  data: formattedTag
95
72
  });
96
- res.json(responseData);
97
- return;
73
+ return reply.send(responseData);
98
74
  } catch (error) {
99
- ErrorHandler.handleAppErrorResponse(res, error);
100
- return;
75
+ return ErrorHandler.handleAppErrorResponse(reply, error);
101
76
  }
102
77
  };
103
78
  /**
104
79
  * Updates an existing tag in the database.
105
80
  */
106
- const updateTag = async (req, res, _next) => {
107
- const { tagId } = req.params;
108
- const { organization, user, roles } = res.locals;
109
- if (!user) {
110
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
111
- return;
112
- }
113
- if (!organization) {
114
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
115
- return;
116
- }
81
+ const updateTag = async (request, reply) => {
82
+ const { tagId } = request.params;
83
+ const { organization, user, roles } = request.locals || {};
84
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
85
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
117
86
  try {
118
87
  const tag = {
119
88
  _id: tagId,
120
- name: req.body.name,
121
- key: req.body.key,
122
- description: req.body.description,
123
- instructions: req.body.instructions
89
+ name: request.body.name,
90
+ key: request.body.key,
91
+ description: request.body.description,
92
+ instructions: request.body.instructions
124
93
  };
125
94
  const tagToDelete = await getTagById(tagId);
126
- if (!hasPermission(roles, "tag:write")({
127
- ...res.locals,
95
+ if (!hasPermission(roles || [], "tag:write")({
96
+ ...request.locals,
128
97
  targetTags: [tagToDelete]
129
- })) {
130
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
131
- return;
132
- }
133
- if (String(tagToDelete.organizationId) !== String(organization.id)) {
134
- ErrorHandler.handleGenericErrorResponse(res, "TAG_NOT_IN_ORGANIZATION");
135
- return;
136
- }
98
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
99
+ if (String(tagToDelete.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_IN_ORGANIZATION");
137
100
  const formattedTag = mapTagToAPI(await updateTagById(tag._id, tag));
138
101
  const responseData = formatResponse({
139
102
  message: t({
@@ -148,52 +111,29 @@ const updateTag = async (req, res, _next) => {
148
111
  }),
149
112
  data: formattedTag
150
113
  });
151
- res.json(responseData);
152
- return;
114
+ return reply.send(responseData);
153
115
  } catch (error) {
154
- ErrorHandler.handleAppErrorResponse(res, error);
155
- return;
116
+ return ErrorHandler.handleAppErrorResponse(reply, error);
156
117
  }
157
118
  };
158
119
  /**
159
120
  * Deletes a tag from the database by its ID.
160
- * @param req - Express request object.
161
- * @param res - Express response object.
162
- * @returns Response confirming the deletion.
163
121
  */
164
- const deleteTag = async (req, res, _next) => {
165
- const { user, organization, roles } = res.locals;
166
- const { tagId } = req.params;
167
- if (!user) {
168
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
169
- return;
170
- }
171
- if (!organization) {
172
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
173
- return;
174
- }
175
- if (!tagId) {
176
- ErrorHandler.handleGenericErrorResponse(res, "TAG_ID_NOT_FOUND");
177
- return;
178
- }
122
+ const deleteTag = async (request, reply) => {
123
+ const { user, organization, roles } = request.locals || {};
124
+ const { tagId } = request.params;
125
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
126
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
127
+ if (!tagId) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_ID_NOT_FOUND");
179
128
  try {
180
129
  const tagToDelete = await getTagById(tagId);
181
- if (!hasPermission(roles, "tag:admin")({
182
- ...res.locals,
130
+ if (!hasPermission(roles || [], "tag:admin")({
131
+ ...request.locals,
183
132
  targetTags: [tagToDelete]
184
- })) {
185
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
186
- return;
187
- }
188
- if (String(tagToDelete.organizationId) !== String(organization.id)) {
189
- ErrorHandler.handleGenericErrorResponse(res, "TAG_NOT_IN_ORGANIZATION");
190
- return;
191
- }
133
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
134
+ if (String(tagToDelete.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_IN_ORGANIZATION");
192
135
  const deletedTag = await deleteTagById(tagId);
193
- if (!deletedTag) {
194
- ErrorHandler.handleGenericErrorResponse(res, "TAG_NOT_FOUND", { tagId });
195
- return;
196
- }
136
+ if (!deletedTag) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_FOUND", { tagId });
197
137
  logger.info(`Tag deleted: ${String(deletedTag.id)}`);
198
138
  const formattedTag = mapTagToAPI(deletedTag);
199
139
  const responseData = formatResponse({
@@ -209,11 +149,9 @@ const deleteTag = async (req, res, _next) => {
209
149
  }),
210
150
  data: formattedTag
211
151
  });
212
- res.json(responseData);
213
- return;
152
+ return reply.send(responseData);
214
153
  } catch (error) {
215
- ErrorHandler.handleAppErrorResponse(res, error);
216
- return;
154
+ return ErrorHandler.handleAppErrorResponse(reply, error);
217
155
  }
218
156
  };
219
157
 
@@ -1 +1 @@
1
- {"version":3,"file":"tag.controller.mjs","names":["tagService.findTags","tagService.countTags","tag: TagData","tagService.createTag","tagService.getTagById","tagService.updateTagById","tagService.deleteTagById"],"sources":["../../../src/controllers/tag.controller.ts"],"sourcesContent":["import { logger } from '@logger';\nimport type { ResponseWithSession } from '@middlewares/sessionAuth.middleware';\nimport * as tagService from '@services/tag.service';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getTagFiltersAndPagination,\n type TagFiltersParams,\n} from '@utils/filtersAndPagination/getTagFiltersAndPagination';\nimport { mapTagsToAPI, mapTagToAPI } from '@utils/mapper/tag';\nimport { hasPermission } from '@utils/permissions';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport { t } from 'express-intlayer';\nimport type {\n Tag,\n TagAPI,\n TagCreationData,\n TagData,\n TagSchema,\n} from '@/types/tag.types';\n\nexport type GetTagsParams = FiltersAndPagination<TagFiltersParams>;\nexport type GetTagsResult = PaginatedResponse<TagAPI>;\n\n/**\n * Retrieves a list of tags based on filters and pagination.\n */\nexport const getTags = async (\n req: Request<GetTagsParams>,\n res: ResponseWithSession<GetTagsResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, roles } = res.locals;\n const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } =\n getTagFiltersAndPagination(req, res);\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n try {\n const tags = await tagService.findTags(\n filters,\n skip,\n pageSize,\n sortOptions\n );\n\n if (\n !hasPermission(\n roles,\n 'tag:read'\n )({\n ...res.locals,\n targetTags: tags,\n })\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n const totalItems = await tagService.countTags(filters);\n\n const formattedTags = mapTagsToAPI(tags);\n\n const responseData = formatPaginatedResponse<TagAPI>({\n data: formattedTags,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AddTagBody = TagCreationData;\nexport type AddTagResult = ResponseData<TagAPI>;\n\n/**\n * Adds a new tag to the database.\n */\nexport const addTag = async (\n req: Request<any, any, AddTagBody>,\n res: ResponseWithSession<AddTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization, project, user, roles } = res.locals;\n const tagData = req.body;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!tagData) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_DATA_NOT_FOUND');\n }\n\n const tag: TagData = {\n creatorId: user.id,\n organizationId: organization.id,\n projectId: project.id,\n ...tagData,\n };\n\n if (\n !hasPermission(\n roles,\n 'tag:admin'\n )({\n ...res.locals,\n targetTags: [tag as Tag],\n })\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n try {\n const newTag = await tagService.createTag(tag);\n\n const formattedTag = mapTagToAPI(newTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag created successfully',\n fr: 'Tag créé avec succès',\n es: 'Tag creado con éxito',\n }),\n description: t({\n en: 'Your tag has been created successfully',\n fr: 'Votre tag a été créé avec succès',\n es: 'Su tag ha sido creado con éxito',\n }),\n data: formattedTag,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type UpdateTagParams = { tagId: string | Tag['id'] };\nexport type UpdateTagBody = Partial<TagData>;\nexport type UpdateTagResult = ResponseData<TagAPI>;\n\n/**\n * Updates an existing tag in the database.\n */\nexport const updateTag = async (\n req: Request<UpdateTagParams, any, UpdateTagBody>,\n res: ResponseWithSession<UpdateTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { tagId } = req.params;\n const { organization, user, roles } = res.locals;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n try {\n const tag = {\n _id: tagId,\n name: req.body.name,\n key: req.body.key,\n description: req.body.description,\n instructions: req.body.instructions,\n } as Partial<TagSchema> & { _id: Tag['id'] };\n\n const tagToDelete = await tagService.getTagById(tagId);\n\n if (\n !hasPermission(\n roles,\n 'tag:write'\n )({\n ...res.locals,\n targetTags: [tagToDelete],\n })\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n if (String(tagToDelete.organizationId) !== String(organization.id)) {\n ErrorHandler.handleGenericErrorResponse(res, 'TAG_NOT_IN_ORGANIZATION');\n return;\n }\n\n const updatedTag = await tagService.updateTagById(tag._id, tag);\n\n const formattedTag = mapTagToAPI(updatedTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag updated successfully',\n fr: 'Tag mis à jour avec succès',\n es: 'Tag actualizado con éxito',\n }),\n description: t({\n en: 'Your tag has been updated successfully',\n fr: 'Votre tag a été mis à jour avec succès',\n es: 'Su tag ha sido actualizado con éxito',\n }),\n data: formattedTag,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type DeleteTagParams = { tagId: string | Tag['id'] };\nexport type DeleteTagResult = ResponseData<TagAPI>;\n\n/**\n * Deletes a tag from the database by its ID.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response confirming the deletion.\n */\nexport const deleteTag = async (\n req: Request<DeleteTagParams>,\n res: ResponseWithSession<DeleteTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, roles } = res.locals;\n const { tagId } = req.params;\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n\n if (!tagId) {\n ErrorHandler.handleGenericErrorResponse(res, 'TAG_ID_NOT_FOUND');\n return;\n }\n\n try {\n const tagToDelete = await tagService.getTagById(tagId);\n\n if (\n !hasPermission(\n roles,\n 'tag:admin'\n )({\n ...res.locals,\n targetTags: [tagToDelete],\n })\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED');\n return;\n }\n\n if (String(tagToDelete.organizationId) !== String(organization.id)) {\n ErrorHandler.handleGenericErrorResponse(res, 'TAG_NOT_IN_ORGANIZATION');\n return;\n }\n\n const deletedTag = await tagService.deleteTagById(tagId);\n\n if (!deletedTag) {\n ErrorHandler.handleGenericErrorResponse(res, 'TAG_NOT_FOUND', {\n tagId,\n });\n\n return;\n }\n\n logger.info(`Tag deleted: ${String(deletedTag.id)}`);\n\n const formattedTag = mapTagToAPI(deletedTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag deleted successfully',\n fr: 'Tag supprimé avec succès',\n es: 'Tag eliminado con éxito',\n }),\n description: t({\n en: 'Your tag has been deleted successfully',\n fr: 'Votre tag a été supprimé avec succès',\n es: 'Su tag ha sido eliminado con éxito',\n }),\n data: formattedTag,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"tag.controller.mjs","names":["tagService.findTags","tagService.countTags","tag: TagData","tagService.createTag","tagService.getTagById","tagService.updateTagById","tagService.deleteTagById"],"sources":["../../../src/controllers/tag.controller.ts"],"sourcesContent":["import { logger } from '@logger';\nimport * as tagService from '@services/tag.service';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport {\n getTagFiltersAndPagination,\n type TagFiltersParams,\n} from '@utils/filtersAndPagination/getTagFiltersAndPagination';\nimport { mapTagsToAPI, mapTagToAPI } from '@utils/mapper/tag';\nimport { hasPermission } from '@utils/permissions';\nimport {\n formatPaginatedResponse,\n formatResponse,\n type PaginatedResponse,\n type ResponseData,\n} from '@utils/responseData';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { t } from 'fastify-intlayer';\nimport type {\n Tag,\n TagAPI,\n TagCreationData,\n TagData,\n TagSchema,\n} from '@/types/tag.types';\n\nexport type GetTagsParams = FiltersAndPagination<TagFiltersParams>;\nexport type GetTagsResult = PaginatedResponse<TagAPI>;\n\n/**\n * Retrieves a list of tags based on filters and pagination.\n */\nexport const getTags = async (\n request: FastifyRequest<{ Querystring: GetTagsParams }>,\n reply: FastifyReply\n): Promise<void> => {\n const { user, organization, roles } = request.locals || {};\n const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } =\n getTagFiltersAndPagination(request);\n\n if (!user) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'USER_NOT_DEFINED');\n }\n\n if (!organization) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'ORGANIZATION_NOT_DEFINED'\n );\n }\n\n try {\n const tags = await tagService.findTags(\n filters,\n skip,\n pageSize,\n sortOptions\n );\n\n if (\n !hasPermission(\n roles || [],\n 'tag:read'\n )({\n ...request.locals,\n targetTags: tags,\n })\n ) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'PERMISSION_DENIED'\n );\n }\n\n const totalItems = await tagService.countTags(filters);\n\n const formattedTags = mapTagsToAPI(tags);\n\n const responseData = formatPaginatedResponse<TagAPI>({\n data: formattedTags,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n return reply.send(responseData);\n } catch (error) {\n return ErrorHandler.handleAppErrorResponse(reply, error as AppError);\n }\n};\n\nexport type AddTagBody = TagCreationData;\nexport type AddTagResult = ResponseData<TagAPI>;\n\n/**\n * Adds a new tag to the database.\n */\nexport const addTag = async (\n request: FastifyRequest<{ Body: AddTagBody }>,\n reply: FastifyReply\n): Promise<void> => {\n const { organization, project, user, roles } = request.locals || {};\n const tagData = request.body;\n\n if (!user) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'USER_NOT_DEFINED');\n }\n\n if (!organization) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'ORGANIZATION_NOT_DEFINED'\n );\n }\n\n if (!project) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'PROJECT_NOT_DEFINED'\n );\n }\n\n if (!tagData) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'PROJECT_DATA_NOT_FOUND'\n );\n }\n\n const tag: TagData = {\n creatorId: user.id,\n organizationId: organization.id,\n projectId: project.id,\n ...tagData,\n };\n\n if (\n !hasPermission(\n roles || [],\n 'tag:admin'\n )({\n ...request.locals,\n targetTags: [tag as Tag],\n })\n ) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'PERMISSION_DENIED');\n }\n\n try {\n const newTag = await tagService.createTag(tag);\n\n const formattedTag = mapTagToAPI(newTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag created successfully',\n fr: 'Tag créé avec succès',\n es: 'Tag creado con éxito',\n }),\n description: t({\n en: 'Your tag has been created successfully',\n fr: 'Votre tag a été créé avec succès',\n es: 'Su tag ha sido creado con éxito',\n }),\n data: formattedTag,\n });\n\n return reply.send(responseData);\n } catch (error) {\n return ErrorHandler.handleAppErrorResponse(reply, error as AppError);\n }\n};\n\nexport type UpdateTagParams = { tagId: string | Tag['id'] };\nexport type UpdateTagBody = Partial<TagData>;\nexport type UpdateTagResult = ResponseData<TagAPI>;\n\n/**\n * Updates an existing tag in the database.\n */\nexport const updateTag = async (\n request: FastifyRequest<{ Params: UpdateTagParams; Body: UpdateTagBody }>,\n reply: FastifyReply\n): Promise<void> => {\n const { tagId } = request.params;\n const { organization, user, roles } = request.locals || {};\n\n if (!user) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'USER_NOT_DEFINED');\n }\n\n if (!organization) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'ORGANIZATION_NOT_DEFINED'\n );\n }\n\n try {\n const tag = {\n _id: tagId,\n name: request.body.name,\n key: request.body.key,\n description: request.body.description,\n instructions: request.body.instructions,\n } as Partial<TagSchema> & { _id: Tag['id'] };\n\n const tagToDelete = await tagService.getTagById(tagId);\n\n if (\n !hasPermission(\n roles || [],\n 'tag:write'\n )({\n ...request.locals,\n targetTags: [tagToDelete],\n })\n ) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'PERMISSION_DENIED'\n );\n }\n\n if (String(tagToDelete.organizationId) !== String(organization.id)) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'TAG_NOT_IN_ORGANIZATION'\n );\n }\n\n const updatedTag = await tagService.updateTagById(tag._id, tag);\n\n const formattedTag = mapTagToAPI(updatedTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag updated successfully',\n fr: 'Tag mis à jour avec succès',\n es: 'Tag actualizado con éxito',\n }),\n description: t({\n en: 'Your tag has been updated successfully',\n fr: 'Votre tag a été mis à jour avec succès',\n es: 'Su tag ha sido actualizado con éxito',\n }),\n data: formattedTag,\n });\n\n return reply.send(responseData);\n } catch (error) {\n return ErrorHandler.handleAppErrorResponse(reply, error as AppError);\n }\n};\n\nexport type DeleteTagParams = { tagId: string | Tag['id'] };\nexport type DeleteTagResult = ResponseData<TagAPI>;\n\n/**\n * Deletes a tag from the database by its ID.\n */\nexport const deleteTag = async (\n request: FastifyRequest<{ Params: DeleteTagParams }>,\n reply: FastifyReply\n): Promise<void> => {\n const { user, organization, roles } = request.locals || {};\n const { tagId } = request.params;\n\n if (!user) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'USER_NOT_DEFINED');\n }\n\n if (!organization) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'ORGANIZATION_NOT_DEFINED'\n );\n }\n\n if (!tagId) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'TAG_ID_NOT_FOUND');\n }\n\n try {\n const tagToDelete = await tagService.getTagById(tagId);\n\n if (\n !hasPermission(\n roles || [],\n 'tag:admin'\n )({\n ...request.locals,\n targetTags: [tagToDelete],\n })\n ) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'PERMISSION_DENIED'\n );\n }\n\n if (String(tagToDelete.organizationId) !== String(organization.id)) {\n return ErrorHandler.handleGenericErrorResponse(\n reply,\n 'TAG_NOT_IN_ORGANIZATION'\n );\n }\n\n const deletedTag = await tagService.deleteTagById(tagId);\n\n if (!deletedTag) {\n return ErrorHandler.handleGenericErrorResponse(reply, 'TAG_NOT_FOUND', {\n tagId,\n });\n }\n\n logger.info(`Tag deleted: ${String(deletedTag.id)}`);\n\n const formattedTag = mapTagToAPI(deletedTag);\n\n const responseData = formatResponse<TagAPI>({\n message: t({\n en: 'Tag deleted successfully',\n fr: 'Tag supprimé avec succès',\n es: 'Tag eliminado con éxito',\n }),\n description: t({\n en: 'Your tag has been deleted successfully',\n fr: 'Votre tag a été supprimé avec succès',\n es: 'Su tag ha sido eliminado con éxito',\n }),\n data: formattedTag,\n });\n\n return reply.send(responseData);\n } catch (error) {\n return ErrorHandler.handleAppErrorResponse(reply, error as AppError);\n }\n};\n"],"mappings":"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"}
@@ -6,25 +6,22 @@ import { countUsers, createUser as createUser$1, deleteUser as deleteUser$1, fin
6
6
  import { mapUserToAPI, mapUsersToAPI } from "../utils/mapper/user.mjs";
7
7
  import { sendEmail } from "../services/email.service.mjs";
8
8
  import { getUserFiltersAndPagination } from "../utils/filtersAndPagination/getUserFiltersAndPagination.mjs";
9
- import { t } from "express-intlayer";
9
+ import { t } from "fastify-intlayer";
10
10
 
11
11
  //#region src/controllers/user.controller.ts
12
12
  /**
13
13
  * Creates a new user.
14
14
  */
15
- const createUser = async (req, res, _next) => {
16
- const user = req.body;
17
- if (!user) {
18
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
19
- return;
20
- }
15
+ const createUser = async (request, reply) => {
16
+ const user = request.body;
17
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
21
18
  try {
22
19
  const newUser = await createUser$1(user);
23
20
  await sendEmail({
24
21
  type: "welcome",
25
22
  to: newUser.email,
26
23
  username: newUser.name,
27
- loginLink: `${process.env.CLIENT_URL}/auth/login`
24
+ loginLink: `${process.env.APP_URL}/auth/login`
28
25
  });
29
26
  const formattedUser = mapUserToAPI(newUser);
30
27
  const responseData = formatResponse({
@@ -40,32 +37,24 @@ const createUser = async (req, res, _next) => {
40
37
  }),
41
38
  data: formattedUser
42
39
  });
43
- res.json(responseData);
44
- return;
40
+ return reply.send(responseData);
45
41
  } catch (error) {
46
- ErrorHandler.handleAppErrorResponse(res, error);
47
- return;
42
+ return ErrorHandler.handleAppErrorResponse(reply, error);
48
43
  }
49
44
  };
50
45
  /**
51
46
  * Retrieves a list of users based on filters and pagination.
52
47
  */
53
- const getUsers = async (req, res, _next) => {
54
- const { user, roles } = res.locals;
55
- if (!user) {
56
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
57
- return;
58
- }
59
- const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getUserFiltersAndPagination(req, res);
48
+ const getUsers = async (request, reply) => {
49
+ const { user, roles } = request.locals || {};
50
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
51
+ const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getUserFiltersAndPagination(request);
60
52
  try {
61
53
  const users = await findUsers(filters, skip, pageSize, sortOptions);
62
- if (!hasPermission(roles, "user:read")({
63
- ...res.locals,
54
+ if (!hasPermission(roles || [], "user:read")({
55
+ ...request.locals,
64
56
  targetUsers: users
65
- })) {
66
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
67
- return;
68
- }
57
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
69
58
  const totalItems = await countUsers(filters);
70
59
  const responseData = formatPaginatedResponse({
71
60
  data: mapUsersToAPI(users),
@@ -74,82 +63,53 @@ const getUsers = async (req, res, _next) => {
74
63
  totalPages: getNumberOfPages(totalItems),
75
64
  totalItems
76
65
  });
77
- res.json(responseData);
78
- return;
66
+ return reply.send(responseData);
79
67
  } catch (error) {
80
- ErrorHandler.handleAppErrorResponse(res, error);
81
- return;
68
+ return ErrorHandler.handleAppErrorResponse(reply, error);
82
69
  }
83
70
  };
84
- const getUserById = async (req, res, _next) => {
85
- const { userId } = req.params;
71
+ const getUserById = async (request, reply) => {
72
+ const { userId } = request.params;
86
73
  try {
87
74
  const user = await getUserById$1(userId);
88
- if (!user) {
89
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
90
- return;
91
- }
75
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
92
76
  const responseData = formatResponse({ data: mapUserToAPI(user) });
93
- res.json(responseData);
94
- return;
77
+ return reply.send(responseData);
95
78
  } catch (error) {
96
- ErrorHandler.handleAppErrorResponse(res, error);
97
- return;
79
+ return ErrorHandler.handleAppErrorResponse(reply, error);
98
80
  }
99
81
  };
100
- const getUserByEmail = async (req, res, _next) => {
101
- const { email } = req.params;
102
- const { roles } = res.locals;
82
+ const getUserByEmail = async (request, reply) => {
83
+ const { email } = request.params;
84
+ const { roles } = request.locals || {};
103
85
  try {
104
86
  const user = await getUserByEmail$1(email);
105
- if (!user) {
106
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
107
- return;
108
- }
109
- if (!hasPermission(roles, "user:read")({
110
- ...res.locals,
87
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
88
+ if (!hasPermission(roles || [], "user:read")({
89
+ ...request.locals,
111
90
  targetUsers: [user]
112
- })) {
113
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
114
- return;
115
- }
91
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
116
92
  const responseData = formatResponse({ data: mapUserToAPI(user) });
117
- res.json(responseData);
93
+ return reply.send(responseData);
118
94
  } catch (error) {
119
- ErrorHandler.handleAppErrorResponse(res, error);
120
- return;
95
+ return ErrorHandler.handleAppErrorResponse(reply, error);
121
96
  }
122
97
  };
123
98
  /**
124
99
  * Updates user information (phone number, date of birth).
125
100
  */
126
- const updateUser = async (req, res, _next) => {
127
- const userData = req.body;
128
- const { user, roles } = res.locals;
129
- if (!user) {
130
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
131
- return;
132
- }
133
- if (typeof userData !== "object") {
134
- ErrorHandler.handleGenericErrorResponse(res, "USER_DATA_NOT_FOUND");
135
- return;
136
- }
137
- if (!userData.id) {
138
- ErrorHandler.handleGenericErrorResponse(res, "USER_INVALID_FIELDS");
139
- return;
140
- }
101
+ const updateUser = async (request, reply) => {
102
+ const userData = request.body;
103
+ const { user, roles } = request.locals || {};
104
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
105
+ if (typeof userData !== "object") return ErrorHandler.handleGenericErrorResponse(reply, "USER_DATA_NOT_FOUND");
106
+ if (!userData.id) return ErrorHandler.handleGenericErrorResponse(reply, "USER_INVALID_FIELDS");
141
107
  const userDB = await getUserById$1(userData.id);
142
- if (!userDB) {
143
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
144
- return;
145
- }
146
- if (!hasPermission(roles, "user:write")({
147
- ...res.locals,
108
+ if (!userDB) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_FOUND");
109
+ if (!hasPermission(roles || [], "user:write")({
110
+ ...request.locals,
148
111
  targetUsers: [userDB]
149
- })) {
150
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
151
- return;
152
- }
112
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
153
113
  try {
154
114
  const updatedUser = await updateUserById(userDB.id, userData);
155
115
  logger.info(`User updated: Name: ${updatedUser.name}, id: ${String(updatedUser.id)}`);
@@ -167,32 +127,24 @@ const updateUser = async (req, res, _next) => {
167
127
  }),
168
128
  data: formattedUser
169
129
  });
170
- res.json(responseData);
171
- return;
130
+ return reply.send(responseData);
172
131
  } catch (error) {
173
- ErrorHandler.handleAppErrorResponse(res, error);
174
- return;
132
+ return ErrorHandler.handleAppErrorResponse(reply, error);
175
133
  }
176
134
  };
177
135
  /**
178
136
  * Deletes a user based on the provided ID.
179
137
  */
180
- const deleteUser = async (req, res, _next) => {
181
- const { userId } = req.params;
182
- const { roles } = res.locals;
138
+ const deleteUser = async (request, reply) => {
139
+ const { userId } = request.params;
140
+ const { roles } = request.locals || {};
183
141
  try {
184
142
  const user = await getUserById$1(userId);
185
- if (!user) {
186
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
187
- return;
188
- }
189
- if (!hasPermission(roles, "user:admin")({
190
- ...res.locals,
143
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_FOUND");
144
+ if (!hasPermission(roles || [], "user:admin")({
145
+ ...request.locals,
191
146
  targetUsers: [user]
192
- })) {
193
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
194
- return;
195
- }
147
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
196
148
  await deleteUser$1(userId);
197
149
  const formattedUser = mapUserToAPI(user);
198
150
  const responseData = formatResponse({
@@ -208,16 +160,15 @@ const deleteUser = async (req, res, _next) => {
208
160
  }),
209
161
  data: formattedUser
210
162
  });
211
- res.json(responseData);
163
+ return reply.send(responseData);
212
164
  } catch (error) {
213
- ErrorHandler.handleAppErrorResponse(res, error);
214
- return;
165
+ return ErrorHandler.handleAppErrorResponse(reply, error);
215
166
  }
216
167
  };
217
168
  let clients = [];
218
169
  const sendVerificationUpdate = (user) => {
219
170
  const filteredClients = clients.filter((client) => String(client.userId) === String(user.id));
220
- for (const client of filteredClients) if (user.emailVerified) client.res.write(`data: ${JSON.stringify({
171
+ for (const client of filteredClients) if (user.emailVerified) client.res.raw.write(`data: ${JSON.stringify({
221
172
  userId: user.id,
222
173
  status: "verified"
223
174
  })}\n\n`);
@@ -225,33 +176,33 @@ const sendVerificationUpdate = (user) => {
225
176
  /**
226
177
  * SSE to check the email verification status
227
178
  */
228
- const verifyEmailStatusSSE = async (req, res) => {
229
- res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
230
- res.setHeader("Cache-Control", "no-cache, no-transform");
231
- res.setHeader("Connection", "keep-alive");
232
- res.setHeader("X-Accel-Buffering", "no");
233
- res.write(":\n\n");
234
- res.flushHeaders();
235
- const { userId } = req.params;
179
+ const verifyEmailStatusSSE = async (request, reply) => {
180
+ reply.raw.setHeader("Content-Type", "text/event-stream;charset=utf-8");
181
+ reply.raw.setHeader("Cache-Control", "no-cache, no-transform");
182
+ reply.raw.setHeader("Connection", "keep-alive");
183
+ reply.raw.setHeader("X-Accel-Buffering", "no");
184
+ reply.raw.write(":\n\n");
185
+ reply.raw.flushHeaders?.();
186
+ const { userId } = request.params;
236
187
  const clientId = Date.now();
237
188
  const user = await getUserById$1(userId);
238
189
  if (!user) {
239
190
  logger.error(`User not found - User ID: ${userId}`);
240
- res.write(`data: ${JSON.stringify({
191
+ reply.raw.write(`data: ${JSON.stringify({
241
192
  userId,
242
193
  status: "error"
243
194
  })}\n\n`);
244
- res.end();
195
+ reply.raw.end();
245
196
  return;
246
197
  }
247
198
  const newClient = {
248
199
  id: clientId,
249
200
  userId,
250
- res
201
+ res: { raw: reply.raw }
251
202
  };
252
203
  clients.push(newClient);
253
204
  sendVerificationUpdate(user);
254
- req.on("close", () => {
205
+ request.raw.on("close", () => {
255
206
  clients = clients.filter((client) => client.id !== clientId);
256
207
  });
257
208
  };