@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
@@ -2,38 +2,31 @@ import { logger } from "../logger/index.mjs";
2
2
  import { formatPaginatedResponse, formatResponse } from "../utils/responseData.mjs";
3
3
  import { ErrorHandler } from "../utils/errors/ErrorHandler.mjs";
4
4
  import { countProjects, createProject, deleteProjectById, findProjects, getProjectById, updateProjectById } from "../services/project.service.mjs";
5
+ import { triggerAll, triggerSingleWebhook } from "../services/webhook.service.mjs";
5
6
  import { hasPermission } from "../utils/permissions.mjs";
6
7
  import { getUsersByIds } from "../services/user.service.mjs";
7
8
  import { SessionModel } from "../models/session.model.mjs";
8
9
  import { getPlanDetails } from "../utils/plan.mjs";
10
+ import { getCIStatus, installCI } from "../services/ci.service.mjs";
9
11
  import { getProjectFiltersAndPagination } from "../utils/filtersAndPagination/getProjectFiltersAndPagination.mjs";
10
12
  import { mapProjectToAPI, mapProjectsToAPI } from "../utils/mapper/project.mjs";
11
- import { t } from "express-intlayer";
13
+ import { t } from "fastify-intlayer";
12
14
 
13
15
  //#region src/controllers/project.controller.ts
14
16
  /**
15
17
  * Retrieves a list of projects based on filters and pagination.
16
18
  */
17
- const getProjects = async (req, res, _next) => {
18
- const { user, organization, roles } = res.locals;
19
- const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getProjectFiltersAndPagination(req, res);
20
- if (!user) {
21
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
22
- return;
23
- }
24
- if (!organization && !roles.includes("admin")) {
25
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
26
- return;
27
- }
19
+ const getProjects = async (request, reply) => {
20
+ const { user, organization, roles } = request.locals || {};
21
+ const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getProjectFiltersAndPagination(request);
22
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
23
+ if (!organization && !roles?.includes("admin")) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
28
24
  try {
29
25
  const projects = await findProjects(filters, skip, pageSize, sortOptions);
30
- if (!hasPermission(roles, "project:read")({
31
- ...res.locals,
26
+ if (!hasPermission(roles || [], "project:read")({
27
+ ...request.locals,
32
28
  targetProjects: projects
33
- })) {
34
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
35
- return;
36
- }
29
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
37
30
  const totalItems = await countProjects(filters);
38
31
  const responseData = formatPaginatedResponse({
39
32
  data: mapProjectsToAPI(projects),
@@ -42,42 +35,28 @@ const getProjects = async (req, res, _next) => {
42
35
  totalPages: getNumberOfPages(totalItems),
43
36
  totalItems
44
37
  });
45
- res.json(responseData);
46
- return;
38
+ return reply.send(responseData);
47
39
  } catch (error) {
48
- ErrorHandler.handleAppErrorResponse(res, error);
49
- return;
40
+ return ErrorHandler.handleAppErrorResponse(reply, error);
50
41
  }
51
42
  };
52
43
  /**
53
44
  * Adds a new project to the database.
54
45
  */
55
- const addProject = async (req, res, _next) => {
56
- const { organization, user, roles } = res.locals;
57
- const projectData = req.body;
58
- if (!user) {
59
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
60
- return;
61
- }
62
- if (!organization) {
63
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
64
- return;
65
- }
66
- if (!projectData) ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
67
- if (!hasPermission(roles, "organization:admin")({
68
- ...res.locals,
46
+ const addProject = async (request, reply) => {
47
+ const { organization, user, roles } = request.locals || {};
48
+ const projectData = request.body;
49
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
50
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
51
+ if (!projectData) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_DATA_NOT_FOUND");
52
+ if (!hasPermission(roles || [], "organization:admin")({
53
+ ...request.locals,
69
54
  targetOrganizations: [organization]
70
- })) {
71
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
72
- return;
73
- }
55
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
74
56
  const { plan } = organization;
75
57
  const planType = getPlanDetails(plan);
76
58
  if (planType.numberOfProjects) {
77
- if (await countProjects({ organizationId: organization.id }) >= planType.numberOfProjects) {
78
- ErrorHandler.handleGenericErrorResponse(res, "PLAN_PROJECT_LIMIT_REACHED", { organizationId: organization.id });
79
- return;
80
- }
59
+ if (await countProjects({ organizationId: organization.id }) >= planType.numberOfProjects) return ErrorHandler.handleGenericErrorResponse(reply, "PLAN_PROJECT_LIMIT_REACHED", { organizationId: organization.id });
81
60
  }
82
61
  const project = {
83
62
  membersIds: [user.id],
@@ -101,42 +80,25 @@ const addProject = async (req, res, _next) => {
101
80
  }),
102
81
  data: formattedProject
103
82
  });
104
- res.json(responseData);
105
- return;
83
+ return reply.send(responseData);
106
84
  } catch (error) {
107
- ErrorHandler.handleAppErrorResponse(res, error);
108
- return;
85
+ return ErrorHandler.handleAppErrorResponse(reply, error);
109
86
  }
110
87
  };
111
88
  /**
112
89
  * Updates an existing project in the database.
113
90
  */
114
- const updateProject = async (req, res, _next) => {
115
- const { organization, project, user, roles } = res.locals;
116
- const projectData = req.body;
117
- if (!user) {
118
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
119
- return;
120
- }
121
- if (!project) {
122
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
123
- return;
124
- }
125
- if (!organization) {
126
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
127
- return;
128
- }
129
- if (String(project.organizationId) !== String(organization.id)) {
130
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_IN_ORGANIZATION");
131
- return;
132
- }
133
- if (!hasPermission(roles, "project:write")({
134
- ...res.locals,
91
+ const updateProject = async (request, reply) => {
92
+ const { organization, project, user, roles } = request.locals || {};
93
+ const projectData = request.body;
94
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
95
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_DATA_NOT_FOUND");
96
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
97
+ if (String(project.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_IN_ORGANIZATION");
98
+ if (!hasPermission(roles || [], "project:write")({
99
+ ...request.locals,
135
100
  targetProjectIds: [String(project.id)]
136
- })) {
137
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
138
- return;
139
- }
101
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
140
102
  try {
141
103
  const formattedProject = mapProjectToAPI(await updateProjectById(project.id, projectData));
142
104
  const responseData = formatResponse({
@@ -152,46 +114,26 @@ const updateProject = async (req, res, _next) => {
152
114
  }),
153
115
  data: formattedProject
154
116
  });
155
- res.json(responseData);
156
- return;
117
+ return reply.send(responseData);
157
118
  } catch (error) {
158
- ErrorHandler.handleAppErrorResponse(res, error);
159
- return;
119
+ return ErrorHandler.handleAppErrorResponse(reply, error);
160
120
  }
161
121
  };
162
122
  /**
163
123
  * Update members to the dictionary in the database.
164
124
  */
165
- const updateProjectMembers = async (req, res, _next) => {
166
- const { user, project, organization, roles } = res.locals;
167
- const { membersIds } = req.body;
168
- if (!user) {
169
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
170
- return;
171
- }
172
- if (!project) {
173
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
174
- return;
175
- }
176
- if (!organization) {
177
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
178
- return;
179
- }
180
- if (membersIds?.length === 0) {
181
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_MUST_HAVE_MEMBER");
182
- return;
183
- }
184
- if (membersIds?.map((el) => el.isAdmin)?.length === 0) {
185
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_MUST_HAVE_ADMIN");
186
- return;
187
- }
188
- if (!hasPermission(roles, "project:write")({
189
- ...res.locals,
125
+ const updateProjectMembers = async (request, reply) => {
126
+ const { user, project, organization, roles } = request.locals || {};
127
+ const { membersIds } = request.body;
128
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
129
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
130
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
131
+ if (membersIds?.length === 0) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_MUST_HAVE_MEMBER");
132
+ if (membersIds?.map((el) => el.isAdmin)?.length === 0) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_MUST_HAVE_ADMIN");
133
+ if (!hasPermission(roles || [], "project:write")({
134
+ ...request.locals,
190
135
  targetProjectIds: [String(project.id)]
191
- })) {
192
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
193
- return;
194
- }
136
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
195
137
  try {
196
138
  const existingUsers = [];
197
139
  if (membersIds) {
@@ -225,45 +167,29 @@ const updateProjectMembers = async (req, res, _next) => {
225
167
  }),
226
168
  data: formattedProject
227
169
  });
228
- res.json(responseData);
229
- return;
170
+ return reply.send(responseData);
230
171
  } catch (error) {
231
- ErrorHandler.handleAppErrorResponse(res, error);
232
- return;
172
+ return ErrorHandler.handleAppErrorResponse(reply, error);
233
173
  }
234
174
  };
235
175
  /**
236
176
  * Pushes a project configuration to the database.
237
- * @param req - Express request object.
238
- * @param res - Express response object.
239
- * @returns Response confirming the deletion.
240
177
  */
241
- const pushProjectConfiguration = async (req, res, _next) => {
242
- const { user, project, roles } = res.locals;
243
- const projectConfiguration = req.body;
244
- if (!user) {
245
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
246
- return;
247
- }
248
- if (!project) {
249
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
250
- return;
251
- }
252
- if (!hasPermission(roles, "project:write")({
253
- ...res.locals,
178
+ const pushProjectConfiguration = async (request, reply) => {
179
+ const { user, project, roles } = request.locals || {};
180
+ const projectConfiguration = request.body;
181
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
182
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
183
+ if (!hasPermission(roles || [], "project:write")({
184
+ ...request.locals,
254
185
  targetProjectIds: [String(project.id)]
255
- })) {
256
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
257
- return;
258
- }
186
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
259
187
  try {
260
188
  const projectObject = await getProjectById(project.id);
189
+ if (projectConfiguration.ai && projectObject.configuration?.ai?.apiKey) projectConfiguration.ai.apiKey = projectObject.configuration.ai.apiKey;
261
190
  projectObject.configuration = projectConfiguration;
262
- projectObject.save();
263
- if (!projectObject.configuration) {
264
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_UPDATE_FAILED", { projectId: project.id });
265
- return;
266
- }
191
+ await projectObject.save();
192
+ if (!projectObject.configuration) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_UPDATE_FAILED", { projectId: project.id });
267
193
  const responseData = formatResponse({
268
194
  message: t({
269
195
  en: "Project configuration updated successfully",
@@ -275,57 +201,95 @@ const pushProjectConfiguration = async (req, res, _next) => {
275
201
  fr: "La configuration du projet a été mise à jour avec succès",
276
202
  es: "Su configuración del proyecto ha sido actualizada con éxito"
277
203
  }),
278
- data: projectObject.configuration
204
+ data: mapProjectToAPI(projectObject)
279
205
  });
280
- res.json(responseData);
281
- return;
206
+ return reply.send(responseData);
282
207
  } catch (error) {
283
- ErrorHandler.handleAppErrorResponse(res, error);
284
- return;
208
+ return ErrorHandler.handleAppErrorResponse(reply, error);
285
209
  }
286
210
  };
287
211
  /**
288
- * Deletes a project from the database by its ID.
289
- * @param req - Express request object.
290
- * @param res - Express response object.
291
- * @returns Response confirming the deletion.
212
+ * Triggers CI builds for a project (Git provider pipelines and webhooks)
292
213
  */
293
- const deleteProject = async (_req, res, _next) => {
294
- const { user, organization, project, session, roles } = res.locals;
295
- if (!user) {
296
- ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
297
- return;
298
- }
299
- if (!organization) {
300
- ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
301
- return;
302
- }
303
- if (!project) {
304
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
305
- return;
306
- }
307
- if (typeof session === "undefined") {
308
- ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
309
- return;
214
+ const triggerBuild = async (request, reply) => {
215
+ const { project, roles } = request.locals || {};
216
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
217
+ if (!hasPermission(roles || [], "project:write")({
218
+ ...request.locals,
219
+ targetProjectIds: [String(project.id)]
220
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
221
+ try {
222
+ const fullProject = await getProjectById(project.id);
223
+ const results = await triggerAll(fullProject);
224
+ const responseData = formatResponse({
225
+ message: t({
226
+ en: "Build triggers initiated",
227
+ fr: "Déclenchement des builds initié",
228
+ es: "Inicio de los triggers de build"
229
+ }),
230
+ description: t({
231
+ en: "CI pipelines and webhooks have been triggered",
232
+ fr: "Les pipelines CI et webhooks ont été déclenchés",
233
+ es: "Los pipelines CI y webhooks han sido activados"
234
+ }),
235
+ data: { results }
236
+ });
237
+ return reply.send(responseData);
238
+ } catch (error) {
239
+ return ErrorHandler.handleAppErrorResponse(reply, error);
310
240
  }
311
- if (!hasPermission(roles, "project:admin")({
312
- ...res.locals,
241
+ };
242
+ /**
243
+ * Triggers a single webhook by index
244
+ */
245
+ const triggerWebhook = async (request, reply) => {
246
+ const { project, roles } = request.locals || {};
247
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
248
+ if (!hasPermission(roles || [], "project:write")({
249
+ ...request.locals,
313
250
  targetProjectIds: [String(project.id)]
314
- })) {
315
- ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
316
- return;
251
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
252
+ try {
253
+ const { webhookIndex } = request.body;
254
+ if (typeof webhookIndex !== "number" || webhookIndex < 0) return ErrorHandler.handleGenericErrorResponse(reply, "INVALID_REQUEST_BODY");
255
+ const fullProject = await getProjectById(project.id);
256
+ const result = await triggerSingleWebhook(fullProject, webhookIndex);
257
+ const responseData = formatResponse({
258
+ message: t({
259
+ en: "Webhook triggered",
260
+ fr: "Webhook déclenché",
261
+ es: "Webhook activado"
262
+ }),
263
+ description: t({
264
+ en: `Webhook "${result.target}" has been triggered`,
265
+ fr: `Le webhook "${result.target}" a été déclenché`,
266
+ es: `El webhook "${result.target}" ha sido activado`
267
+ }),
268
+ data: result
269
+ });
270
+ return reply.send(responseData);
271
+ } catch (error) {
272
+ return ErrorHandler.handleAppErrorResponse(reply, error);
317
273
  }
274
+ };
275
+ /**
276
+ * Deletes a project from the database by its ID.
277
+ */
278
+ const deleteProject = async (_request, reply) => {
279
+ const { user, organization, project, session, roles } = _request.locals || {};
280
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
281
+ if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
282
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
283
+ if (typeof session === "undefined") return ErrorHandler.handleGenericErrorResponse(reply, "SESSION_NOT_DEFINED");
284
+ if (!hasPermission(roles || [], "project:admin")({
285
+ ..._request.locals,
286
+ targetProjectIds: [String(project.id)]
287
+ })) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
318
288
  try {
319
289
  const projectToDelete = await getProjectById(project.id);
320
- if (String(projectToDelete.organizationId) !== String(organization.id)) {
321
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_IN_ORGANIZATION");
322
- return;
323
- }
290
+ if (String(projectToDelete.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_IN_ORGANIZATION");
324
291
  const deletedProject = await deleteProjectById(project.id);
325
- if (!deletedProject) {
326
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED", { projectId: project.id });
327
- return;
328
- }
292
+ if (!deletedProject) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED", { projectId: project.id });
329
293
  logger.info(`Project deleted: ${String(deletedProject.id)}`);
330
294
  const responseData = formatResponse({
331
295
  message: t({
@@ -341,27 +305,19 @@ const deleteProject = async (_req, res, _next) => {
341
305
  data: mapProjectToAPI(deletedProject)
342
306
  });
343
307
  await SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: null } });
344
- res.json(responseData);
345
- return;
308
+ return reply.send(responseData);
346
309
  } catch (error) {
347
- ErrorHandler.handleAppErrorResponse(res, error);
348
- return;
310
+ return ErrorHandler.handleAppErrorResponse(reply, error);
349
311
  }
350
312
  };
351
313
  /**
352
314
  * Select a project.
353
315
  */
354
- const selectProject = async (req, res, _next) => {
355
- const { projectId } = req.params;
356
- const { session } = res.locals;
357
- if (!projectId) {
358
- ErrorHandler.handleGenericErrorResponse(res, "PROJECT_ID_NOT_FOUND");
359
- return;
360
- }
361
- if (typeof session === "undefined") {
362
- ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
363
- return;
364
- }
316
+ const selectProject = async (request, reply) => {
317
+ const { projectId } = request.params;
318
+ const { session } = request.locals || {};
319
+ if (!projectId) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_ID_NOT_FOUND");
320
+ if (typeof session === "undefined") return ErrorHandler.handleGenericErrorResponse(reply, "SESSION_NOT_DEFINED");
365
321
  try {
366
322
  const project = await getProjectById(projectId);
367
323
  await SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: String(projectId) } });
@@ -378,22 +334,17 @@ const selectProject = async (req, res, _next) => {
378
334
  }),
379
335
  data: mapProjectToAPI(project)
380
336
  });
381
- res.json(responseData);
382
- return;
337
+ return reply.send(responseData);
383
338
  } catch (error) {
384
- ErrorHandler.handleAppErrorResponse(res, error);
385
- return;
339
+ return ErrorHandler.handleAppErrorResponse(reply, error);
386
340
  }
387
341
  };
388
342
  /**
389
343
  * Unselect a project.
390
344
  */
391
- const unselectProject = async (_req, res, _next) => {
392
- const { session } = res.locals;
393
- if (typeof session === "undefined") {
394
- ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
395
- return;
396
- }
345
+ const unselectProject = async (_request, reply) => {
346
+ const { session } = _request.locals || {};
347
+ if (typeof session === "undefined") return ErrorHandler.handleGenericErrorResponse(reply, "SESSION_NOT_DEFINED");
397
348
  try {
398
349
  await SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: null } });
399
350
  const responseData = formatResponse({
@@ -409,14 +360,53 @@ const unselectProject = async (_req, res, _next) => {
409
360
  }),
410
361
  data: null
411
362
  });
412
- res.json(responseData);
413
- return;
363
+ return reply.send(responseData);
364
+ } catch (error) {
365
+ return ErrorHandler.handleAppErrorResponse(reply, error);
366
+ }
367
+ };
368
+ /**
369
+ * Get CI configuration status for the current project
370
+ */
371
+ const getCIConfiguration = async (request, reply) => {
372
+ const { project, user } = request.locals || {};
373
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
374
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
375
+ try {
376
+ const responseData = formatResponse({ data: await getCIStatus(project) });
377
+ return reply.send(responseData);
378
+ } catch (error) {
379
+ return ErrorHandler.handleAppErrorResponse(reply, error);
380
+ }
381
+ };
382
+ /**
383
+ * Push CI configuration file to the repository
384
+ */
385
+ const pushCIConfiguration = async (request, reply) => {
386
+ const { project, user } = request.locals || {};
387
+ if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
388
+ if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
389
+ try {
390
+ await installCI(project);
391
+ const responseData = formatResponse({
392
+ message: t({
393
+ en: "CI configuration installed successfully",
394
+ fr: "Configuration CI installée avec succès",
395
+ es: "Configuración CI instalada con éxito"
396
+ }),
397
+ description: t({
398
+ en: "The CI workflow file has been added to your repository",
399
+ fr: "Le fichier de workflow CI a été ajouté à votre dépôt",
400
+ es: "El archivo de flujo de trabajo CI se ha agregado a su repositorio"
401
+ }),
402
+ data: { success: true }
403
+ });
404
+ return reply.send(responseData);
414
405
  } catch (error) {
415
- ErrorHandler.handleAppErrorResponse(res, error);
416
- return;
406
+ return ErrorHandler.handleAppErrorResponse(reply, error);
417
407
  }
418
408
  };
419
409
 
420
410
  //#endregion
421
- export { addProject, deleteProject, getProjects, pushProjectConfiguration, selectProject, unselectProject, updateProject, updateProjectMembers };
411
+ export { addProject, deleteProject, getCIConfiguration, getProjects, pushCIConfiguration, pushProjectConfiguration, selectProject, triggerBuild, triggerWebhook, unselectProject, updateProject, updateProjectMembers };
422
412
  //# sourceMappingURL=project.controller.mjs.map