@intlayer/backend 8.12.2 → 8.12.4-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) hide show
  1. package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/bundle_optimization.json +9954 -6953
  2. package/dist/assets/utils/AI/askDocQuestion/embeddings/docs/en/configuration.json +1 -1
  3. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  4. package/dist/esm/controllers/audit.controller.mjs.map +1 -1
  5. package/dist/esm/controllers/bitbucket.controller.mjs.map +1 -1
  6. package/dist/esm/controllers/cliSessionToken.controller.mjs.map +1 -1
  7. package/dist/esm/controllers/demo.controller.mjs +32 -25
  8. package/dist/esm/controllers/demo.controller.mjs.map +1 -1
  9. package/dist/esm/controllers/dictionary.controller.mjs +1 -0
  10. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  11. package/dist/esm/controllers/environment.controller.mjs.map +1 -1
  12. package/dist/esm/controllers/eventListener.controller.mjs.map +1 -1
  13. package/dist/esm/controllers/github.controller.mjs.map +1 -1
  14. package/dist/esm/controllers/gitlab.controller.mjs.map +1 -1
  15. package/dist/esm/controllers/newsletter.controller.mjs.map +1 -1
  16. package/dist/esm/controllers/oAuth2.controller.mjs.map +1 -1
  17. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  18. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  19. package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
  20. package/dist/esm/controllers/projectMemberAccess.controller.mjs.map +1 -1
  21. package/dist/esm/controllers/recursiveAudit.controller.mjs.map +1 -1
  22. package/dist/esm/controllers/reviewer.controller.mjs.map +1 -1
  23. package/dist/esm/controllers/searchDoc.controller.mjs.map +1 -1
  24. package/dist/esm/controllers/showcaseProject.controller.mjs.map +1 -1
  25. package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
  26. package/dist/esm/controllers/tag.controller.mjs.map +1 -1
  27. package/dist/esm/controllers/translation.controller.mjs.map +1 -1
  28. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  29. package/dist/esm/emails/AffiliateActivatedEmail.mjs.map +1 -1
  30. package/dist/esm/emails/AffiliateConversionEmail.mjs.map +1 -1
  31. package/dist/esm/emails/AffiliateInvitationEmail.mjs.map +1 -1
  32. package/dist/esm/emails/AffiliateWelcomeEmail.mjs.map +1 -1
  33. package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
  34. package/dist/esm/emails/MagicLinkEmail.mjs.map +1 -1
  35. package/dist/esm/emails/MissionRequestedClientEmail.mjs.map +1 -1
  36. package/dist/esm/emails/MissionRequestedReviewerEmail.mjs.map +1 -1
  37. package/dist/esm/emails/OAuthTokenCreatedEmail.mjs.map +1 -1
  38. package/dist/esm/emails/PasswordChangeConfirmation.mjs.map +1 -1
  39. package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
  40. package/dist/esm/emails/ReviewerApplicationEmail.mjs.map +1 -1
  41. package/dist/esm/emails/ReviewerApprovedEmail.mjs.map +1 -1
  42. package/dist/esm/emails/ReviewerContactEmail.mjs.map +1 -1
  43. package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -1
  44. package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -1
  45. package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -1
  46. package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
  47. package/dist/esm/emails/Welcome.mjs.map +1 -1
  48. package/dist/esm/index.mjs +1 -1
  49. package/dist/esm/index.mjs.map +1 -1
  50. package/dist/esm/logger/index.mjs.map +1 -1
  51. package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
  52. package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
  53. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  54. package/dist/esm/routes/audit.routes.mjs.map +1 -1
  55. package/dist/esm/routes/bitbucket.routes.mjs.map +1 -1
  56. package/dist/esm/routes/demo.routes.mjs.map +1 -1
  57. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  58. package/dist/esm/routes/environment.routes.mjs.map +1 -1
  59. package/dist/esm/routes/eventListener.routes.mjs.map +1 -1
  60. package/dist/esm/routes/github.routes.mjs.map +1 -1
  61. package/dist/esm/routes/gitlab.routes.mjs.map +1 -1
  62. package/dist/esm/routes/newsletter.routes.mjs.map +1 -1
  63. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  64. package/dist/esm/routes/paramsSchemas.mjs.map +1 -1
  65. package/dist/esm/routes/project.routes.mjs.map +1 -1
  66. package/dist/esm/routes/reviewer.routes.mjs.map +1 -1
  67. package/dist/esm/routes/search.routes.mjs.map +1 -1
  68. package/dist/esm/routes/showcaseProject.routes.mjs.map +1 -1
  69. package/dist/esm/routes/stripe.routes.mjs.map +1 -1
  70. package/dist/esm/routes/tags.routes.mjs.map +1 -1
  71. package/dist/esm/routes/translate.routes.mjs.map +1 -1
  72. package/dist/esm/routes/user.routes.mjs.map +1 -1
  73. package/dist/esm/schemas/account.schema.mjs.map +1 -1
  74. package/dist/esm/schemas/affiliate.schema.mjs.map +1 -1
  75. package/dist/esm/schemas/affiliateInvitation.schema.mjs.map +1 -1
  76. package/dist/esm/schemas/audit.schema.mjs.map +1 -1
  77. package/dist/esm/schemas/auditJob.schema.mjs.map +1 -1
  78. package/dist/esm/schemas/auditPage.schema.mjs.map +1 -1
  79. package/dist/esm/schemas/cliSessionToken.schema.mjs.map +1 -1
  80. package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
  81. package/dist/esm/schemas/discussion.schema.mjs.map +1 -1
  82. package/dist/esm/schemas/oAuth2.schema.mjs.map +1 -1
  83. package/dist/esm/schemas/organization.schema.mjs.map +1 -1
  84. package/dist/esm/schemas/plans.schema.mjs.map +1 -1
  85. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  86. package/dist/esm/schemas/promoCode.schema.mjs.map +1 -1
  87. package/dist/esm/schemas/reviewer.schema.mjs.map +1 -1
  88. package/dist/esm/schemas/session.schema.mjs.map +1 -1
  89. package/dist/esm/schemas/showcaseProject.schema.mjs.map +1 -1
  90. package/dist/esm/schemas/tag.schema.mjs.map +1 -1
  91. package/dist/esm/schemas/user.schema.mjs.map +1 -1
  92. package/dist/esm/services/affiliate.service.mjs.map +1 -1
  93. package/dist/esm/services/audit/analysis/analyzeBundleContent.mjs.map +1 -1
  94. package/dist/esm/services/audit/analysis/analyzeLinguisticStructure.mjs.map +1 -1
  95. package/dist/esm/services/audit/analysis/analyzeMetadata.mjs.map +1 -1
  96. package/dist/esm/services/audit/analysis/analyzeRobots.mjs.map +1 -1
  97. package/dist/esm/services/audit/analysis/analyzeSitemap.mjs.map +1 -1
  98. package/dist/esm/services/audit/analysis/analyzeUrlStructure.mjs.map +1 -1
  99. package/dist/esm/services/audit/analysis/calculateScore.mjs.map +1 -1
  100. package/dist/esm/services/audit/checkers/bundleChecker.mjs.map +1 -1
  101. package/dist/esm/services/audit/checkers/linguisticChecker.mjs.map +1 -1
  102. package/dist/esm/services/audit/checkers/metadataChecker.mjs.map +1 -1
  103. package/dist/esm/services/audit/checkers/pageChecker.mjs.map +1 -1
  104. package/dist/esm/services/audit/checkers/robotsChecker.mjs.map +1 -1
  105. package/dist/esm/services/audit/checkers/sitemapChecker.mjs.map +1 -1
  106. package/dist/esm/services/audit/checkers/urlChecker.mjs.map +1 -1
  107. package/dist/esm/services/audit/recursiveAudit.service.mjs.map +1 -1
  108. package/dist/esm/services/audit/seoAudit.service.mjs.map +1 -1
  109. package/dist/esm/services/bitbucket.service.mjs.map +1 -1
  110. package/dist/esm/services/ci.service.mjs.map +1 -1
  111. package/dist/esm/services/cliSessionToken.service.mjs.map +1 -1
  112. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  113. package/dist/esm/services/email.service.mjs.map +1 -1
  114. package/dist/esm/services/environment.service.mjs.map +1 -1
  115. package/dist/esm/services/github.service.mjs.map +1 -1
  116. package/dist/esm/services/gitlab.service.mjs.map +1 -1
  117. package/dist/esm/services/oAuth2.service.mjs.map +1 -1
  118. package/dist/esm/services/organization.service.mjs.map +1 -1
  119. package/dist/esm/services/project/projectScreenshot.service.mjs.map +1 -1
  120. package/dist/esm/services/project.service.mjs.map +1 -1
  121. package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
  122. package/dist/esm/services/promoCode.service.mjs.map +1 -1
  123. package/dist/esm/services/reviewer/pictureUpload.service.mjs.map +1 -1
  124. package/dist/esm/services/reviewer.service.mjs.map +1 -1
  125. package/dist/esm/services/reviewerMessage.service.mjs.map +1 -1
  126. package/dist/esm/services/reviewerMission.service.mjs.map +1 -1
  127. package/dist/esm/services/session.service.mjs.map +1 -1
  128. package/dist/esm/services/showcase/showcaseProject.service.mjs.map +1 -1
  129. package/dist/esm/services/showcase/showcaseScan.service.mjs.map +1 -1
  130. package/dist/esm/services/showcase/showcaseUploadScreenshot.service.mjs.map +1 -1
  131. package/dist/esm/services/showcase/showcaseVerifyBundle.service.mjs.map +1 -1
  132. package/dist/esm/services/showcase/showcaseVerifyGithub.service.mjs.map +1 -1
  133. package/dist/esm/services/subscription.service.mjs.map +1 -1
  134. package/dist/esm/services/tag.service.mjs.map +1 -1
  135. package/dist/esm/services/translationQueue.service.mjs.map +1 -1
  136. package/dist/esm/services/translationWorker.service.mjs.map +1 -1
  137. package/dist/esm/services/user/avatarUpload.service.mjs.map +1 -1
  138. package/dist/esm/services/user.service.mjs.map +1 -1
  139. package/dist/esm/services/webhook.service.mjs.map +1 -1
  140. package/dist/esm/types/user.types.mjs.map +1 -1
  141. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -1
  142. package/dist/esm/utils/AI/askDocQuestion/embeddings/docs/en/bundle_optimization.json +9954 -6953
  143. package/dist/esm/utils/AI/askDocQuestion/embeddings/docs/en/configuration.json +1 -1
  144. package/dist/esm/utils/AI/askDocQuestion/indexMarkdownFiles.mjs.map +1 -1
  145. package/dist/esm/utils/AI/auditDictionary/index.mjs.map +1 -1
  146. package/dist/esm/utils/AI/auditDictionaryField/index.mjs.map +1 -1
  147. package/dist/esm/utils/AI/auditDictionaryMetadata/index.mjs.map +1 -1
  148. package/dist/esm/utils/AI/auditTag/index.mjs.map +1 -1
  149. package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -1
  150. package/dist/esm/utils/AI/chat/index.mjs.map +1 -1
  151. package/dist/esm/utils/AI/chat/mcpInProcessTools.mjs.map +1 -1
  152. package/dist/esm/utils/AI/chat/sessionTools.mjs.map +1 -1
  153. package/dist/esm/utils/AI/customQuery/index.mjs.map +1 -1
  154. package/dist/esm/utils/AI/getProjectAIOptions.mjs.map +1 -1
  155. package/dist/esm/utils/AI/translateDictionaryDB.mjs.map +1 -1
  156. package/dist/esm/utils/AI/translateJSON/index.mjs.map +1 -1
  157. package/dist/esm/utils/accessControl.mjs.map +1 -1
  158. package/dist/esm/utils/auth/getAuth.mjs.map +1 -1
  159. package/dist/esm/utils/cors.mjs +2 -13
  160. package/dist/esm/utils/cors.mjs.map +1 -1
  161. package/dist/esm/utils/demoDictionaries.mjs.map +1 -1
  162. package/dist/esm/utils/ensureArrayQueryFilter.mjs.map +1 -1
  163. package/dist/esm/utils/ensureMongoDocumentToObject.mjs.map +1 -1
  164. package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
  165. package/dist/esm/utils/errors/ErrorsClass.mjs.map +1 -1
  166. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  167. package/dist/esm/utils/errors/index.mjs +1 -0
  168. package/dist/esm/utils/filtersAndPagination/getDictionaryFiltersAndPagination.mjs.map +1 -1
  169. package/dist/esm/utils/filtersAndPagination/getDiscussionFiltersAndPagination.mjs.map +1 -1
  170. package/dist/esm/utils/filtersAndPagination/getFiltersAndPaginationFromBody.mjs.map +1 -1
  171. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
  172. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
  173. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -1
  174. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
  175. package/dist/esm/utils/getFaviconUrl.mjs.map +1 -1
  176. package/dist/esm/utils/github/connectGithub.mjs.map +1 -1
  177. package/dist/esm/utils/httpStatusCodes.mjs.map +1 -1
  178. package/dist/esm/utils/image/resizeImage.mjs.map +1 -1
  179. package/dist/esm/utils/mapper/dictionary.mjs.map +1 -1
  180. package/dist/esm/utils/mapper/organization.mjs.map +1 -1
  181. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  182. package/dist/esm/utils/mapper/session.mjs.map +1 -1
  183. package/dist/esm/utils/mapper/showcaseProject.mjs.map +1 -1
  184. package/dist/esm/utils/mapper/tag.mjs.map +1 -1
  185. package/dist/esm/utils/mapper/user.mjs.map +1 -1
  186. package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
  187. package/dist/esm/utils/oAuth2.mjs.map +1 -1
  188. package/dist/esm/utils/permissions.mjs.map +1 -1
  189. package/dist/esm/utils/plan.mjs.map +1 -1
  190. package/dist/esm/utils/puppeteer/launchBrowser.mjs.map +1 -1
  191. package/dist/esm/utils/rateLimiter.mjs.map +1 -1
  192. package/dist/esm/utils/redis/connectRedis.mjs.map +1 -1
  193. package/dist/esm/utils/removeObjectKeys.mjs.map +1 -1
  194. package/dist/esm/utils/responseData.mjs.map +1 -1
  195. package/dist/esm/utils/s3/s3Client.mjs.map +1 -1
  196. package/dist/esm/utils/validation/validateDictionary.mjs.map +1 -1
  197. package/dist/esm/utils/validation/validateOrganization.mjs.map +1 -1
  198. package/dist/esm/utils/validation/validateProject.mjs.map +1 -1
  199. package/dist/esm/utils/validation/validateTag.mjs.map +1 -1
  200. package/dist/esm/utils/validation/validateUser.mjs.map +1 -1
  201. package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -1
  202. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  203. package/dist/types/controllers/bitbucket.controller.d.ts.map +1 -1
  204. package/dist/types/controllers/cliSessionToken.controller.d.ts.map +1 -1
  205. package/dist/types/controllers/demo.controller.d.ts.map +1 -1
  206. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  207. package/dist/types/controllers/environment.controller.d.ts.map +1 -1
  208. package/dist/types/controllers/eventListener.controller.d.ts.map +1 -1
  209. package/dist/types/controllers/github.controller.d.ts.map +1 -1
  210. package/dist/types/controllers/gitlab.controller.d.ts.map +1 -1
  211. package/dist/types/controllers/newsletter.controller.d.ts.map +1 -1
  212. package/dist/types/controllers/oAuth2.controller.d.ts.map +1 -1
  213. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  214. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  215. package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
  216. package/dist/types/controllers/projectMemberAccess.controller.d.ts.map +1 -1
  217. package/dist/types/controllers/recursiveAudit.controller.d.ts.map +1 -1
  218. package/dist/types/controllers/reviewer.controller.d.ts.map +1 -1
  219. package/dist/types/controllers/searchDoc.controller.d.ts.map +1 -1
  220. package/dist/types/controllers/showcaseProject.controller.d.ts.map +1 -1
  221. package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
  222. package/dist/types/controllers/tag.controller.d.ts.map +1 -1
  223. package/dist/types/controllers/translation.controller.d.ts.map +1 -1
  224. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  225. package/dist/types/emails/AffiliateActivatedEmail.d.ts +20 -18
  226. package/dist/types/emails/AffiliateActivatedEmail.d.ts.map +1 -1
  227. package/dist/types/emails/AffiliateConversionEmail.d.ts +21 -19
  228. package/dist/types/emails/AffiliateConversionEmail.d.ts.map +1 -1
  229. package/dist/types/emails/AffiliateInvitationEmail.d.ts +20 -18
  230. package/dist/types/emails/AffiliateInvitationEmail.d.ts.map +1 -1
  231. package/dist/types/emails/AffiliateWelcomeEmail.d.ts +20 -18
  232. package/dist/types/emails/AffiliateWelcomeEmail.d.ts.map +1 -1
  233. package/dist/types/emails/InviteUserEmail.d.ts +20 -18
  234. package/dist/types/emails/InviteUserEmail.d.ts.map +1 -1
  235. package/dist/types/emails/MagicLinkEmail.d.ts +20 -18
  236. package/dist/types/emails/MagicLinkEmail.d.ts.map +1 -1
  237. package/dist/types/emails/MissionRequestedClientEmail.d.ts +20 -18
  238. package/dist/types/emails/MissionRequestedClientEmail.d.ts.map +1 -1
  239. package/dist/types/emails/MissionRequestedReviewerEmail.d.ts +20 -18
  240. package/dist/types/emails/MissionRequestedReviewerEmail.d.ts.map +1 -1
  241. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +20 -18
  242. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts.map +1 -1
  243. package/dist/types/emails/PasswordChangeConfirmation.d.ts +20 -18
  244. package/dist/types/emails/PasswordChangeConfirmation.d.ts.map +1 -1
  245. package/dist/types/emails/ResetUserPassword.d.ts +20 -18
  246. package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
  247. package/dist/types/emails/ReviewerApplicationEmail.d.ts +20 -18
  248. package/dist/types/emails/ReviewerApplicationEmail.d.ts.map +1 -1
  249. package/dist/types/emails/ReviewerApprovedEmail.d.ts +20 -18
  250. package/dist/types/emails/ReviewerApprovedEmail.d.ts.map +1 -1
  251. package/dist/types/emails/ReviewerContactEmail.d.ts +3 -1
  252. package/dist/types/emails/ReviewerContactEmail.d.ts.map +1 -1
  253. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +20 -18
  254. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts.map +1 -1
  255. package/dist/types/emails/SubscriptionPaymentError.d.ts +20 -18
  256. package/dist/types/emails/SubscriptionPaymentError.d.ts.map +1 -1
  257. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +20 -18
  258. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts.map +1 -1
  259. package/dist/types/emails/ValidateUserEmail.d.ts +20 -18
  260. package/dist/types/emails/ValidateUserEmail.d.ts.map +1 -1
  261. package/dist/types/emails/Welcome.d.ts +20 -18
  262. package/dist/types/emails/Welcome.d.ts.map +1 -1
  263. package/dist/types/export.d.ts +1 -1
  264. package/dist/types/logger/index.d.ts +3 -1
  265. package/dist/types/logger/index.d.ts.map +1 -1
  266. package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
  267. package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
  268. package/dist/types/routes/demo.routes.d.ts.map +1 -1
  269. package/dist/types/schemas/account.schema.d.ts +35 -34
  270. package/dist/types/schemas/account.schema.d.ts.map +1 -1
  271. package/dist/types/schemas/affiliate.schema.d.ts +109 -108
  272. package/dist/types/schemas/affiliate.schema.d.ts.map +1 -1
  273. package/dist/types/schemas/affiliateInvitation.schema.d.ts +49 -48
  274. package/dist/types/schemas/affiliateInvitation.schema.d.ts.map +1 -1
  275. package/dist/types/schemas/audit.schema.d.ts.map +1 -1
  276. package/dist/types/schemas/auditJob.schema.d.ts +6 -6
  277. package/dist/types/schemas/auditPage.schema.d.ts +6 -6
  278. package/dist/types/schemas/cliSessionToken.schema.d.ts +14 -13
  279. package/dist/types/schemas/cliSessionToken.schema.d.ts.map +1 -1
  280. package/dist/types/schemas/dictionary.schema.d.ts +60 -59
  281. package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
  282. package/dist/types/schemas/discussion.schema.d.ts +51 -50
  283. package/dist/types/schemas/discussion.schema.d.ts.map +1 -1
  284. package/dist/types/schemas/oAuth2.schema.d.ts +18 -17
  285. package/dist/types/schemas/oAuth2.schema.d.ts.map +1 -1
  286. package/dist/types/schemas/organization.schema.d.ts +45 -44
  287. package/dist/types/schemas/organization.schema.d.ts.map +1 -1
  288. package/dist/types/schemas/plans.schema.d.ts +45 -44
  289. package/dist/types/schemas/plans.schema.d.ts.map +1 -1
  290. package/dist/types/schemas/project.schema.d.ts +73 -72
  291. package/dist/types/schemas/project.schema.d.ts.map +1 -1
  292. package/dist/types/schemas/promoCode.schema.d.ts +61 -60
  293. package/dist/types/schemas/promoCode.schema.d.ts.map +1 -1
  294. package/dist/types/schemas/reviewer.schema.d.ts +221 -220
  295. package/dist/types/schemas/reviewer.schema.d.ts.map +1 -1
  296. package/dist/types/schemas/session.schema.d.ts +54 -52
  297. package/dist/types/schemas/session.schema.d.ts.map +1 -1
  298. package/dist/types/schemas/showcaseProject.schema.d.ts +61 -60
  299. package/dist/types/schemas/showcaseProject.schema.d.ts.map +1 -1
  300. package/dist/types/schemas/tag.schema.d.ts +45 -44
  301. package/dist/types/schemas/tag.schema.d.ts.map +1 -1
  302. package/dist/types/schemas/user.schema.d.ts +71 -70
  303. package/dist/types/schemas/user.schema.d.ts.map +1 -1
  304. package/dist/types/services/affiliate.service.d.ts.map +1 -1
  305. package/dist/types/services/audit/analysis/analyzeBundleContent.d.ts.map +1 -1
  306. package/dist/types/services/audit/analysis/analyzeLinguisticStructure.d.ts.map +1 -1
  307. package/dist/types/services/audit/analysis/analyzeRobots.d.ts.map +1 -1
  308. package/dist/types/services/audit/analysis/analyzeSitemap.d.ts.map +1 -1
  309. package/dist/types/services/audit/analysis/calculateScore.d.ts.map +1 -1
  310. package/dist/types/services/audit/checkers/bundleChecker.d.ts.map +1 -1
  311. package/dist/types/services/audit/recursiveAudit.service.d.ts +5 -4
  312. package/dist/types/services/audit/recursiveAudit.service.d.ts.map +1 -1
  313. package/dist/types/services/audit/types.d.ts.map +1 -1
  314. package/dist/types/services/bitbucket.service.d.ts.map +1 -1
  315. package/dist/types/services/cliSessionToken.service.d.ts.map +1 -1
  316. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  317. package/dist/types/services/email.service.d.ts.map +1 -1
  318. package/dist/types/services/github.service.d.ts.map +1 -1
  319. package/dist/types/services/gitlab.service.d.ts.map +1 -1
  320. package/dist/types/services/oAuth2.service.d.ts.map +1 -1
  321. package/dist/types/services/organization.service.d.ts.map +1 -1
  322. package/dist/types/services/project/projectScreenshot.service.d.ts.map +1 -1
  323. package/dist/types/services/project.service.d.ts.map +1 -1
  324. package/dist/types/services/promoCode.service.d.ts.map +1 -1
  325. package/dist/types/services/reviewer/pictureUpload.service.d.ts.map +1 -1
  326. package/dist/types/services/reviewer.service.d.ts.map +1 -1
  327. package/dist/types/services/reviewerMessage.service.d.ts.map +1 -1
  328. package/dist/types/services/reviewerMission.service.d.ts.map +1 -1
  329. package/dist/types/services/session.service.d.ts.map +1 -1
  330. package/dist/types/services/showcase/showcaseProject.service.d.ts.map +1 -1
  331. package/dist/types/services/showcase/showcaseScan.service.d.ts.map +1 -1
  332. package/dist/types/services/showcase/showcaseUploadScreenshot.service.d.ts.map +1 -1
  333. package/dist/types/services/showcase/showcaseVerifyBundle.service.d.ts.map +1 -1
  334. package/dist/types/services/showcase/showcaseVerifyGithub.service.d.ts.map +1 -1
  335. package/dist/types/services/subscription.service.d.ts.map +1 -1
  336. package/dist/types/services/tag.service.d.ts.map +1 -1
  337. package/dist/types/services/translationQueue.service.d.ts +2 -1
  338. package/dist/types/services/translationQueue.service.d.ts.map +1 -1
  339. package/dist/types/services/translationWorker.service.d.ts.map +1 -1
  340. package/dist/types/services/user/avatarUpload.service.d.ts.map +1 -1
  341. package/dist/types/services/user.service.d.ts.map +1 -1
  342. package/dist/types/services/webhook.service.d.ts.map +1 -1
  343. package/dist/types/types/Routes.d.ts.map +1 -1
  344. package/dist/types/types/account.types.d.ts.map +1 -1
  345. package/dist/types/types/affiliate.types.d.ts.map +1 -1
  346. package/dist/types/types/affiliateInvitation.types.d.ts.map +1 -1
  347. package/dist/types/types/dictionary.types.d.ts.map +1 -1
  348. package/dist/types/types/discussion.types.d.ts.map +1 -1
  349. package/dist/types/types/oAuth2.types.d.ts.map +1 -1
  350. package/dist/types/types/organization.types.d.ts.map +1 -1
  351. package/dist/types/types/plan.types.d.ts.map +1 -1
  352. package/dist/types/types/project.types.d.ts.map +1 -1
  353. package/dist/types/types/promoCode.types.d.ts.map +1 -1
  354. package/dist/types/types/reviewer.types.d.ts.map +1 -1
  355. package/dist/types/types/session.types.d.ts.map +1 -1
  356. package/dist/types/types/showcaseProject.types.d.ts.map +1 -1
  357. package/dist/types/types/tag.types.d.ts.map +1 -1
  358. package/dist/types/types/user.types.d.ts.map +1 -1
  359. package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -1
  360. package/dist/types/utils/AI/askDocQuestion/indexMarkdownFiles.d.ts.map +1 -1
  361. package/dist/types/utils/AI/auditDictionary/index.d.ts.map +1 -1
  362. package/dist/types/utils/AI/auditDictionaryField/index.d.ts.map +1 -1
  363. package/dist/types/utils/AI/auditDictionaryMetadata/index.d.ts.map +1 -1
  364. package/dist/types/utils/AI/auditTag/index.d.ts.map +1 -1
  365. package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -1
  366. package/dist/types/utils/AI/chat/index.d.ts.map +1 -1
  367. package/dist/types/utils/AI/chat/mcpInProcessTools.d.ts.map +1 -1
  368. package/dist/types/utils/AI/chat/sessionTools.d.ts +25 -24
  369. package/dist/types/utils/AI/chat/sessionTools.d.ts.map +1 -1
  370. package/dist/types/utils/AI/customQuery/index.d.ts.map +1 -1
  371. package/dist/types/utils/AI/translateDictionaryDB.d.ts.map +1 -1
  372. package/dist/types/utils/AI/translateJSON/index.d.ts.map +1 -1
  373. package/dist/types/utils/auth/getAuth.d.ts.map +1 -1
  374. package/dist/types/utils/cors.d.ts +1 -7
  375. package/dist/types/utils/cors.d.ts.map +1 -1
  376. package/dist/types/utils/demoDictionaries.d.ts.map +1 -1
  377. package/dist/types/utils/ensureArrayQueryFilter.d.ts.map +1 -1
  378. package/dist/types/utils/errors/ErrorHandler.d.ts +8 -6
  379. package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
  380. package/dist/types/utils/errors/ErrorsClass.d.ts.map +1 -1
  381. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  382. package/dist/types/utils/filtersAndPagination/getDictionaryFiltersAndPagination.d.ts.map +1 -1
  383. package/dist/types/utils/filtersAndPagination/getDiscussionFiltersAndPagination.d.ts.map +1 -1
  384. package/dist/types/utils/filtersAndPagination/getFiltersAndPaginationFromBody.d.ts.map +1 -1
  385. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
  386. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
  387. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +7 -6
  388. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -1
  389. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
  390. package/dist/types/utils/getFaviconUrl.d.ts.map +1 -1
  391. package/dist/types/utils/github/connectGithub.d.ts.map +1 -1
  392. package/dist/types/utils/httpStatusCodes.d.ts.map +1 -1
  393. package/dist/types/utils/image/resizeImage.d.ts.map +1 -1
  394. package/dist/types/utils/mapper/dictionary.d.ts.map +1 -1
  395. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  396. package/dist/types/utils/mapper/session.d.ts.map +1 -1
  397. package/dist/types/utils/mapper/showcaseProject.d.ts.map +1 -1
  398. package/dist/types/utils/mapper/tag.d.ts.map +1 -1
  399. package/dist/types/utils/mergeFunctionTypes.d.ts.map +1 -1
  400. package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
  401. package/dist/types/utils/mongoDB/types.d.ts.map +1 -1
  402. package/dist/types/utils/oAuth2.d.ts.map +1 -1
  403. package/dist/types/utils/permissions.d.ts +2 -1
  404. package/dist/types/utils/permissions.d.ts.map +1 -1
  405. package/dist/types/utils/plan.d.ts.map +1 -1
  406. package/dist/types/utils/rateLimiter.d.ts.map +1 -1
  407. package/dist/types/utils/redis/connectRedis.d.ts.map +1 -1
  408. package/dist/types/utils/responseData.d.ts.map +1 -1
  409. package/dist/types/utils/s3/s3Client.d.ts.map +1 -1
  410. package/dist/types/utils/validation/validateDictionary.d.ts.map +1 -1
  411. package/dist/types/utils/validation/validateOrganization.d.ts.map +1 -1
  412. package/dist/types/utils/validation/validateProject.d.ts.map +1 -1
  413. package/dist/types/utils/validation/validateTag.d.ts.map +1 -1
  414. package/dist/types/utils/validation/validateUser.d.ts.map +1 -1
  415. package/package.json +17 -17
@@ -1,3 +1,4 @@
1
+ import { errorData } from "./errorCodes.mjs";
1
2
  import { ErrorHandler, formatGenericErrorResponse, handleAppErrorResponse, handleCustomErrorResponse, handleGenericErrorResponse } from "./ErrorHandler.mjs";
2
3
  import { AppError, GenericError } from "./ErrorsClass.mjs";
3
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"getDictionaryFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getDictionaryFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type DictionaryFiltersParams = {\n ids?: string | string[];\n projectId?: string;\n projectIds?: string[];\n organizationId?: string;\n organizationIds?: string[];\n userId?: string;\n userIds?: string[];\n creatorId?: string;\n creatorIds?: string[];\n title?: string;\n description?: string;\n key?: string;\n keys?: string[];\n tags?: string | string[];\n location?: 'remote' | 'local' | 'both' | 'none';\n priority?: string;\n version?: string;\n search?: string;\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all users without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type DictionaryFilters = any; // mongoose.QueryFilter<Dictionary>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getDictionaryFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<DictionaryFiltersParams>;\n }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<DictionaryFiltersParams>(req);\n const roles = req.session?.roles;\n const project = req.session?.project;\n\n let filters: DictionaryFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n key,\n search,\n keys,\n tags,\n location,\n priority,\n ids,\n projectId,\n projectIds,\n userId,\n userIds,\n creatorId,\n creatorIds,\n title,\n description,\n version,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n // null = production (default env); an ObjectId string = a specific non-default env.\n // The session always carries this convention (set by the selectEnvironment endpoint).\n const sessionEnvironmentId =\n (req.session?.session as any)?.activeEnvironmentId ?? null;\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (projectId) {\n filters = { ...filters, projectIds: projectId };\n }\n\n if (projectIds) {\n filters = {\n ...filters,\n projectIds: { $in: ensureArrayQueryFilter(projectIds) },\n };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, projectIds: { $in: project?.id } };\n }\n\n if (userId) {\n filters = { ...filters, creatorId: userId };\n }\n\n if (userIds) {\n filters = {\n ...filters,\n creatorId: { $in: ensureArrayQueryFilter(userIds) },\n };\n }\n\n if (creatorId) {\n filters = { ...filters, creatorId: creatorId };\n }\n\n if (creatorIds) {\n filters = {\n ...filters,\n creatorId: { $in: ensureArrayQueryFilter(creatorIds) },\n };\n }\n\n if (title) {\n filters = { ...filters, title: new RegExp(title, 'i') };\n }\n\n if (description) {\n filters = { ...filters, description: new RegExp(description, 'i') };\n }\n\n if (key) {\n filters = { ...filters, key: new RegExp(key, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { key: searchRegex },\n { title: searchRegex },\n { description: searchRegex },\n { tags: searchRegex },\n ],\n };\n }\n\n if (keys) {\n filters = { ...filters, key: { $in: ensureArrayQueryFilter(keys) } };\n }\n\n if (tags) {\n filters = { ...filters, tags: { $in: ensureArrayQueryFilter(tags) } };\n }\n\n if (location === 'local') {\n filters = { ...filters, _id: null };\n }\n\n if (priority) {\n filters = { ...filters, priority: Number(priority) };\n }\n\n if (version) {\n filters = { ...filters, [`content.${version}`]: { $exists: true } };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n // Always scope by environment.\n // Production (sessionEnvironmentId = null): match dicts with no environmentId set.\n // { environmentId: null } in $match covers both explicit null and missing field.\n // Other envs: match dicts with the exact environmentId.\n if (sessionEnvironmentId) {\n filters = { ...filters, environmentId: sessionEnvironmentId };\n } else {\n filters = { ...filters, environmentId: null };\n }\n\n // Enforce allowedEnvironmentIds constraint (from memberAccess or access key scope).\n // Skip for admin/org_admin/project_admin who bypass granular constraints.\n const sessionAllowedEnvironmentIds =\n req.session?.allowedEnvironmentIds ?? null;\n const isGlobalAdmin =\n roles?.includes('admin') ||\n roles?.includes('org_admin') ||\n roles?.includes('project_admin');\n\n if (sessionAllowedEnvironmentIds !== null && !isGlobalAdmin) {\n // Check whether the session's active environment is in the allowed list.\n const isSessionEnvAllowed = sessionAllowedEnvironmentIds.some(\n (allowedEnvId) => {\n if (sessionEnvironmentId === null) {\n return allowedEnvId === null;\n }\n return String(allowedEnvId) === String(sessionEnvironmentId);\n }\n );\n\n if (!isSessionEnvAllowed) {\n // Block all dictionary access — current env is not in the allowed set.\n filters = { ...filters, _id: null };\n }\n // When allowed, the session env filter applied above is already correct.\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"getDictionaryFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getDictionaryFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type DictionaryFiltersParams = {\n ids?: string | string[];\n projectId?: string;\n projectIds?: string[];\n organizationId?: string;\n organizationIds?: string[];\n userId?: string;\n userIds?: string[];\n creatorId?: string;\n creatorIds?: string[];\n title?: string;\n description?: string;\n key?: string;\n keys?: string[];\n tags?: string | string[];\n location?: 'remote' | 'local' | 'both' | 'none';\n priority?: string;\n version?: string;\n search?: string;\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all users without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type DictionaryFilters = any; // mongoose.QueryFilter<Dictionary>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getDictionaryFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<DictionaryFiltersParams>;\n }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<DictionaryFiltersParams>(req);\n const roles = req.session?.roles;\n const project = req.session?.project;\n\n let filters: DictionaryFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n key,\n search,\n keys,\n tags,\n location,\n priority,\n ids,\n projectId,\n projectIds,\n userId,\n userIds,\n creatorId,\n creatorIds,\n title,\n description,\n version,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n // null = production (default env); an ObjectId string = a specific non-default env.\n // The session always carries this convention (set by the selectEnvironment endpoint).\n const sessionEnvironmentId =\n (req.session?.session as any)?.activeEnvironmentId ?? null;\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (projectId) {\n filters = { ...filters, projectIds: projectId };\n }\n\n if (projectIds) {\n filters = {\n ...filters,\n projectIds: { $in: ensureArrayQueryFilter(projectIds) },\n };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, projectIds: { $in: project?.id } };\n }\n\n if (userId) {\n filters = { ...filters, creatorId: userId };\n }\n\n if (userIds) {\n filters = {\n ...filters,\n creatorId: { $in: ensureArrayQueryFilter(userIds) },\n };\n }\n\n if (creatorId) {\n filters = { ...filters, creatorId: creatorId };\n }\n\n if (creatorIds) {\n filters = {\n ...filters,\n creatorId: { $in: ensureArrayQueryFilter(creatorIds) },\n };\n }\n\n if (title) {\n filters = { ...filters, title: new RegExp(title, 'i') };\n }\n\n if (description) {\n filters = { ...filters, description: new RegExp(description, 'i') };\n }\n\n if (key) {\n filters = { ...filters, key: new RegExp(key, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { key: searchRegex },\n { title: searchRegex },\n { description: searchRegex },\n { tags: searchRegex },\n ],\n };\n }\n\n if (keys) {\n filters = { ...filters, key: { $in: ensureArrayQueryFilter(keys) } };\n }\n\n if (tags) {\n filters = { ...filters, tags: { $in: ensureArrayQueryFilter(tags) } };\n }\n\n if (location === 'local') {\n filters = { ...filters, _id: null };\n }\n\n if (priority) {\n filters = { ...filters, priority: Number(priority) };\n }\n\n if (version) {\n filters = { ...filters, [`content.${version}`]: { $exists: true } };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n // Always scope by environment.\n // Production (sessionEnvironmentId = null): match dicts with no environmentId set.\n // { environmentId: null } in $match covers both explicit null and missing field.\n // Other envs: match dicts with the exact environmentId.\n if (sessionEnvironmentId) {\n filters = { ...filters, environmentId: sessionEnvironmentId };\n } else {\n filters = { ...filters, environmentId: null };\n }\n\n // Enforce allowedEnvironmentIds constraint (from memberAccess or access key scope).\n // Skip for admin/org_admin/project_admin who bypass granular constraints.\n const sessionAllowedEnvironmentIds =\n req.session?.allowedEnvironmentIds ?? null;\n const isGlobalAdmin =\n roles?.includes('admin') ||\n roles?.includes('org_admin') ||\n roles?.includes('project_admin');\n\n if (sessionAllowedEnvironmentIds !== null && !isGlobalAdmin) {\n // Check whether the session's active environment is in the allowed list.\n const isSessionEnvAllowed = sessionAllowedEnvironmentIds.some(\n (allowedEnvId) => {\n if (sessionEnvironmentId === null) {\n return allowedEnvId === null;\n }\n return String(allowedEnvId) === String(sessionEnvironmentId);\n }\n );\n\n if (!isSessionEnvAllowed) {\n // Block all dictionary access — current env is not in the allowed set.\n filters = { ...filters, _id: null };\n }\n // When allowed, the session env filter applied above is already correct.\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getDiscussionFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getDiscussionFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type DiscussionFiltersParams = {\n ids?: string | string[];\n userId?: string;\n userIds?: string[];\n discussionId?: string;\n search?: string;\n isArchived?: 'true' | 'false';\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users only: if true, will not restrict to current user\n */\n fetchAll?: 'true' | 'false';\n};\nexport type DiscussionFilters = any;\n\n/**\n * Extracts filters and pagination information for discussions.\n * Enforces that non-admin users can only see their own discussions.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getDiscussionFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<DiscussionFiltersParams>;\n }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<DiscussionFiltersParams>(req);\n const roles = req.session?.roles;\n const user = req.session?.user;\n\n let filters: DiscussionFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n ids,\n userId,\n userIds,\n discussionId,\n search,\n isArchived,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (discussionId) {\n filters = { ...filters, discussionId };\n }\n\n if (typeof isArchived !== 'undefined') {\n filters = { ...filters, isArchived: isArchived === 'true' };\n }\n\n if (userId) {\n filters = { ...filters, userId: userId };\n }\n\n if (userIds) {\n filters = { ...filters, userId: { $in: ensureArrayQueryFilter(userIds) } };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { discussionId: searchRegex },\n { title: searchRegex },\n // search within messages content\n { 'messages.content': searchRegex },\n ],\n } as DiscussionFilters;\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n // Enforce user scope for non-admins\n const isAdmin = roles?.includes('admin');\n if (!isAdmin && user?.id) {\n filters = { ...filters, userId: user.id };\n } else if (isAdmin && fetchAll !== 'true' && user?.id) {\n // by default, even admins see their own discussions unless fetchAll=true\n filters = { ...filters, userId: user.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;;AA6BA,MAAa,qCACX,QAGG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAyD,GAAG;CAC9D,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,OAAO,IAAI,SAAS;CAE1B,IAAI,UAA6B,CAAC;CAClC,IAAI,cAAsC,EAAE,WAAW,GAAG;CAE1D,MAAM,EACJ,KACA,QACA,SACA,cACA,QACA,YACA,QACA,WACA,aACE,kBAAkB,CAAC;CAEvB,IAAI,KACF,UAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,GAAG,EAAE;CAAE;CAGpE,IAAI,cACF,UAAU;EAAE,GAAG;EAAS;CAAa;CAGvC,IAAI,OAAO,eAAe,aACxB,UAAU;EAAE,GAAG;EAAS,YAAY,eAAe;CAAO;CAG5D,IAAI,QACF,UAAU;EAAE,GAAG;EAAiB;CAAO;CAGzC,IAAI,SACF,UAAU;EAAE,GAAG;EAAS,QAAQ,EAAE,KAAK,uBAAuB,OAAO,EAAE;CAAE;CAG3E,IAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,GAAG;EAC1C,UAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,cAAc,YAAY;IAC5B,EAAE,OAAO,YAAY;IAErB,EAAE,oBAAoB,YAAY;GACpC;EACF;CACF;CAEA,IAAI,UAAU,cAAc,cAAc,SAAS,cAAc,SAC/D,cAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,GAAG;CAIzD,MAAM,UAAU,OAAO,SAAS,OAAO;CACvC,IAAI,CAAC,WAAW,MAAM,IACpB,UAAU;EAAE,GAAG;EAAS,QAAQ,KAAK;CAAG;MACnC,IAAI,WAAW,aAAa,UAAU,MAAM,IAEjD,UAAU;EAAE,GAAG;EAAS,QAAQ,KAAK;CAAG;CAG1C,OAAO;EAAE;EAAS;EAAa,GAAG;CAAW;AAC/C"}
1
+ {"version":3,"file":"getDiscussionFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getDiscussionFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type DiscussionFiltersParams = {\n ids?: string | string[];\n userId?: string;\n userIds?: string[];\n discussionId?: string;\n search?: string;\n isArchived?: 'true' | 'false';\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users only: if true, will not restrict to current user\n */\n fetchAll?: 'true' | 'false';\n};\nexport type DiscussionFilters = any;\n\n/**\n * Extracts filters and pagination information for discussions.\n * Enforces that non-admin users can only see their own discussions.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getDiscussionFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<DiscussionFiltersParams>;\n }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<DiscussionFiltersParams>(req);\n const roles = req.session?.roles;\n const user = req.session?.user;\n\n let filters: DiscussionFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n ids,\n userId,\n userIds,\n discussionId,\n search,\n isArchived,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (discussionId) {\n filters = { ...filters, discussionId };\n }\n\n if (typeof isArchived !== 'undefined') {\n filters = { ...filters, isArchived: isArchived === 'true' };\n }\n\n if (userId) {\n filters = { ...filters, userId: userId };\n }\n\n if (userIds) {\n filters = { ...filters, userId: { $in: ensureArrayQueryFilter(userIds) } };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { discussionId: searchRegex },\n { title: searchRegex },\n // search within messages content\n { 'messages.content': searchRegex },\n ],\n } as DiscussionFilters;\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n // Enforce user scope for non-admins\n const isAdmin = roles?.includes('admin');\n if (!isAdmin && user?.id) {\n filters = { ...filters, userId: user.id };\n } else if (isAdmin && fetchAll !== 'true' && user?.id) {\n // by default, even admins see their own discussions unless fetchAll=true\n filters = { ...filters, userId: user.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;;AA6BA,MAAa,qCACX,QAGG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAyD,IAAI;CAC/D,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,OAAO,IAAI,SAAS;CAE1B,IAAI,UAA6B,EAAE;CACnC,IAAI,cAAsC,EAAE,WAAW,IAAI;CAE3D,MAAM,EACJ,KACA,QACA,SACA,cACA,QACA,YACA,QACA,WACA,aACE,kBAAkB,EAAE;AAExB,KAAI,IACF,WAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;EAAE;AAGrE,KAAI,aACF,WAAU;EAAE,GAAG;EAAS;EAAc;AAGxC,KAAI,OAAO,eAAe,YACxB,WAAU;EAAE,GAAG;EAAS,YAAY,eAAe;EAAQ;AAG7D,KAAI,OACF,WAAU;EAAE,GAAG;EAAiB;EAAQ;AAG1C,KAAI,QACF,WAAU;EAAE,GAAG;EAAS,QAAQ,EAAE,KAAK,uBAAuB,QAAQ,EAAE;EAAE;AAG5E,KAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,IAAI;AAC3C,YAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,cAAc,aAAa;IAC7B,EAAE,OAAO,aAAa;IAEtB,EAAE,oBAAoB,aAAa;IACpC;GACF;;AAGH,KAAI,UAAU,cAAc,cAAc,SAAS,cAAc,QAC/D,eAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,IAAI;CAI1D,MAAM,UAAU,OAAO,SAAS,QAAQ;AACxC,KAAI,CAAC,WAAW,MAAM,GACpB,WAAU;EAAE,GAAG;EAAS,QAAQ,KAAK;EAAI;UAChC,WAAW,aAAa,UAAU,MAAM,GAEjD,WAAU;EAAE,GAAG;EAAS,QAAQ,KAAK;EAAI;AAG3C,QAAO;EAAE;EAAS;EAAa,GAAG;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFiltersAndPaginationFromBody.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getFiltersAndPaginationFromBody.ts"],"sourcesContent":["import type { FastifyRequest } from 'fastify';\nimport type { ObjectId } from 'mongoose';\n\nconst DEFAULT_PAGE_SIZE = 1000;\nconst DEFAULT_PAGE = 1;\n\ntype Filters = Record<string, string | string[] | ObjectId | ObjectId[]>;\n\nexport type FiltersAndPagination<T extends Filters> =\n | ({\n page?: string | number;\n pageSize?: string | number;\n } & T)\n | undefined;\n\nexport type FiltersAndPaginationResult<T extends Filters> = {\n filters: T;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getFiltersAndPaginationFromBody = <T extends Filters>(\n req: FastifyRequest<{ Querystring: FiltersAndPagination<T> }>\n): FiltersAndPaginationResult<T> => {\n let filters = {} as T;\n let pageSize = DEFAULT_PAGE_SIZE;\n let page = DEFAULT_PAGE;\n\n const query = req.query as unknown as FiltersAndPagination<T>;\n\n if (typeof query === 'object') {\n const {\n pageSize: pageSizeRequest,\n page: pageRequest,\n ...filtersRequest\n } = query;\n\n if (typeof pageSizeRequest === 'string') {\n pageSize = parseInt(pageSizeRequest, 10);\n } else if (typeof pageSizeRequest === 'number') {\n pageSize = pageSizeRequest;\n }\n\n if (typeof pageRequest === 'string') {\n page = parseInt(pageRequest, 10);\n } else if (typeof pageRequest === 'number') {\n page = pageRequest;\n }\n\n if (filtersRequest && Object.keys(filtersRequest).length > 0) {\n filters = filtersRequest as T;\n }\n }\n\n const skip = (page - 1) * pageSize;\n\n const getNumberOfPages = (totalItems: number) =>\n Math.ceil(totalItems / pageSize);\n\n return {\n filters,\n skip,\n page,\n pageSize,\n getNumberOfPages,\n };\n};\n"],"mappings":";AAGA,MAAM,oBAAoB;AAC1B,MAAM,eAAe;;;;;;AAwBrB,MAAa,mCACX,QACkC;CAClC,IAAI,UAAU,CAAC;CACf,IAAI,WAAW;CACf,IAAI,OAAO;CAEX,MAAM,QAAQ,IAAI;CAElB,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,EACJ,UAAU,iBACV,MAAM,aACN,GAAG,mBACD;EAEJ,IAAI,OAAO,oBAAoB,UAC7B,WAAW,SAAS,iBAAiB,EAAE;OAClC,IAAI,OAAO,oBAAoB,UACpC,WAAW;EAGb,IAAI,OAAO,gBAAgB,UACzB,OAAO,SAAS,aAAa,EAAE;OAC1B,IAAI,OAAO,gBAAgB,UAChC,OAAO;EAGT,IAAI,kBAAkB,OAAO,KAAK,cAAc,CAAC,CAAC,SAAS,GACzD,UAAU;CAEd;CAEA,MAAM,QAAQ,OAAO,KAAK;CAE1B,MAAM,oBAAoB,eACxB,KAAK,KAAK,aAAa,QAAQ;CAEjC,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"getFiltersAndPaginationFromBody.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getFiltersAndPaginationFromBody.ts"],"sourcesContent":["import type { FastifyRequest } from 'fastify';\nimport type { ObjectId } from 'mongoose';\n\nconst DEFAULT_PAGE_SIZE = 1000;\nconst DEFAULT_PAGE = 1;\n\ntype Filters = Record<string, string | string[] | ObjectId | ObjectId[]>;\n\nexport type FiltersAndPagination<T extends Filters> =\n | ({\n page?: string | number;\n pageSize?: string | number;\n } & T)\n | undefined;\n\nexport type FiltersAndPaginationResult<T extends Filters> = {\n filters: T;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getFiltersAndPaginationFromBody = <T extends Filters>(\n req: FastifyRequest<{ Querystring: FiltersAndPagination<T> }>\n): FiltersAndPaginationResult<T> => {\n let filters = {} as T;\n let pageSize = DEFAULT_PAGE_SIZE;\n let page = DEFAULT_PAGE;\n\n const query = req.query as unknown as FiltersAndPagination<T>;\n\n if (typeof query === 'object') {\n const {\n pageSize: pageSizeRequest,\n page: pageRequest,\n ...filtersRequest\n } = query;\n\n if (typeof pageSizeRequest === 'string') {\n pageSize = parseInt(pageSizeRequest, 10);\n } else if (typeof pageSizeRequest === 'number') {\n pageSize = pageSizeRequest;\n }\n\n if (typeof pageRequest === 'string') {\n page = parseInt(pageRequest, 10);\n } else if (typeof pageRequest === 'number') {\n page = pageRequest;\n }\n\n if (filtersRequest && Object.keys(filtersRequest).length > 0) {\n filters = filtersRequest as T;\n }\n }\n\n const skip = (page - 1) * pageSize;\n\n const getNumberOfPages = (totalItems: number) =>\n Math.ceil(totalItems / pageSize);\n\n return {\n filters,\n skip,\n page,\n pageSize,\n getNumberOfPages,\n };\n};\n"],"mappings":";AAGA,MAAM,oBAAoB;AAC1B,MAAM,eAAe;;;;;;AAwBrB,MAAa,mCACX,QACkC;CAClC,IAAI,UAAU,EAAE;CAChB,IAAI,WAAW;CACf,IAAI,OAAO;CAEX,MAAM,QAAQ,IAAI;AAElB,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,EACJ,UAAU,iBACV,MAAM,aACN,GAAG,mBACD;AAEJ,MAAI,OAAO,oBAAoB,SAC7B,YAAW,SAAS,iBAAiB,GAAG;WAC/B,OAAO,oBAAoB,SACpC,YAAW;AAGb,MAAI,OAAO,gBAAgB,SACzB,QAAO,SAAS,aAAa,GAAG;WACvB,OAAO,gBAAgB,SAChC,QAAO;AAGT,MAAI,kBAAkB,OAAO,KAAK,eAAe,CAAC,SAAS,EACzD,WAAU;;CAId,MAAM,QAAQ,OAAO,KAAK;CAE1B,MAAM,oBAAoB,eACxB,KAAK,KAAK,aAAa,SAAS;AAElC,QAAO;EACL;EACA;EACA;EACA;EACA;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"getOrganizationFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getOrganizationFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Organization } from '@/types/organization.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type OrganizationFiltersParams = {\n /**\n * Comma separated list of ids\n *\n * ```\n * GET /organizations?ids=5f8d9f1d8a1e4f0e8c0c,5f8d9f1d8a1e4f0e8d1\n * -> ids: \"5f8d9f1d8a1e4f0e8c0c,5f8d9f1d8a1e4f0e8d1\"\n * ```\n */\n ids?: string | string[];\n name?: string;\n search?: string;\n membersIds?: string[];\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all organizations without filtering by members\n */\n fetchAll?: 'true' | 'false';\n};\nexport type OrganizationFilters = QueryFilter<Organization>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport type OrganizationFiltersAndPaginationResult = {\n filters: OrganizationFilters;\n sortOptions: Record<string, 1 | -1>;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\nexport const getOrganizationFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<OrganizationFiltersParams>;\n }>\n): OrganizationFiltersAndPaginationResult => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<OrganizationFiltersParams>(req);\n const roles = req.session?.roles;\n const user = req.session?.user;\n\n let filters: OrganizationFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const { name, search, ids, membersIds, fetchAll, sortBy, sortOrder } =\n filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n // Non-admins can only see organizations they are members of\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, membersIds: { $in: [user?.id] } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = { ...filters, $or: [{ name: searchRegex }] };\n }\n\n if (membersIds) {\n filters = {\n ...filters,\n membersIds: { $in: ensureArrayQueryFilter(membersIds) },\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;AA6CA,MAAa,uCACX,QAG2C;CAC3C,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAA2D,GAAG;CAChE,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,OAAO,IAAI,SAAS;CAE1B,IAAI,UAA+B,CAAC;CACpC,IAAI,cAAsC,EAAE,WAAW,GAAG;CAE1D,MAAM,EAAE,MAAM,QAAQ,KAAK,YAAY,UAAU,QAAQ,cACvD,kBAAkB,CAAC;CAErB,IAAI,KACF,UAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,GAAG,EAAE;CAAE;CAIpE,IAAI,EAAE,OAAO,SAAS,OAAO,KAAK,aAAa,SAC7C,UAAU;EAAE,GAAG;EAAS,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE;CAAE;CAG1D,IAAI,MACF,UAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,GAAG;CAAE;CAGtD,IAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,GAAG;EAC1C,UAAU;GAAE,GAAG;GAAS,KAAK,CAAC,EAAE,MAAM,YAAY,CAAC;EAAE;CACvD;CAEA,IAAI,YACF,UAAU;EACR,GAAG;EACH,YAAY,EAAE,KAAK,uBAAuB,UAAU,EAAE;CACxD;CAGF,IAAI,UAAU,cAAc,cAAc,SAAS,cAAc,SAC/D,cAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,GAAG;CAGzD,OAAO;EAAE;EAAS;EAAa,GAAG;CAAW;AAC/C"}
1
+ {"version":3,"file":"getOrganizationFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getOrganizationFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Organization } from '@/types/organization.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type OrganizationFiltersParams = {\n /**\n * Comma separated list of ids\n *\n * ```\n * GET /organizations?ids=5f8d9f1d8a1e4f0e8c0c,5f8d9f1d8a1e4f0e8d1\n * -> ids: \"5f8d9f1d8a1e4f0e8c0c,5f8d9f1d8a1e4f0e8d1\"\n * ```\n */\n ids?: string | string[];\n name?: string;\n search?: string;\n membersIds?: string[];\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all organizations without filtering by members\n */\n fetchAll?: 'true' | 'false';\n};\nexport type OrganizationFilters = QueryFilter<Organization>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport type OrganizationFiltersAndPaginationResult = {\n filters: OrganizationFilters;\n sortOptions: Record<string, 1 | -1>;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\nexport const getOrganizationFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<OrganizationFiltersParams>;\n }>\n): OrganizationFiltersAndPaginationResult => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<OrganizationFiltersParams>(req);\n const roles = req.session?.roles;\n const user = req.session?.user;\n\n let filters: OrganizationFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const { name, search, ids, membersIds, fetchAll, sortBy, sortOrder } =\n filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n // Non-admins can only see organizations they are members of\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, membersIds: { $in: [user?.id] } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = { ...filters, $or: [{ name: searchRegex }] };\n }\n\n if (membersIds) {\n filters = {\n ...filters,\n membersIds: { $in: ensureArrayQueryFilter(membersIds) },\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;AA6CA,MAAa,uCACX,QAG2C;CAC3C,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAA2D,IAAI;CACjE,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,OAAO,IAAI,SAAS;CAE1B,IAAI,UAA+B,EAAE;CACrC,IAAI,cAAsC,EAAE,WAAW,IAAI;CAE3D,MAAM,EAAE,MAAM,QAAQ,KAAK,YAAY,UAAU,QAAQ,cACvD,kBAAkB,EAAE;AAEtB,KAAI,IACF,WAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;EAAE;AAIrE,KAAI,EAAE,OAAO,SAAS,QAAQ,IAAI,aAAa,QAC7C,WAAU;EAAE,GAAG;EAAS,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE;EAAE;AAG3D,KAAI,KACF,WAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,IAAI;EAAE;AAGvD,KAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,IAAI;AAC3C,YAAU;GAAE,GAAG;GAAS,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;GAAE;;AAGxD,KAAI,WACF,WAAU;EACR,GAAG;EACH,YAAY,EAAE,KAAK,uBAAuB,WAAW,EAAE;EACxD;AAGH,KAAI,UAAU,cAAc,cAAc,SAAS,cAAc,QAC/D,eAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,IAAI;AAG1D,QAAO;EAAE;EAAS;EAAa,GAAG;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"getProjectFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getProjectFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Project } from '@/types/project.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type ProjectFiltersParams = {\n ids?: string | string[];\n name?: string;\n search?: string;\n organizationId?: string;\n membersIds?: string[];\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all projects without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type ProjectFilters = QueryFilter<Project>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport type ProjectFiltersAndPaginationResult = {\n filters: ProjectFilters;\n sortOptions: Record<string, 1 | -1>;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\nexport const getProjectFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<ProjectFiltersParams>;\n }>\n): ProjectFiltersAndPaginationResult => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<ProjectFiltersParams>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters: ProjectFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n name,\n search,\n ids,\n organizationId,\n membersIds,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [{ name: searchRegex }],\n };\n }\n\n if (organizationId) {\n filters = { ...filters, organizationId };\n }\n\n if (membersIds) {\n filters = {\n ...filters,\n membersIds: { $in: ensureArrayQueryFilter(membersIds) },\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, organizationId: organization?.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;AAsCA,MAAa,kCACX,QAGsC;CACtC,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAsD,GAAG;CAC3D,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAA0B,CAAC;CAC/B,IAAI,cAAsC,EAAE,WAAW,GAAG;CAE1D,MAAM,EACJ,MACA,QACA,KACA,gBACA,YACA,QACA,WACA,aACE,kBAAkB,CAAC;CAEvB,IAAI,KACF,UAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,GAAG,EAAE;CAAE;CAGpE,IAAI,MACF,UAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,GAAG;CAAE;CAGtD,IAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,GAAG;EAC1C,UAAU;GACR,GAAG;GACH,KAAK,CAAC,EAAE,MAAM,YAAY,CAAC;EAC7B;CACF;CAEA,IAAI,gBACF,UAAU;EAAE,GAAG;EAAS;CAAe;CAGzC,IAAI,YACF,UAAU;EACR,GAAG;EACH,YAAY,EAAE,KAAK,uBAAuB,UAAU,EAAE;CACxD;CAGF,IAAI,UAAU,cAAc,cAAc,SAAS,cAAc,SAC/D,cAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,GAAG;CAGzD,IAAI,EAAE,OAAO,SAAS,OAAO,KAAK,aAAa,SAC7C,UAAU;EAAE,GAAG;EAAS,gBAAgB,cAAc;CAAG;CAG3D,OAAO;EAAE;EAAS;EAAa,GAAG;CAAW;AAC/C"}
1
+ {"version":3,"file":"getProjectFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getProjectFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Project } from '@/types/project.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type ProjectFiltersParams = {\n ids?: string | string[];\n name?: string;\n search?: string;\n organizationId?: string;\n membersIds?: string[];\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all projects without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type ProjectFilters = QueryFilter<Project>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport type ProjectFiltersAndPaginationResult = {\n filters: ProjectFilters;\n sortOptions: Record<string, 1 | -1>;\n page: number;\n skip: number;\n pageSize: number;\n getNumberOfPages: (totalItems: number) => number;\n};\n\nexport const getProjectFiltersAndPagination = (\n req: FastifyRequest<{\n Querystring: FiltersAndPagination<ProjectFiltersParams>;\n }>\n): ProjectFiltersAndPaginationResult => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<ProjectFiltersParams>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters: ProjectFilters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n name,\n search,\n ids,\n organizationId,\n membersIds,\n sortBy,\n sortOrder,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [{ name: searchRegex }],\n };\n }\n\n if (organizationId) {\n filters = { ...filters, organizationId };\n }\n\n if (membersIds) {\n filters = {\n ...filters,\n membersIds: { $in: ensureArrayQueryFilter(membersIds) },\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, organizationId: organization?.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;AAsCA,MAAa,kCACX,QAGsC;CACtC,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAsD,IAAI;CAC5D,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAA0B,EAAE;CAChC,IAAI,cAAsC,EAAE,WAAW,IAAI;CAE3D,MAAM,EACJ,MACA,QACA,KACA,gBACA,YACA,QACA,WACA,aACE,kBAAkB,EAAE;AAExB,KAAI,IACF,WAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;EAAE;AAGrE,KAAI,KACF,WAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,IAAI;EAAE;AAGvD,KAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,IAAI;AAC3C,YAAU;GACR,GAAG;GACH,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;GAC7B;;AAGH,KAAI,eACF,WAAU;EAAE,GAAG;EAAS;EAAgB;AAG1C,KAAI,WACF,WAAU;EACR,GAAG;EACH,YAAY,EAAE,KAAK,uBAAuB,WAAW,EAAE;EACxD;AAGH,KAAI,UAAU,cAAc,cAAc,SAAS,cAAc,QAC/D,eAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,IAAI;AAG1D,KAAI,EAAE,OAAO,SAAS,QAAQ,IAAI,aAAa,QAC7C,WAAU;EAAE,GAAG;EAAS,gBAAgB,cAAc;EAAI;AAG5D,QAAO;EAAE;EAAS;EAAa,GAAG;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"getTagFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getTagFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Tag } from '@/types/tag.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type TagFiltersParams = {\n ids?: string | string[];\n keys?: string | string[];\n name?: string;\n search?: string;\n organizationId?: string;\n /**\n * For admin users, if true, will fetch all tags without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type TagFilters = QueryFilter<Tag>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getTagFiltersAndPagination = (\n req: FastifyRequest<{ Querystring: FiltersAndPagination<TagFiltersParams> }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<TagFiltersParams>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters: TagFilters = {};\n const sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const { name, search, ids, keys, organizationId, fetchAll } =\n filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (keys) {\n filters = { ...filters, key: { $in: ensureArrayQueryFilter(keys) } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { name: searchRegex },\n { key: searchRegex },\n { description: searchRegex },\n { instructions: searchRegex },\n ],\n };\n }\n\n if (organizationId) {\n filters = { ...filters, organizationId };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, organizationId: organization?.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;AA2BA,MAAa,8BACX,QACG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAkD,GAAG;CACvD,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAAsB,CAAC;CAC3B,MAAM,cAAsC,EAAE,WAAW,GAAG;CAE5D,MAAM,EAAE,MAAM,QAAQ,KAAK,MAAM,gBAAgB,aAC/C,kBAAkB,CAAC;CAErB,IAAI,KACF,UAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,GAAG,EAAE;CAAE;CAGpE,IAAI,MACF,UAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;CAAE;CAGrE,IAAI,MACF,UAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,GAAG;CAAE;CAGtD,IAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,GAAG;EAC1C,UAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,MAAM,YAAY;IACpB,EAAE,KAAK,YAAY;IACnB,EAAE,aAAa,YAAY;IAC3B,EAAE,cAAc,YAAY;GAC9B;EACF;CACF;CAEA,IAAI,gBACF,UAAU;EAAE,GAAG;EAAS;CAAe;CAGzC,IAAI,EAAE,OAAO,SAAS,OAAO,KAAK,aAAa,SAC7C,UAAU;EAAE,GAAG;EAAS,gBAAgB,cAAc;CAAG;CAG3D,OAAO;EAAE;EAAS;EAAa,GAAG;CAAW;AAC/C"}
1
+ {"version":3,"file":"getTagFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getTagFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { Tag } from '@/types/tag.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type TagFiltersParams = {\n ids?: string | string[];\n keys?: string | string[];\n name?: string;\n search?: string;\n organizationId?: string;\n /**\n * For admin users, if true, will fetch all tags without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type TagFilters = QueryFilter<Tag>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getTagFiltersAndPagination = (\n req: FastifyRequest<{ Querystring: FiltersAndPagination<TagFiltersParams> }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<TagFiltersParams>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters: TagFilters = {};\n const sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const { name, search, ids, keys, organizationId, fetchAll } =\n filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n }\n\n if (keys) {\n filters = { ...filters, key: { $in: ensureArrayQueryFilter(keys) } };\n }\n\n if (name) {\n filters = { ...filters, name: new RegExp(name, 'i') };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { name: searchRegex },\n { key: searchRegex },\n { description: searchRegex },\n { instructions: searchRegex },\n ],\n };\n }\n\n if (organizationId) {\n filters = { ...filters, organizationId };\n }\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n filters = { ...filters, organizationId: organization?.id };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;AA2BA,MAAa,8BACX,QACG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAkD,IAAI;CACxD,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAAsB,EAAE;CAC5B,MAAM,cAAsC,EAAE,WAAW,IAAI;CAE7D,MAAM,EAAE,MAAM,QAAQ,KAAK,MAAM,gBAAgB,aAC/C,kBAAkB,EAAE;AAEtB,KAAI,IACF,WAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;EAAE;AAGrE,KAAI,KACF,WAAU;EAAE,GAAG;EAAS,KAAK,EAAE,KAAK,uBAAuB,KAAK,EAAE;EAAE;AAGtE,KAAI,KACF,WAAU;EAAE,GAAG;EAAS,MAAM,IAAI,OAAO,MAAM,IAAI;EAAE;AAGvD,KAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,IAAI;AAC3C,YAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,MAAM,aAAa;IACrB,EAAE,KAAK,aAAa;IACpB,EAAE,aAAa,aAAa;IAC5B,EAAE,cAAc,aAAa;IAC9B;GACF;;AAGH,KAAI,eACF,WAAU;EAAE,GAAG;EAAS;EAAgB;AAG1C,KAAI,EAAE,OAAO,SAAS,QAAQ,IAAI,aAAa,QAC7C,WAAU;EAAE,GAAG;EAAS,gBAAgB,cAAc;EAAI;AAG5D,QAAO;EAAE;EAAS;EAAa,GAAG;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"getUserFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getUserFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { User } from '@/types/user.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type UserFiltersParam = {\n ids?: string | string[];\n firstName?: string;\n lastName?: string;\n email?: string;\n emailVerified?: string;\n role?: string;\n search?: string;\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all users without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type UserFilters = QueryFilter<User>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getUserFiltersAndPagination = (\n req: FastifyRequest<{ Querystring: FiltersAndPagination<UserFiltersParam> }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<UserFiltersParam>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n firstName,\n lastName,\n email,\n emailVerified,\n role,\n search,\n sortBy,\n sortOrder,\n ids,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n const requestedIds = ensureArrayQueryFilter(ids) ?? [];\n\n // Build the set of IDs the requester is allowed to fetch:\n // 1. Always allow fetching themselves.\n // 2. Allow fetching any member of their active organization.\n const currentUserId = req.session?.user?.id\n ? String(req.session.user.id)\n : null;\n const orgMemberIds: string[] =\n organization?.membersIds?.map(String) ?? [];\n\n const allowedIds = requestedIds.filter(\n (id) =>\n (currentUserId && id === currentUserId) || orgMemberIds.includes(id)\n );\n\n filters = {\n ...filters,\n _id: {\n $in: allowedIds,\n },\n };\n }\n }\n\n if (firstName) {\n filters = { ...filters, firstName: new RegExp(firstName, 'i') };\n }\n\n if (lastName) {\n filters = { ...filters, lastName: new RegExp(lastName, 'i') };\n }\n\n if (email) {\n filters = { ...filters, email: new RegExp(email, 'i') };\n }\n\n if (emailVerified !== undefined) {\n const isVerified = emailVerified === 'true';\n filters = { ...filters, emailVerified: isVerified };\n }\n\n if (role) {\n filters = { ...filters, role };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { firstName: searchRegex },\n { lastName: searchRegex },\n { email: searchRegex },\n { name: searchRegex },\n ],\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;AA+BA,MAAa,+BACX,QACG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAkD,GAAG;CACvD,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAAU,CAAC;CACf,IAAI,cAAsC,EAAE,WAAW,GAAG;CAE1D,MAAM,EACJ,WACA,UACA,OACA,eACA,MACA,QACA,QACA,WACA,KACA,aACE,kBAAkB,CAAC;CAEvB,IAAI,KAAK;EACP,UAAU;GAAE,GAAG;GAAS,KAAK,EAAE,KAAK,uBAAuB,GAAG,EAAE;EAAE;EAElE,IAAI,EAAE,OAAO,SAAS,OAAO,KAAK,aAAa,SAAS;GACtD,MAAM,eAAe,uBAAuB,GAAG,KAAK,CAAC;GAKrD,MAAM,gBAAgB,IAAI,SAAS,MAAM,KACrC,OAAO,IAAI,QAAQ,KAAK,EAAE,IAC1B;GACJ,MAAM,eACJ,cAAc,YAAY,IAAI,MAAM,KAAK,CAAC;GAE5C,MAAM,aAAa,aAAa,QAC7B,OACE,iBAAiB,OAAO,iBAAkB,aAAa,SAAS,EAAE,CACvE;GAEA,UAAU;IACR,GAAG;IACH,KAAK,EACH,KAAK,WACP;GACF;EACF;CACF;CAEA,IAAI,WACF,UAAU;EAAE,GAAG;EAAS,WAAW,IAAI,OAAO,WAAW,GAAG;CAAE;CAGhE,IAAI,UACF,UAAU;EAAE,GAAG;EAAS,UAAU,IAAI,OAAO,UAAU,GAAG;CAAE;CAG9D,IAAI,OACF,UAAU;EAAE,GAAG;EAAS,OAAO,IAAI,OAAO,OAAO,GAAG;CAAE;CAGxD,IAAI,kBAAkB,QAAW;EAC/B,MAAM,aAAa,kBAAkB;EACrC,UAAU;GAAE,GAAG;GAAS,eAAe;EAAW;CACpD;CAEA,IAAI,MACF,UAAU;EAAE,GAAG;EAAS;CAAK;CAG/B,IAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,GAAG;EAC1C,UAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,WAAW,YAAY;IACzB,EAAE,UAAU,YAAY;IACxB,EAAE,OAAO,YAAY;IACrB,EAAE,MAAM,YAAY;GACtB;EACF;CACF;CAEA,IAAI,UAAU,cAAc,cAAc,SAAS,cAAc,SAC/D,cAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,GAAG;CAGzD,OAAO;EAAE;EAAS;EAAa,GAAG;CAAW;AAC/C"}
1
+ {"version":3,"file":"getUserFiltersAndPagination.mjs","names":[],"sources":["../../../../src/utils/filtersAndPagination/getUserFiltersAndPagination.ts"],"sourcesContent":["import { ensureArrayQueryFilter } from '@utils/ensureArrayQueryFilter';\nimport type { FastifyRequest } from 'fastify';\nimport type { QueryFilter } from 'mongoose';\nimport type { User } from '@/types/user.types';\nimport {\n type FiltersAndPagination,\n getFiltersAndPaginationFromBody,\n} from './getFiltersAndPaginationFromBody';\n\nexport type UserFiltersParam = {\n ids?: string | string[];\n firstName?: string;\n lastName?: string;\n email?: string;\n emailVerified?: string;\n role?: string;\n search?: string;\n sortBy?: string;\n sortOrder?: string;\n /**\n * For admin users, if true, will fetch all users without filtering by organization\n */\n fetchAll?: 'true' | 'false';\n};\nexport type UserFilters = QueryFilter<User>;\n\n/**\n * Extracts filters and pagination information from the request body.\n * @param req - Fastify request object.\n * @returns Object containing filters, page, pageSize, and getNumberOfPages functions.\n */\nexport const getUserFiltersAndPagination = (\n req: FastifyRequest<{ Querystring: FiltersAndPagination<UserFiltersParam> }>\n) => {\n const { filters: filtersRequest, ...pagination } =\n getFiltersAndPaginationFromBody<UserFiltersParam>(req);\n const roles = req.session?.roles;\n const organization = req.session?.organization;\n\n let filters = {};\n let sortOptions: Record<string, 1 | -1> = { updatedAt: -1 };\n\n const {\n firstName,\n lastName,\n email,\n emailVerified,\n role,\n search,\n sortBy,\n sortOrder,\n ids,\n fetchAll,\n } = filtersRequest ?? {};\n\n if (ids) {\n filters = { ...filters, _id: { $in: ensureArrayQueryFilter(ids) } };\n\n if (!(roles?.includes('admin') && fetchAll === 'true')) {\n const requestedIds = ensureArrayQueryFilter(ids) ?? [];\n\n // Build the set of IDs the requester is allowed to fetch:\n // 1. Always allow fetching themselves.\n // 2. Allow fetching any member of their active organization.\n const currentUserId = req.session?.user?.id\n ? String(req.session.user.id)\n : null;\n const orgMemberIds: string[] =\n organization?.membersIds?.map(String) ?? [];\n\n const allowedIds = requestedIds.filter(\n (id) =>\n (currentUserId && id === currentUserId) || orgMemberIds.includes(id)\n );\n\n filters = {\n ...filters,\n _id: {\n $in: allowedIds,\n },\n };\n }\n }\n\n if (firstName) {\n filters = { ...filters, firstName: new RegExp(firstName, 'i') };\n }\n\n if (lastName) {\n filters = { ...filters, lastName: new RegExp(lastName, 'i') };\n }\n\n if (email) {\n filters = { ...filters, email: new RegExp(email, 'i') };\n }\n\n if (emailVerified !== undefined) {\n const isVerified = emailVerified === 'true';\n filters = { ...filters, emailVerified: isVerified };\n }\n\n if (role) {\n filters = { ...filters, role };\n }\n\n if (search) {\n const searchRegex = new RegExp(search, 'i');\n filters = {\n ...filters,\n $or: [\n { firstName: searchRegex },\n { lastName: searchRegex },\n { email: searchRegex },\n { name: searchRegex },\n ],\n };\n }\n\n if (sortBy && sortOrder && (sortOrder === 'asc' || sortOrder === 'desc')) {\n sortOptions = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };\n }\n\n return { filters, sortOptions, ...pagination };\n};\n"],"mappings":";;;;;;;;;AA+BA,MAAa,+BACX,QACG;CACH,MAAM,EAAE,SAAS,gBAAgB,GAAG,eAClC,gCAAkD,IAAI;CACxD,MAAM,QAAQ,IAAI,SAAS;CAC3B,MAAM,eAAe,IAAI,SAAS;CAElC,IAAI,UAAU,EAAE;CAChB,IAAI,cAAsC,EAAE,WAAW,IAAI;CAE3D,MAAM,EACJ,WACA,UACA,OACA,eACA,MACA,QACA,QACA,WACA,KACA,aACE,kBAAkB,EAAE;AAExB,KAAI,KAAK;AACP,YAAU;GAAE,GAAG;GAAS,KAAK,EAAE,KAAK,uBAAuB,IAAI,EAAE;GAAE;AAEnE,MAAI,EAAE,OAAO,SAAS,QAAQ,IAAI,aAAa,SAAS;GACtD,MAAM,eAAe,uBAAuB,IAAI,IAAI,EAAE;GAKtD,MAAM,gBAAgB,IAAI,SAAS,MAAM,KACrC,OAAO,IAAI,QAAQ,KAAK,GAAG,GAC3B;GACJ,MAAM,eACJ,cAAc,YAAY,IAAI,OAAO,IAAI,EAAE;GAE7C,MAAM,aAAa,aAAa,QAC7B,OACE,iBAAiB,OAAO,iBAAkB,aAAa,SAAS,GAAG,CACvE;AAED,aAAU;IACR,GAAG;IACH,KAAK,EACH,KAAK,YACN;IACF;;;AAIL,KAAI,UACF,WAAU;EAAE,GAAG;EAAS,WAAW,IAAI,OAAO,WAAW,IAAI;EAAE;AAGjE,KAAI,SACF,WAAU;EAAE,GAAG;EAAS,UAAU,IAAI,OAAO,UAAU,IAAI;EAAE;AAG/D,KAAI,MACF,WAAU;EAAE,GAAG;EAAS,OAAO,IAAI,OAAO,OAAO,IAAI;EAAE;AAGzD,KAAI,kBAAkB,QAAW;EAC/B,MAAM,aAAa,kBAAkB;AACrC,YAAU;GAAE,GAAG;GAAS,eAAe;GAAY;;AAGrD,KAAI,KACF,WAAU;EAAE,GAAG;EAAS;EAAM;AAGhC,KAAI,QAAQ;EACV,MAAM,cAAc,IAAI,OAAO,QAAQ,IAAI;AAC3C,YAAU;GACR,GAAG;GACH,KAAK;IACH,EAAE,WAAW,aAAa;IAC1B,EAAE,UAAU,aAAa;IACzB,EAAE,OAAO,aAAa;IACtB,EAAE,MAAM,aAAa;IACtB;GACF;;AAGH,KAAI,UAAU,cAAc,cAAc,SAAS,cAAc,QAC/D,eAAc,GAAG,SAAS,cAAc,QAAQ,IAAI,IAAI;AAG1D,QAAO;EAAE;EAAS;EAAa,GAAG;EAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFaviconUrl.mjs","names":[],"sources":["../../../src/utils/getFaviconUrl.ts"],"sourcesContent":["/**\n * Returns the Google Favicon service URL for a given project URL.\n */\nexport const getFaviconUrl = (url: string): string | null => {\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}`;\n } catch {\n return null;\n }\n};\n"],"mappings":";;;;AAGA,MAAa,iBAAiB,QAA+B;CAC3D,IAAI;EAEF,OAAO,6CADQ,IAAI,IAAI,GAAG,CAAC,CAAC;CAE9B,QAAQ;EACN,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"getFaviconUrl.mjs","names":[],"sources":["../../../src/utils/getFaviconUrl.ts"],"sourcesContent":["/**\n * Returns the Google Favicon service URL for a given project URL.\n */\nexport const getFaviconUrl = (url: string): string | null => {\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}`;\n } catch {\n return null;\n }\n};\n"],"mappings":";;;;AAGA,MAAa,iBAAiB,QAA+B;AAC3D,KAAI;AAEF,SAAO,6CADQ,IAAI,IAAI,IAAI,CAAC;SAEtB;AACN,SAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"connectGithub.mjs","names":[],"sources":["../../../../src/utils/github/connectGithub.ts"],"sourcesContent":["import { Octokit } from '@octokit/rest';\n\nlet githubClientInstance: Octokit | null = null;\n\nexport const connectGithub = async (): Promise<Octokit> => {\n try {\n githubClientInstance = new Octokit({\n auth: process.env.GITHUB_TOKEN,\n headers: {\n 'X-GitHub-Api-Version': '2026-03-10',\n },\n });\n return githubClientInstance;\n } catch (error) {\n const errorMessage = `Github connection error - ${(error as Error).message}`;\n throw new Error(errorMessage);\n }\n};\n\nexport const getGithubClient = (): Octokit => {\n if (!githubClientInstance) {\n githubClientInstance = new Octokit({\n auth: process.env.GITHUB_TOKEN,\n headers: {\n 'X-GitHub-Api-Version': '2026-03-10',\n },\n });\n }\n return githubClientInstance;\n};\n"],"mappings":";;;AAEA,IAAI,uBAAuC;AAE3C,MAAa,gBAAgB,YAA8B;CACzD,IAAI;EACF,uBAAuB,IAAI,QAAQ;GACjC,MAAM,QAAQ,IAAI;GAClB,SAAS,EACP,wBAAwB,aAC1B;EACF,CAAC;EACD,OAAO;CACT,SAAS,OAAO;EACd,MAAM,eAAe,6BAA8B,MAAgB;EACnE,MAAM,IAAI,MAAM,YAAY;CAC9B;AACF;AAEA,MAAa,wBAAiC;CAC5C,IAAI,CAAC,sBACH,uBAAuB,IAAI,QAAQ;EACjC,MAAM,QAAQ,IAAI;EAClB,SAAS,EACP,wBAAwB,aAC1B;CACF,CAAC;CAEH,OAAO;AACT"}
1
+ {"version":3,"file":"connectGithub.mjs","names":[],"sources":["../../../../src/utils/github/connectGithub.ts"],"sourcesContent":["import { Octokit } from '@octokit/rest';\n\nlet githubClientInstance: Octokit | null = null;\n\nexport const connectGithub = async (): Promise<Octokit> => {\n try {\n githubClientInstance = new Octokit({\n auth: process.env.GITHUB_TOKEN,\n headers: {\n 'X-GitHub-Api-Version': '2026-03-10',\n },\n });\n return githubClientInstance;\n } catch (error) {\n const errorMessage = `Github connection error - ${(error as Error).message}`;\n throw new Error(errorMessage);\n }\n};\n\nexport const getGithubClient = (): Octokit => {\n if (!githubClientInstance) {\n githubClientInstance = new Octokit({\n auth: process.env.GITHUB_TOKEN,\n headers: {\n 'X-GitHub-Api-Version': '2026-03-10',\n },\n });\n }\n return githubClientInstance;\n};\n"],"mappings":";;;AAEA,IAAI,uBAAuC;AAE3C,MAAa,gBAAgB,YAA8B;AACzD,KAAI;AACF,yBAAuB,IAAI,QAAQ;GACjC,MAAM,QAAQ,IAAI;GAClB,SAAS,EACP,wBAAwB,cACzB;GACF,CAAC;AACF,SAAO;UACA,OAAO;EACd,MAAM,eAAe,6BAA8B,MAAgB;AACnE,QAAM,IAAI,MAAM,aAAa;;;AAIjC,MAAa,wBAAiC;AAC5C,KAAI,CAAC,qBACH,wBAAuB,IAAI,QAAQ;EACjC,MAAM,QAAQ,IAAI;EAClB,SAAS,EACP,wBAAwB,cACzB;EACF,CAAC;AAEJ,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"httpStatusCodes.mjs","names":[],"sources":["../../../src/utils/httpStatusCodes.ts"],"sourcesContent":["/**\n * Enum for HTTP response status codes.\n * Contains all the possible HTTP response codes according to the standard.\n *\n *\n * 1xx: Informational responses\n *\n *\n * 100 - CONTINUE - The server has received the request headers and the client should proceed to send the request body.\n *\n * 101 - SWITCHING_PROTOCOLS - The requester has asked the server to switch protocols and the server has agreed to do so.\n *\n * 102 - PROCESSING - Used to return some response headers before final HTTP message.\n *\n * 103 - EARLY_HINTS - Early hints - part of optimization to improve page load time.\n *\n *\n * 2xx: Successful responses\n *\n *\n * 200 - OK - The request has succeeded.\n *\n * 201 - CREATED - The request has been fulfilled and has resulted in one or more new resources being created.\n *\n * 202 - ACCEPTED - The request has been accepted for processing, but the processing has not been completed.\n *\n * 203 - NON_AUTHORITATIVE_INFORMATION - The server successfully processed the request, but is returning information that may be from another source.\n *\n * 204 - NO_CONTENT - The server successfully processed the request and is not returning any content.\n *\n * 205 - RESET_CONTENT - The server successfully processed the request, but is not returning any content and requires that the requester reset the document view.\n *\n * 206 - PARTIAL_CONTENT - The server is delivering only part of the resource due to a range header sent by the client.\n *\n * 207 - MULTI_STATUS - Multi-status response providing status for multiple independent operations.\n *\n * 208 - ALREADY_REPORTED - The members of a DAV binding have already been enumerated in a preceding part of the request.\n *\n * 226 - IM_USED - The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance manipulations applied to the current instance.\n *\n *\n * 3xx: Redirection messages\n *\n *\n * 300 - MULTIPLE_CHOICES - The request has more than one possible response. The user-agent or user should choose one of them.\n *\n * 301 - MOVED_PERMANENTLY - The URL of the requested resource has been changed permanently.\n *\n * 302 - FOUND - The requested resource is available at a different URI.\n *\n * 303 - SEE_OTHER - The response to the request can be found under another URI using a GET method.\n *\n * 304 - NOT_MODIFIED - Indicates that the resource has not been modified since the version specified by the request headers.\n *\n * 305 - USE_PROXY - The requested resource must be accessed through the proxy given by the Location field.\n *\n * 306 - SWITCH_PROXY - No longer used. Originally meant to direct the client to switch to a different proxy.\n *\n * 307 - TEMPORARY_REDIRECT - The requested resource resides temporarily under a different URI.\n *\n * 308 - PERMANENT_REDIRECT - The request should be repeated with another URI, but future requests should still use the original URI.\n *\n *\n * 4xx: Client error responses\n *\n *\n * 400 - BAD_REQUEST - The server cannot or will not process the request due to something perceived to be a client error.\n *\n * 401 - UNAUTHORIZED - The client must authenticate itself to get the requested response.\n *\n * 403 - FORBIDDEN - The client does not have access rights to the content.\n *\n * 404 - NOT_FOUND - The server can not find the requested resource.\n *\n * 405 - METHOD_NOT_ALLOWED - The request method is known by the server but is not supported by the target resource.\n *\n * 406 - NOT_ACCEPTABLE - This response is sent when the requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.\n *\n * 407 - PROXY_AUTHENTICATION_REQUIRED - This is similar to 401 but authentication is needed to be done by a proxy.\n *\n * 408 - REQUEST_TIMEOUT - This response is sent on an idle connection by some servers, even without any previous request by the client.\n *\n * 409 - CONFLICT - This response is sent when a request conflicts with the current state of the server.\n *\n * 410 - GONE - This response is sent when the requested resource is no longer available and will not be available again.\n *\n * 411 - LENGTH_REQUIRED - The request did not specify the length of its content, which is required by the requested resource.\n *\n * 412 - PRECONDITION_FAILED - The server does not meet one of the preconditions that the requester put on the request.\n *\n * 413 - PAYLOAD_TOO_LARGE - The request is larger than the server is willing or able to process.\n *\n * 414 - URI_TOO_LONG - The URI requested by the client is longer than the server is willing to interpret.\n *\n * 415 - UNSUPPORTED_MEDIA_TYPE - The media format of the requested data is not supported by the server.\n *\n * 416 - RANGE_NOT_SATISFIABLE - The range specified by the Range header field in the request can't be fulfilled.\n *\n * 417 - EXPECTATION_FAILED - The expectation indicated by the Expect request header field can't be met by the server.\n *\n * 418 - IM_A_TEAPOT - The server refuses the attempt to brew coffee with a teapot.\n *\n * 421 - MISDIRECTED_REQUEST - The request was directed at a server that is not able to produce a response.\n *\n * 422 - UNPROCESSABLE_ENTITY - The request was well-formed but was unable to be followed due to semantic errors.\n *\n * 423 - LOCKED - The resource that is being accessed is locked.\n *\n * 424 - FAILED_DEPENDENCY - The request failed due to failure of a previous request.\n *\n * 425 - TOO_EARLY - Indicates that the server is unwilling to risk processing a request that might be replayed.\n *\n * 426 - UPGRADE_REQUIRED - The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.\n *\n * 428 - PRECONDITION_REQUIRED - The origin server requires the request to be conditional.\n *\n * 429 - TOO_MANY_REQUESTS - The user has sent too many requests in a given amount of time.\n *\n * 431 - REQUEST_HEADER_FIELDS_TOO_LARGE - The server is unwilling to process the request because its header fields are too large.\n *\n * 451 - UNAVAILABLE_FOR_LEGAL_REASONS - The user-agent requested a resource that cannot legally be provided, such as a censored resource.\n *\n *\n * 5xx: Server error responses\n *\n *\n * 500 - INTERNAL_SERVER_ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.\n *\n * 501 - NOT_IMPLEMENTED - The server does not support the functionality required to fulfill the request.\n *\n * 502 - BAD_GATEWAY - The server, while acting as a gateway or proxy, received an invalid response from the upstream server.\n *\n * 503 - SERVICE_UNAVAILABLE - The server is currently unavailable (because it is overloaded or down for maintenance).\n *\n * 504 - GATEWAY_TIMEOUT - The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.\n *\n * 505 - HTTP_VERSION_NOT_SUPPORTED - The server does not support the HTTP protocol version used in the request.\n *\n * 506 - VARIANT_ALSO_NEGOTIATES - The server has an internal configuration error, such as a misconfigured gateway.\n *\n * 507 - INSUFFICIENT_STORAGE - The server is unable to store the representation needed to complete the request.\n *\n * 508 - LOOP_DETECTED - The server detected an infinite loop while processing a request.\n */\nexport enum HttpStatusCodes {\n //* ********************************\n // 1xx: Informational responses\n //* ********************************\n\n /**\n * The server has received the request headers and the client should proceed to send the request body.\n */\n CONTINUE_100 = 100,\n\n /**\n * The requester has asked the server to switch protocols and the server has agreed to do so.\n */\n SWITCHING_PROTOCOLS_101 = 101,\n\n /**\n * Used to return some response headers before final HTTP message.\n */\n PROCESSING_102 = 102, // WebDAV\n\n /**\n * Early hints - part of optimization to improve page load time.\n */\n EARLY_HINTS_103 = 103,\n\n //* ********************************\n // 2xx: Successful responses\n //* ********************************\n\n /**\n * The request has succeeded.\n */\n OK_200 = 200,\n\n /**\n * The request has been fulfilled and has resulted in one or more new resources being created.\n */\n CREATED_201 = 201,\n\n /**\n * The request has been accepted for processing, but the processing has not been completed.\n */\n ACCEPTED_202 = 202,\n\n /**\n * The server successfully processed the request, but is returning information that may be from another source.\n */\n NON_AUTHORITATIVE_INFORMATION_203 = 203,\n\n /**\n * The server successfully processed the request and is not returning any content.\n */\n NO_CONTENT_204 = 204,\n\n /**\n * The server successfully processed the request, but is not returning any content and requires that the requester reset the document view.\n */\n RESET_CONTENT_205 = 205,\n\n /**\n * The server is delivering only part of the resource due to a range header sent by the client.\n */\n PARTIAL_CONTENT_206 = 206,\n\n /**\n * Multi-status response providing status for multiple independent operations.\n */\n MULTI_STATUS_207 = 207, // WebDAV\n\n /**\n * The members of a DAV binding have already been enumerated in a preceding part of the request.\n */\n ALREADY_REPORTED_208 = 208, // WebDAV\n\n /**\n * The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance manipulations applied to the current instance.\n */\n IM_USED_226 = 226,\n\n //* ********************************\n // 3xx: Redirection messages\n //* ********************************\n\n /**\n * The request has more than one possible response. The user-agent or user should choose one of them.\n */\n MULTIPLE_CHOICES_300 = 300,\n\n /**\n * The URL of the requested resource has been changed permanently.\n */\n MOVED_PERMANENTLY_301 = 301,\n\n /**\n * The requested resource is available at a different URI.\n */\n FOUND_302 = 302,\n\n /**\n * The response to the request can be found under another URI using a GET method.\n */\n SEE_OTHER_303 = 303,\n\n /**\n * Indicates that the resource has not been modified since the version specified by the request headers.\n */\n NOT_MODIFIED_304 = 304,\n\n /**\n * The requested resource must be accessed through the proxy given by the Location field.\n */\n USE_PROXY_305 = 305,\n\n /**\n * No longer used. Originally meant to direct the client to switch to a different proxy.\n */\n SWITCH_PROXY_306 = 306,\n\n /**\n * The requested resource resides temporarily under a different URI.\n */\n TEMPORARY_REDIRECT_307 = 307,\n\n /**\n * The request should be repeated with another URI, but future requests should still use the original URI.\n */\n PERMANENT_REDIRECT_308 = 308,\n\n //* ********************************\n // 4xx: Client error responses\n //* ********************************\n\n /**\n * The server cannot or will not process the request due to something perceived to be a client error.\n */\n BAD_REQUEST_400 = 400,\n\n /**\n * The client must authenticate itself to get the requested response.\n */\n UNAUTHORIZED_401 = 401,\n\n /**\n * The client does not have access rights to the content.\n */\n FORBIDDEN_403 = 403,\n\n /**\n * The server can not find the requested resource.\n */\n NOT_FOUND_404 = 404,\n\n /**\n * The request method is known by the server but is not supported by the target resource.\n */\n METHOD_NOT_ALLOWED_405 = 405,\n\n /**\n * This response is sent when the requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.\n */\n NOT_ACCEPTABLE_406 = 406,\n\n /**\n * This is similar to 401 but authentication is needed to be done by a proxy.\n */\n PROXY_AUTHENTICATION_REQUIRED_407 = 407,\n\n /**\n * This response is sent on an idle connection by some servers, even without any previous request by the client.\n */\n REQUEST_TIMEOUT_408 = 408,\n\n /**\n * This response is sent when a request conflicts with the current state of the server.\n */\n CONFLICT_409 = 409,\n\n /**\n * This response is sent when the requested resource is no longer available and will not be available again.\n */\n GONE_410 = 410,\n\n /**\n * The request did not specify the length of its content, which is required by the requested resource.\n */\n LENGTH_REQUIRED_411 = 411,\n\n /**\n * The server does not meet one of the preconditions that the requester put on the request.\n */\n PRECONDITION_FAILED_412 = 412,\n\n /**\n * The request is larger than the server is willing or able to process.\n */\n PAYLOAD_TOO_LARGE_413 = 413,\n\n /**\n * The URI requested by the client is longer than the server is willing to interpret.\n */\n URI_TOO_LONG_414 = 414,\n\n /**\n * The media format of the requested data is not supported by the server.\n */\n UNSUPPORTED_MEDIA_TYPE_415 = 415,\n\n /**\n * The range specified by the Range header field in the request can't be fulfilled.\n */\n RANGE_NOT_SATISFIABLE_416 = 416,\n\n /**\n * The expectation indicated by the Expect request header field can't be met by the server.\n */\n EXPECTATION_FAILED_417 = 417,\n\n /**\n * The server refuses the attempt to brew coffee with a teapot.\n */\n IM_A_TEAPOT_418 = 418, // Easter egg from the HTCPCP/1.0 protocol.\n\n /**\n * The request was directed at a server that is not able to produce a response.\n */\n MISDIRECTED_REQUEST_421 = 421,\n\n /**\n * The request was well-formed but was unable to be followed due to semantic errors.\n */\n UNPROCESSABLE_ENTITY_422 = 422, // WebDAV\n\n /**\n * The resource that is being accessed is locked.\n */\n LOCKED_423 = 423, // WebDAV\n\n /**\n * The request failed due to failure of a previous request.\n */\n FAILED_DEPENDENCY_424 = 424, // WebDAV\n\n /**\n * Indicates that the server is unwilling to risk processing a request that might be replayed.\n */\n TOO_EARLY_425 = 425,\n\n /**\n * The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.\n */\n UPGRADE_REQUIRED_426 = 426,\n\n /**\n * The origin server requires the request to be conditional.\n */\n PRECONDITION_REQUIRED_428 = 428,\n\n /**\n * The user has sent too many requests in a given amount of time.\n */\n TOO_MANY_REQUESTS_429 = 429,\n\n /**\n * The server is unwilling to process the request because its header fields are too large.\n */\n REQUEST_HEADER_FIELDS_TOO_LARGE_431 = 431,\n\n /**\n * The user-agent requested a resource that cannot legally be provided, such as a censored resource.\n */\n UNAVAILABLE_FOR_LEGAL_REASONS_451 = 451,\n\n //* ********************************\n // 5xx: Server error responses\n //* ********************************\n\n /**\n * The server encountered an unexpected condition that prevented it from fulfilling the request.\n */\n INTERNAL_SERVER_ERROR_500 = 500,\n\n /**\n * The server does not support the functionality required to fulfill the request.\n */\n NOT_IMPLEMENTED_501 = 501,\n\n /**\n * The server, while acting as a gateway or proxy, received an invalid response from the upstream server.\n */\n BAD_GATEWAY_502 = 502,\n\n /**\n * The server is currently unavailable (because it is overloaded or down for maintenance).\n */\n SERVICE_UNAVAILABLE_503 = 503,\n\n /**\n * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.\n */\n GATEWAY_TIMEOUT_504 = 504,\n\n /**\n * The server does not support the HTTP protocol version used in the request.\n */\n HTTP_VERSION_NOT_SUPPORTED_505 = 505,\n\n /**\n * The server has an internal configuration error, such as a misconfigured gateway.\n */\n VARIANT_ALSO_NEGOTIATES_506 = 506,\n\n /**\n * The server is unable to store the representation needed to complete the request.\n */\n INSUFFICIENT_STORAGE_507 = 507, // WebDAV\n\n /**\n * The server detected an infinite loop while processing a request.\n */\n LOOP_DETECTED_508 = 508, // WebDAV\n\n /**\n * Further extensions to the request are required for the server to fulfill it.\n */\n NOT_EXTENDED_510 = 510,\n\n /**\n * The client needs to authenticate to gain network access.\n */\n NETWORK_AUTHENTICATION_REQUIRED_511 = 511,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgJA,IAAY,kBAAL;;;;CAQL;;;;CAKA;;;;CAKA;;;;CAKA;;;;CASA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CASA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CASA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CASA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;AACF"}
1
+ {"version":3,"file":"httpStatusCodes.mjs","names":[],"sources":["../../../src/utils/httpStatusCodes.ts"],"sourcesContent":["/**\n * Enum for HTTP response status codes.\n * Contains all the possible HTTP response codes according to the standard.\n *\n *\n * 1xx: Informational responses\n *\n *\n * 100 - CONTINUE - The server has received the request headers and the client should proceed to send the request body.\n *\n * 101 - SWITCHING_PROTOCOLS - The requester has asked the server to switch protocols and the server has agreed to do so.\n *\n * 102 - PROCESSING - Used to return some response headers before final HTTP message.\n *\n * 103 - EARLY_HINTS - Early hints - part of optimization to improve page load time.\n *\n *\n * 2xx: Successful responses\n *\n *\n * 200 - OK - The request has succeeded.\n *\n * 201 - CREATED - The request has been fulfilled and has resulted in one or more new resources being created.\n *\n * 202 - ACCEPTED - The request has been accepted for processing, but the processing has not been completed.\n *\n * 203 - NON_AUTHORITATIVE_INFORMATION - The server successfully processed the request, but is returning information that may be from another source.\n *\n * 204 - NO_CONTENT - The server successfully processed the request and is not returning any content.\n *\n * 205 - RESET_CONTENT - The server successfully processed the request, but is not returning any content and requires that the requester reset the document view.\n *\n * 206 - PARTIAL_CONTENT - The server is delivering only part of the resource due to a range header sent by the client.\n *\n * 207 - MULTI_STATUS - Multi-status response providing status for multiple independent operations.\n *\n * 208 - ALREADY_REPORTED - The members of a DAV binding have already been enumerated in a preceding part of the request.\n *\n * 226 - IM_USED - The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance manipulations applied to the current instance.\n *\n *\n * 3xx: Redirection messages\n *\n *\n * 300 - MULTIPLE_CHOICES - The request has more than one possible response. The user-agent or user should choose one of them.\n *\n * 301 - MOVED_PERMANENTLY - The URL of the requested resource has been changed permanently.\n *\n * 302 - FOUND - The requested resource is available at a different URI.\n *\n * 303 - SEE_OTHER - The response to the request can be found under another URI using a GET method.\n *\n * 304 - NOT_MODIFIED - Indicates that the resource has not been modified since the version specified by the request headers.\n *\n * 305 - USE_PROXY - The requested resource must be accessed through the proxy given by the Location field.\n *\n * 306 - SWITCH_PROXY - No longer used. Originally meant to direct the client to switch to a different proxy.\n *\n * 307 - TEMPORARY_REDIRECT - The requested resource resides temporarily under a different URI.\n *\n * 308 - PERMANENT_REDIRECT - The request should be repeated with another URI, but future requests should still use the original URI.\n *\n *\n * 4xx: Client error responses\n *\n *\n * 400 - BAD_REQUEST - The server cannot or will not process the request due to something perceived to be a client error.\n *\n * 401 - UNAUTHORIZED - The client must authenticate itself to get the requested response.\n *\n * 403 - FORBIDDEN - The client does not have access rights to the content.\n *\n * 404 - NOT_FOUND - The server can not find the requested resource.\n *\n * 405 - METHOD_NOT_ALLOWED - The request method is known by the server but is not supported by the target resource.\n *\n * 406 - NOT_ACCEPTABLE - This response is sent when the requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.\n *\n * 407 - PROXY_AUTHENTICATION_REQUIRED - This is similar to 401 but authentication is needed to be done by a proxy.\n *\n * 408 - REQUEST_TIMEOUT - This response is sent on an idle connection by some servers, even without any previous request by the client.\n *\n * 409 - CONFLICT - This response is sent when a request conflicts with the current state of the server.\n *\n * 410 - GONE - This response is sent when the requested resource is no longer available and will not be available again.\n *\n * 411 - LENGTH_REQUIRED - The request did not specify the length of its content, which is required by the requested resource.\n *\n * 412 - PRECONDITION_FAILED - The server does not meet one of the preconditions that the requester put on the request.\n *\n * 413 - PAYLOAD_TOO_LARGE - The request is larger than the server is willing or able to process.\n *\n * 414 - URI_TOO_LONG - The URI requested by the client is longer than the server is willing to interpret.\n *\n * 415 - UNSUPPORTED_MEDIA_TYPE - The media format of the requested data is not supported by the server.\n *\n * 416 - RANGE_NOT_SATISFIABLE - The range specified by the Range header field in the request can't be fulfilled.\n *\n * 417 - EXPECTATION_FAILED - The expectation indicated by the Expect request header field can't be met by the server.\n *\n * 418 - IM_A_TEAPOT - The server refuses the attempt to brew coffee with a teapot.\n *\n * 421 - MISDIRECTED_REQUEST - The request was directed at a server that is not able to produce a response.\n *\n * 422 - UNPROCESSABLE_ENTITY - The request was well-formed but was unable to be followed due to semantic errors.\n *\n * 423 - LOCKED - The resource that is being accessed is locked.\n *\n * 424 - FAILED_DEPENDENCY - The request failed due to failure of a previous request.\n *\n * 425 - TOO_EARLY - Indicates that the server is unwilling to risk processing a request that might be replayed.\n *\n * 426 - UPGRADE_REQUIRED - The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.\n *\n * 428 - PRECONDITION_REQUIRED - The origin server requires the request to be conditional.\n *\n * 429 - TOO_MANY_REQUESTS - The user has sent too many requests in a given amount of time.\n *\n * 431 - REQUEST_HEADER_FIELDS_TOO_LARGE - The server is unwilling to process the request because its header fields are too large.\n *\n * 451 - UNAVAILABLE_FOR_LEGAL_REASONS - The user-agent requested a resource that cannot legally be provided, such as a censored resource.\n *\n *\n * 5xx: Server error responses\n *\n *\n * 500 - INTERNAL_SERVER_ERROR - The server encountered an unexpected condition that prevented it from fulfilling the request.\n *\n * 501 - NOT_IMPLEMENTED - The server does not support the functionality required to fulfill the request.\n *\n * 502 - BAD_GATEWAY - The server, while acting as a gateway or proxy, received an invalid response from the upstream server.\n *\n * 503 - SERVICE_UNAVAILABLE - The server is currently unavailable (because it is overloaded or down for maintenance).\n *\n * 504 - GATEWAY_TIMEOUT - The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.\n *\n * 505 - HTTP_VERSION_NOT_SUPPORTED - The server does not support the HTTP protocol version used in the request.\n *\n * 506 - VARIANT_ALSO_NEGOTIATES - The server has an internal configuration error, such as a misconfigured gateway.\n *\n * 507 - INSUFFICIENT_STORAGE - The server is unable to store the representation needed to complete the request.\n *\n * 508 - LOOP_DETECTED - The server detected an infinite loop while processing a request.\n */\nexport enum HttpStatusCodes {\n //* ********************************\n // 1xx: Informational responses\n //* ********************************\n\n /**\n * The server has received the request headers and the client should proceed to send the request body.\n */\n CONTINUE_100 = 100,\n\n /**\n * The requester has asked the server to switch protocols and the server has agreed to do so.\n */\n SWITCHING_PROTOCOLS_101 = 101,\n\n /**\n * Used to return some response headers before final HTTP message.\n */\n PROCESSING_102 = 102, // WebDAV\n\n /**\n * Early hints - part of optimization to improve page load time.\n */\n EARLY_HINTS_103 = 103,\n\n //* ********************************\n // 2xx: Successful responses\n //* ********************************\n\n /**\n * The request has succeeded.\n */\n OK_200 = 200,\n\n /**\n * The request has been fulfilled and has resulted in one or more new resources being created.\n */\n CREATED_201 = 201,\n\n /**\n * The request has been accepted for processing, but the processing has not been completed.\n */\n ACCEPTED_202 = 202,\n\n /**\n * The server successfully processed the request, but is returning information that may be from another source.\n */\n NON_AUTHORITATIVE_INFORMATION_203 = 203,\n\n /**\n * The server successfully processed the request and is not returning any content.\n */\n NO_CONTENT_204 = 204,\n\n /**\n * The server successfully processed the request, but is not returning any content and requires that the requester reset the document view.\n */\n RESET_CONTENT_205 = 205,\n\n /**\n * The server is delivering only part of the resource due to a range header sent by the client.\n */\n PARTIAL_CONTENT_206 = 206,\n\n /**\n * Multi-status response providing status for multiple independent operations.\n */\n MULTI_STATUS_207 = 207, // WebDAV\n\n /**\n * The members of a DAV binding have already been enumerated in a preceding part of the request.\n */\n ALREADY_REPORTED_208 = 208, // WebDAV\n\n /**\n * The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance manipulations applied to the current instance.\n */\n IM_USED_226 = 226,\n\n //* ********************************\n // 3xx: Redirection messages\n //* ********************************\n\n /**\n * The request has more than one possible response. The user-agent or user should choose one of them.\n */\n MULTIPLE_CHOICES_300 = 300,\n\n /**\n * The URL of the requested resource has been changed permanently.\n */\n MOVED_PERMANENTLY_301 = 301,\n\n /**\n * The requested resource is available at a different URI.\n */\n FOUND_302 = 302,\n\n /**\n * The response to the request can be found under another URI using a GET method.\n */\n SEE_OTHER_303 = 303,\n\n /**\n * Indicates that the resource has not been modified since the version specified by the request headers.\n */\n NOT_MODIFIED_304 = 304,\n\n /**\n * The requested resource must be accessed through the proxy given by the Location field.\n */\n USE_PROXY_305 = 305,\n\n /**\n * No longer used. Originally meant to direct the client to switch to a different proxy.\n */\n SWITCH_PROXY_306 = 306,\n\n /**\n * The requested resource resides temporarily under a different URI.\n */\n TEMPORARY_REDIRECT_307 = 307,\n\n /**\n * The request should be repeated with another URI, but future requests should still use the original URI.\n */\n PERMANENT_REDIRECT_308 = 308,\n\n //* ********************************\n // 4xx: Client error responses\n //* ********************************\n\n /**\n * The server cannot or will not process the request due to something perceived to be a client error.\n */\n BAD_REQUEST_400 = 400,\n\n /**\n * The client must authenticate itself to get the requested response.\n */\n UNAUTHORIZED_401 = 401,\n\n /**\n * The client does not have access rights to the content.\n */\n FORBIDDEN_403 = 403,\n\n /**\n * The server can not find the requested resource.\n */\n NOT_FOUND_404 = 404,\n\n /**\n * The request method is known by the server but is not supported by the target resource.\n */\n METHOD_NOT_ALLOWED_405 = 405,\n\n /**\n * This response is sent when the requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.\n */\n NOT_ACCEPTABLE_406 = 406,\n\n /**\n * This is similar to 401 but authentication is needed to be done by a proxy.\n */\n PROXY_AUTHENTICATION_REQUIRED_407 = 407,\n\n /**\n * This response is sent on an idle connection by some servers, even without any previous request by the client.\n */\n REQUEST_TIMEOUT_408 = 408,\n\n /**\n * This response is sent when a request conflicts with the current state of the server.\n */\n CONFLICT_409 = 409,\n\n /**\n * This response is sent when the requested resource is no longer available and will not be available again.\n */\n GONE_410 = 410,\n\n /**\n * The request did not specify the length of its content, which is required by the requested resource.\n */\n LENGTH_REQUIRED_411 = 411,\n\n /**\n * The server does not meet one of the preconditions that the requester put on the request.\n */\n PRECONDITION_FAILED_412 = 412,\n\n /**\n * The request is larger than the server is willing or able to process.\n */\n PAYLOAD_TOO_LARGE_413 = 413,\n\n /**\n * The URI requested by the client is longer than the server is willing to interpret.\n */\n URI_TOO_LONG_414 = 414,\n\n /**\n * The media format of the requested data is not supported by the server.\n */\n UNSUPPORTED_MEDIA_TYPE_415 = 415,\n\n /**\n * The range specified by the Range header field in the request can't be fulfilled.\n */\n RANGE_NOT_SATISFIABLE_416 = 416,\n\n /**\n * The expectation indicated by the Expect request header field can't be met by the server.\n */\n EXPECTATION_FAILED_417 = 417,\n\n /**\n * The server refuses the attempt to brew coffee with a teapot.\n */\n IM_A_TEAPOT_418 = 418, // Easter egg from the HTCPCP/1.0 protocol.\n\n /**\n * The request was directed at a server that is not able to produce a response.\n */\n MISDIRECTED_REQUEST_421 = 421,\n\n /**\n * The request was well-formed but was unable to be followed due to semantic errors.\n */\n UNPROCESSABLE_ENTITY_422 = 422, // WebDAV\n\n /**\n * The resource that is being accessed is locked.\n */\n LOCKED_423 = 423, // WebDAV\n\n /**\n * The request failed due to failure of a previous request.\n */\n FAILED_DEPENDENCY_424 = 424, // WebDAV\n\n /**\n * Indicates that the server is unwilling to risk processing a request that might be replayed.\n */\n TOO_EARLY_425 = 425,\n\n /**\n * The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.\n */\n UPGRADE_REQUIRED_426 = 426,\n\n /**\n * The origin server requires the request to be conditional.\n */\n PRECONDITION_REQUIRED_428 = 428,\n\n /**\n * The user has sent too many requests in a given amount of time.\n */\n TOO_MANY_REQUESTS_429 = 429,\n\n /**\n * The server is unwilling to process the request because its header fields are too large.\n */\n REQUEST_HEADER_FIELDS_TOO_LARGE_431 = 431,\n\n /**\n * The user-agent requested a resource that cannot legally be provided, such as a censored resource.\n */\n UNAVAILABLE_FOR_LEGAL_REASONS_451 = 451,\n\n //* ********************************\n // 5xx: Server error responses\n //* ********************************\n\n /**\n * The server encountered an unexpected condition that prevented it from fulfilling the request.\n */\n INTERNAL_SERVER_ERROR_500 = 500,\n\n /**\n * The server does not support the functionality required to fulfill the request.\n */\n NOT_IMPLEMENTED_501 = 501,\n\n /**\n * The server, while acting as a gateway or proxy, received an invalid response from the upstream server.\n */\n BAD_GATEWAY_502 = 502,\n\n /**\n * The server is currently unavailable (because it is overloaded or down for maintenance).\n */\n SERVICE_UNAVAILABLE_503 = 503,\n\n /**\n * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.\n */\n GATEWAY_TIMEOUT_504 = 504,\n\n /**\n * The server does not support the HTTP protocol version used in the request.\n */\n HTTP_VERSION_NOT_SUPPORTED_505 = 505,\n\n /**\n * The server has an internal configuration error, such as a misconfigured gateway.\n */\n VARIANT_ALSO_NEGOTIATES_506 = 506,\n\n /**\n * The server is unable to store the representation needed to complete the request.\n */\n INSUFFICIENT_STORAGE_507 = 507, // WebDAV\n\n /**\n * The server detected an infinite loop while processing a request.\n */\n LOOP_DETECTED_508 = 508, // WebDAV\n\n /**\n * Further extensions to the request are required for the server to fulfill it.\n */\n NOT_EXTENDED_510 = 510,\n\n /**\n * The client needs to authenticate to gain network access.\n */\n NETWORK_AUTHENTICATION_REQUIRED_511 = 511,\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgJA,IAAY,kBAAL;;;;AAQL;;;;AAKA;;;;AAKA;;;;AAKA;;;;AASA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AASA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AASA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AASA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;;;AAKA;;KACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"resizeImage.mjs","names":[],"sources":["../../../../src/utils/image/resizeImage.ts"],"sourcesContent":["import sharp from 'sharp';\n\nexport type ResizeImageOptions = {\n /** Max width in pixels */\n width: number;\n /** Max height in pixels */\n height: number;\n /** JPEG quality 1–100 (default: 80) */\n quality?: number;\n};\n\n/**\n * Resize and re-encode any supported image (JPEG, PNG, WebP, GIF) to JPEG.\n * Maintains aspect ratio (never upscales). Returns the compressed buffer.\n */\nexport const resizeImage = async (\n input: Buffer,\n { width, height, quality = 80 }: ResizeImageOptions\n): Promise<{ buffer: Buffer; contentType: 'image/jpeg' }> => {\n const buffer = await sharp(input)\n .resize(width, height, { fit: 'inside', withoutEnlargement: true })\n .jpeg({ quality, mozjpeg: true })\n .toBuffer();\n\n return { buffer, contentType: 'image/jpeg' };\n};\n"],"mappings":";;;;;;;AAeA,MAAa,cAAc,OACzB,OACA,EAAE,OAAO,QAAQ,UAAU,SACgC;CAM3D,OAAO;EAAE,cALY,MAAM,KAAK,CAAC,CAC9B,OAAO,OAAO,QAAQ;GAAE,KAAK;GAAU,oBAAoB;EAAK,CAAC,CAAC,CAClE,KAAK;GAAE;GAAS,SAAS;EAAK,CAAC,CAAC,CAChC,SAAS;EAEK,aAAa;CAAa;AAC7C"}
1
+ {"version":3,"file":"resizeImage.mjs","names":[],"sources":["../../../../src/utils/image/resizeImage.ts"],"sourcesContent":["import sharp from 'sharp';\n\nexport type ResizeImageOptions = {\n /** Max width in pixels */\n width: number;\n /** Max height in pixels */\n height: number;\n /** JPEG quality 1–100 (default: 80) */\n quality?: number;\n};\n\n/**\n * Resize and re-encode any supported image (JPEG, PNG, WebP, GIF) to JPEG.\n * Maintains aspect ratio (never upscales). Returns the compressed buffer.\n */\nexport const resizeImage = async (\n input: Buffer,\n { width, height, quality = 80 }: ResizeImageOptions\n): Promise<{ buffer: Buffer; contentType: 'image/jpeg' }> => {\n const buffer = await sharp(input)\n .resize(width, height, { fit: 'inside', withoutEnlargement: true })\n .jpeg({ quality, mozjpeg: true })\n .toBuffer();\n\n return { buffer, contentType: 'image/jpeg' };\n};\n"],"mappings":";;;;;;;AAeA,MAAa,cAAc,OACzB,OACA,EAAE,OAAO,QAAQ,UAAU,SACgC;AAM3D,QAAO;EAAE,cALY,MAAM,MAAM,CAC9B,OAAO,OAAO,QAAQ;GAAE,KAAK;GAAU,oBAAoB;GAAM,CAAC,CAClE,KAAK;GAAE;GAAS,SAAS;GAAM,CAAC,CAChC,UAAU;EAEI,aAAa;EAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"dictionary.mjs","names":[],"sources":["../../../../src/utils/mapper/dictionary.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Dictionary, DictionaryAPI } from '@/types/dictionary.types';\n\n/**\n * Maps a dictionary to an API response.\n * If the version is not provided, the latest version is used.\n *\n * @param dictionary - The dictionary to map.\n * @param projectId - The ID of the project the dictionary belongs to.\n * @returns The dictionary mapped to an API response.\n */\nexport const mapDictionaryToAPI = (\n dictionary: Dictionary,\n version?: string\n): DictionaryAPI => {\n const dictionaryObject = ensureMongoDocumentToObject<Dictionary>(dictionary);\n\n const versionList = dictionaryObject.content\n ? [...(dictionaryObject.content.keys() ?? [])]\n : [];\n let returnedVersion = version;\n\n if (!returnedVersion) {\n const lastVersion = versionList[versionList.length - 1];\n returnedVersion = lastVersion;\n }\n\n const content = dictionaryObject.content\n ? ((dictionaryObject.content.get(returnedVersion as string)\n ?.content as DictionaryAPI['content']) ?? null)\n : null;\n\n return {\n ...dictionaryObject,\n content,\n version: returnedVersion,\n localId: `${dictionaryObject.key}::remote::${dictionaryObject.id}`,\n versionList,\n } as unknown as DictionaryAPI;\n};\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,sBACX,YACA,YACkB;CAClB,MAAM,mBAAmB,4BAAwC,UAAU;CAE3E,MAAM,cAAc,iBAAiB,UACjC,CAAC,GAAI,iBAAiB,QAAQ,KAAK,KAAK,CAAC,CAAE,IAC3C,CAAC;CACL,IAAI,kBAAkB;CAEtB,IAAI,CAAC,iBAEH,kBADoB,YAAY,YAAY,SAAS;CAIvD,MAAM,UAAU,iBAAiB,UAC3B,iBAAiB,QAAQ,IAAI,eAAyB,CAAC,EACrD,WAAwC,OAC5C;CAEJ,OAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,SAAS,GAAG,iBAAiB,IAAI,YAAY,iBAAiB;EAC9D;CACF;AACF"}
1
+ {"version":3,"file":"dictionary.mjs","names":[],"sources":["../../../../src/utils/mapper/dictionary.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Dictionary, DictionaryAPI } from '@/types/dictionary.types';\n\n/**\n * Maps a dictionary to an API response.\n * If the version is not provided, the latest version is used.\n *\n * @param dictionary - The dictionary to map.\n * @param projectId - The ID of the project the dictionary belongs to.\n * @returns The dictionary mapped to an API response.\n */\nexport const mapDictionaryToAPI = (\n dictionary: Dictionary,\n version?: string\n): DictionaryAPI => {\n const dictionaryObject = ensureMongoDocumentToObject<Dictionary>(dictionary);\n\n const versionList = dictionaryObject.content\n ? [...(dictionaryObject.content.keys() ?? [])]\n : [];\n let returnedVersion = version;\n\n if (!returnedVersion) {\n const lastVersion = versionList[versionList.length - 1];\n returnedVersion = lastVersion;\n }\n\n const content = dictionaryObject.content\n ? ((dictionaryObject.content.get(returnedVersion as string)\n ?.content as DictionaryAPI['content']) ?? null)\n : null;\n\n return {\n ...dictionaryObject,\n content,\n version: returnedVersion,\n localId: `${dictionaryObject.key}::remote::${dictionaryObject.id}`,\n versionList,\n } as unknown as DictionaryAPI;\n};\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,sBACX,YACA,YACkB;CAClB,MAAM,mBAAmB,4BAAwC,WAAW;CAE5E,MAAM,cAAc,iBAAiB,UACjC,CAAC,GAAI,iBAAiB,QAAQ,MAAM,IAAI,EAAE,CAAE,GAC5C,EAAE;CACN,IAAI,kBAAkB;AAEtB,KAAI,CAAC,gBAEH,mBADoB,YAAY,YAAY,SAAS;CAIvD,MAAM,UAAU,iBAAiB,UAC3B,iBAAiB,QAAQ,IAAI,gBAA0B,EACrD,WAAwC,OAC5C;AAEJ,QAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,SAAS,GAAG,iBAAiB,IAAI,YAAY,iBAAiB;EAC9D;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"organization.mjs","names":[],"sources":["../../../../src/utils/mapper/organization.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Organization, OrganizationAPI } from '@/types/organization.types';\n\n/**\n * Maps an organization to an API response.\n * @param organization - The organization to map.\n * @param - Whether the user is an admin of the organization.\n * @returns The organization mapped to an API response.\n */\nexport const mapOrganizationToAPI = <\n T extends Organization | OrganizationAPI | null,\n>(\n organization?: T\n): T extends null ? null : OrganizationAPI => {\n if (!organization) {\n return null as any;\n }\n\n const organizationObject = ensureMongoDocumentToObject(organization);\n\n return organizationObject as any;\n};\n\nexport const mapOrganizationsToAPI = (\n organizations: (Organization | OrganizationAPI)[]\n): OrganizationAPI[] =>\n organizations.map(mapOrganizationToAPI).filter(Boolean) as OrganizationAPI[];\n"],"mappings":";;;;;;;;;AASA,MAAa,wBAGX,iBAC4C;CAC5C,IAAI,CAAC,cACH,OAAO;CAKT,OAF2B,4BAA4B,YAE/B;AAC1B;AAEA,MAAa,yBACX,kBAEA,cAAc,IAAI,oBAAoB,CAAC,CAAC,OAAO,OAAO"}
1
+ {"version":3,"file":"organization.mjs","names":[],"sources":["../../../../src/utils/mapper/organization.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Organization, OrganizationAPI } from '@/types/organization.types';\n\n/**\n * Maps an organization to an API response.\n * @param organization - The organization to map.\n * @param - Whether the user is an admin of the organization.\n * @returns The organization mapped to an API response.\n */\nexport const mapOrganizationToAPI = <\n T extends Organization | OrganizationAPI | null,\n>(\n organization?: T\n): T extends null ? null : OrganizationAPI => {\n if (!organization) {\n return null as any;\n }\n\n const organizationObject = ensureMongoDocumentToObject(organization);\n\n return organizationObject as any;\n};\n\nexport const mapOrganizationsToAPI = (\n organizations: (Organization | OrganizationAPI)[]\n): OrganizationAPI[] =>\n organizations.map(mapOrganizationToAPI).filter(Boolean) as OrganizationAPI[];\n"],"mappings":";;;;;;;;;AASA,MAAa,wBAGX,iBAC4C;AAC5C,KAAI,CAAC,aACH,QAAO;AAKT,QAF2B,4BAA4B,aAE9B;;AAG3B,MAAa,yBACX,kBAEA,cAAc,IAAI,qBAAqB,CAAC,OAAO,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"project.mjs","names":[],"sources":["../../../../src/utils/mapper/project.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type {\n EnvironmentAPI,\n Project,\n ProjectAPI,\n ProjectConfiguration,\n} from '@/types/project.types';\n\n/**\n * Sentinel ID used for the virtual \"production\" environment when the project\n * has no DB-persisted default environment. The frontend uses this value to\n * identify production and route the selection to the null-env reset endpoint.\n *\n * Safe to use as a sentinel because MongoDB ObjectIds are 24-char hex strings.\n */\nexport const PRODUCTION_ENV_SENTINEL_ID = 'production';\n\n/**\n * Sanitizes the AI configuration by removing the API key and adding a flag.\n * @param apiKey - The API key to mask.\n * @returns The masked API key.\n */\nconst maskApiKey = (apiKey: string): string => {\n if (apiKey.length <= 8) return '*'.repeat(apiKey.length);\n const prefix = apiKey.slice(0, 8);\n const suffix = apiKey.slice(-4);\n const masked = '*'.repeat(Math.max(apiKey.length - 12, 8));\n return `${prefix}${masked}${suffix}`;\n};\n\nconst sanitizeAIConfig = (\n aiConfig?: ProjectConfiguration['ai']\n): ProjectConfiguration['ai'] => {\n if (!aiConfig) {\n return aiConfig;\n }\n\n const { apiKey, ...rest } = aiConfig;\n return {\n ...rest,\n apiKey: apiKey ? maskApiKey(apiKey) : undefined,\n };\n};\n\n/**\n * Sanitizes the project configuration by removing sensitive data.\n * @param configuration - The project configuration to sanitize.\n * @returns The sanitized project configuration.\n */\nconst sanitizeProjectConfiguration = (\n configuration?: Project['configuration']\n): Project['configuration'] => {\n if (!configuration) {\n return configuration;\n }\n\n return {\n ...configuration,\n ai: sanitizeAIConfig(configuration.ai),\n };\n};\n\n/**\n * Maps a project to an API response.\n * @param project - The project to map.\n * @returns The project mapped to an API response.\n */\nexport const mapProjectToAPI = <T extends Project | ProjectAPI | null>(\n project?: T\n): T extends null ? null : ProjectAPI => {\n if (!project) {\n return null as any;\n }\n\n const projectObject = ensureMongoDocumentToObject(\n project\n ) as unknown as ProjectAPI;\n\n // Sanitize configuration to remove sensitive API key\n if (projectObject.configuration) {\n projectObject.configuration = sanitizeProjectConfiguration(\n projectObject.configuration\n );\n }\n\n // Sanitize per-environment AI keys\n const rawEnvironments: any[] = projectObject.environments ?? [];\n\n const mappedEnvironments: EnvironmentAPI[] = rawEnvironments.map(\n (environment) => ({\n ...environment,\n // Subdocuments expose _id before the toJSON transform; normalise to id\n id: String(environment._id ?? environment.id),\n configuration: sanitizeProjectConfiguration(environment.configuration),\n })\n );\n\n const hasDefaultEnvironment = mappedEnvironments.some(\n (environment) => environment.isDefault\n );\n\n // Production is the canonical default. If no DB environment is marked as\n // default, inject a virtual production entry so the frontend always has a\n // baseline to display and migrate to/from.\n if (!hasDefaultEnvironment) {\n mappedEnvironments.unshift({\n id: PRODUCTION_ENV_SENTINEL_ID,\n name: 'production',\n isDefault: true,\n } as unknown as EnvironmentAPI);\n }\n\n projectObject.environments = mappedEnvironments;\n\n return projectObject as any;\n};\n\n/**\n * Formats an array of projects for API response. Removes sensitive information.\n * @param projects - The array of project objects to format.\n * @returns The formatted array of user objects.\n */\nexport const mapProjectsToAPI = (\n projects: (Project | ProjectAPI)[]\n): ProjectAPI[] =>\n projects.map(mapProjectToAPI).filter(Boolean) as ProjectAPI[];\n"],"mappings":";;;;;;;;;;AAeA,MAAa,6BAA6B;;;;;;AAO1C,MAAM,cAAc,WAA2B;CAC7C,IAAI,OAAO,UAAU,GAAG,OAAO,IAAI,OAAO,OAAO,MAAM;CACvD,MAAM,SAAS,OAAO,MAAM,GAAG,CAAC;CAChC,MAAM,SAAS,OAAO,MAAM,EAAE;CAE9B,OAAO,GAAG,SADK,IAAI,OAAO,KAAK,IAAI,OAAO,SAAS,IAAI,CAAC,CAChC,IAAI;AAC9B;AAEA,MAAM,oBACJ,aAC+B;CAC/B,IAAI,CAAC,UACH,OAAO;CAGT,MAAM,EAAE,QAAQ,GAAG,SAAS;CAC5B,OAAO;EACL,GAAG;EACH,QAAQ,SAAS,WAAW,MAAM,IAAI;CACxC;AACF;;;;;;AAOA,MAAM,gCACJ,kBAC6B;CAC7B,IAAI,CAAC,eACH,OAAO;CAGT,OAAO;EACL,GAAG;EACH,IAAI,iBAAiB,cAAc,EAAE;CACvC;AACF;;;;;;AAOA,MAAa,mBACX,YACuC;CACvC,IAAI,CAAC,SACH,OAAO;CAGT,MAAM,gBAAgB,4BACpB,OACF;CAGA,IAAI,cAAc,eAChB,cAAc,gBAAgB,6BAC5B,cAAc,aAChB;CAMF,MAAM,sBAFyB,cAAc,gBAAgB,CAAC,EAEF,CAAC,KAC1D,iBAAiB;EAChB,GAAG;EAEH,IAAI,OAAO,YAAY,OAAO,YAAY,EAAE;EAC5C,eAAe,6BAA6B,YAAY,aAAa;CACvE,EACF;CASA,IAAI,CAP0B,mBAAmB,MAC9C,gBAAgB,YAAY,SAMN,GACvB,mBAAmB,QAAQ;EACzB,IAAI;EACJ,MAAM;EACN,WAAW;CACb,CAA8B;CAGhC,cAAc,eAAe;CAE7B,OAAO;AACT;;;;;;AAOA,MAAa,oBACX,aAEA,SAAS,IAAI,eAAe,CAAC,CAAC,OAAO,OAAO"}
1
+ {"version":3,"file":"project.mjs","names":[],"sources":["../../../../src/utils/mapper/project.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type {\n EnvironmentAPI,\n Project,\n ProjectAPI,\n ProjectConfiguration,\n} from '@/types/project.types';\n\n/**\n * Sentinel ID used for the virtual \"production\" environment when the project\n * has no DB-persisted default environment. The frontend uses this value to\n * identify production and route the selection to the null-env reset endpoint.\n *\n * Safe to use as a sentinel because MongoDB ObjectIds are 24-char hex strings.\n */\nexport const PRODUCTION_ENV_SENTINEL_ID = 'production';\n\n/**\n * Sanitizes the AI configuration by removing the API key and adding a flag.\n * @param apiKey - The API key to mask.\n * @returns The masked API key.\n */\nconst maskApiKey = (apiKey: string): string => {\n if (apiKey.length <= 8) return '*'.repeat(apiKey.length);\n const prefix = apiKey.slice(0, 8);\n const suffix = apiKey.slice(-4);\n const masked = '*'.repeat(Math.max(apiKey.length - 12, 8));\n return `${prefix}${masked}${suffix}`;\n};\n\nconst sanitizeAIConfig = (\n aiConfig?: ProjectConfiguration['ai']\n): ProjectConfiguration['ai'] => {\n if (!aiConfig) {\n return aiConfig;\n }\n\n const { apiKey, ...rest } = aiConfig;\n return {\n ...rest,\n apiKey: apiKey ? maskApiKey(apiKey) : undefined,\n };\n};\n\n/**\n * Sanitizes the project configuration by removing sensitive data.\n * @param configuration - The project configuration to sanitize.\n * @returns The sanitized project configuration.\n */\nconst sanitizeProjectConfiguration = (\n configuration?: Project['configuration']\n): Project['configuration'] => {\n if (!configuration) {\n return configuration;\n }\n\n return {\n ...configuration,\n ai: sanitizeAIConfig(configuration.ai),\n };\n};\n\n/**\n * Maps a project to an API response.\n * @param project - The project to map.\n * @returns The project mapped to an API response.\n */\nexport const mapProjectToAPI = <T extends Project | ProjectAPI | null>(\n project?: T\n): T extends null ? null : ProjectAPI => {\n if (!project) {\n return null as any;\n }\n\n const projectObject = ensureMongoDocumentToObject(\n project\n ) as unknown as ProjectAPI;\n\n // Sanitize configuration to remove sensitive API key\n if (projectObject.configuration) {\n projectObject.configuration = sanitizeProjectConfiguration(\n projectObject.configuration\n );\n }\n\n // Sanitize per-environment AI keys\n const rawEnvironments: any[] = projectObject.environments ?? [];\n\n const mappedEnvironments: EnvironmentAPI[] = rawEnvironments.map(\n (environment) => ({\n ...environment,\n // Subdocuments expose _id before the toJSON transform; normalise to id\n id: String(environment._id ?? environment.id),\n configuration: sanitizeProjectConfiguration(environment.configuration),\n })\n );\n\n const hasDefaultEnvironment = mappedEnvironments.some(\n (environment) => environment.isDefault\n );\n\n // Production is the canonical default. If no DB environment is marked as\n // default, inject a virtual production entry so the frontend always has a\n // baseline to display and migrate to/from.\n if (!hasDefaultEnvironment) {\n mappedEnvironments.unshift({\n id: PRODUCTION_ENV_SENTINEL_ID,\n name: 'production',\n isDefault: true,\n } as unknown as EnvironmentAPI);\n }\n\n projectObject.environments = mappedEnvironments;\n\n return projectObject as any;\n};\n\n/**\n * Formats an array of projects for API response. Removes sensitive information.\n * @param projects - The array of project objects to format.\n * @returns The formatted array of user objects.\n */\nexport const mapProjectsToAPI = (\n projects: (Project | ProjectAPI)[]\n): ProjectAPI[] =>\n projects.map(mapProjectToAPI).filter(Boolean) as ProjectAPI[];\n"],"mappings":";;;;;;;;;;AAeA,MAAa,6BAA6B;;;;;;AAO1C,MAAM,cAAc,WAA2B;AAC7C,KAAI,OAAO,UAAU,EAAG,QAAO,IAAI,OAAO,OAAO,OAAO;CACxD,MAAM,SAAS,OAAO,MAAM,GAAG,EAAE;CACjC,MAAM,SAAS,OAAO,MAAM,GAAG;AAE/B,QAAO,GAAG,SADK,IAAI,OAAO,KAAK,IAAI,OAAO,SAAS,IAAI,EAAE,CAChC,GAAG;;AAG9B,MAAM,oBACJ,aAC+B;AAC/B,KAAI,CAAC,SACH,QAAO;CAGT,MAAM,EAAE,QAAQ,GAAG,SAAS;AAC5B,QAAO;EACL,GAAG;EACH,QAAQ,SAAS,WAAW,OAAO,GAAG;EACvC;;;;;;;AAQH,MAAM,gCACJ,kBAC6B;AAC7B,KAAI,CAAC,cACH,QAAO;AAGT,QAAO;EACL,GAAG;EACH,IAAI,iBAAiB,cAAc,GAAG;EACvC;;;;;;;AAQH,MAAa,mBACX,YACuC;AACvC,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,gBAAgB,4BACpB,QACD;AAGD,KAAI,cAAc,cAChB,eAAc,gBAAgB,6BAC5B,cAAc,cACf;CAMH,MAAM,sBAFyB,cAAc,gBAAgB,EAAE,EAEF,KAC1D,iBAAiB;EAChB,GAAG;EAEH,IAAI,OAAO,YAAY,OAAO,YAAY,GAAG;EAC7C,eAAe,6BAA6B,YAAY,cAAc;EACvE,EACF;AASD,KAAI,CAP0B,mBAAmB,MAC9C,gBAAgB,YAAY,UAML,CACxB,oBAAmB,QAAQ;EACzB,IAAI;EACJ,MAAM;EACN,WAAW;EACZ,CAA8B;AAGjC,eAAc,eAAe;AAE7B,QAAO;;;;;;;AAQT,MAAa,oBACX,aAEA,SAAS,IAAI,gBAAgB,CAAC,OAAO,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"session.mjs","names":[],"sources":["../../../../src/utils/mapper/session.ts"],"sourcesContent":["import type { Session, SessionAPI } from '@/types/session.types';\nimport { mapOrganizationToAPI } from './organization';\nimport { mapProjectToAPI } from './project';\nimport { mapUserToAPI } from './user';\n\nexport const mapSessionToAPI = (session: Session): SessionAPI => ({\n ...(session as any),\n id: session.id ? String(session.id) : undefined,\n user: mapUserToAPI(session.user),\n organization: mapOrganizationToAPI(session.organization),\n project: mapProjectToAPI(session.project),\n environment: session.environment ?? null,\n});\n"],"mappings":";;;;;AAKA,MAAa,mBAAmB,aAAkC;CAChE,GAAI;CACJ,IAAI,QAAQ,KAAK,OAAO,QAAQ,EAAE,IAAI;CACtC,MAAM,aAAa,QAAQ,IAAI;CAC/B,cAAc,qBAAqB,QAAQ,YAAY;CACvD,SAAS,gBAAgB,QAAQ,OAAO;CACxC,aAAa,QAAQ,eAAe;AACtC"}
1
+ {"version":3,"file":"session.mjs","names":[],"sources":["../../../../src/utils/mapper/session.ts"],"sourcesContent":["import type { Session, SessionAPI } from '@/types/session.types';\nimport { mapOrganizationToAPI } from './organization';\nimport { mapProjectToAPI } from './project';\nimport { mapUserToAPI } from './user';\n\nexport const mapSessionToAPI = (session: Session): SessionAPI => ({\n ...(session as any),\n id: session.id ? String(session.id) : undefined,\n user: mapUserToAPI(session.user),\n organization: mapOrganizationToAPI(session.organization),\n project: mapProjectToAPI(session.project),\n environment: session.environment ?? null,\n});\n"],"mappings":";;;;;AAKA,MAAa,mBAAmB,aAAkC;CAChE,GAAI;CACJ,IAAI,QAAQ,KAAK,OAAO,QAAQ,GAAG,GAAG;CACtC,MAAM,aAAa,QAAQ,KAAK;CAChC,cAAc,qBAAqB,QAAQ,aAAa;CACxD,SAAS,gBAAgB,QAAQ,QAAQ;CACzC,aAAa,QAAQ,eAAe;CACrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"showcaseProject.mjs","names":[],"sources":["../../../../src/utils/mapper/showcaseProject.ts"],"sourcesContent":["import type {\n ShowcaseProjectAPI,\n ShowcaseProjectDocument,\n} from '@/types/showcaseProject.types';\n\n/**\n * Maps a ShowcaseProjectDocument to a ShowcaseProjectAPI response.\n * Reduces the `upvoters` array to a numeric `upvotes` count and\n * optionally computes `isUpvoted`/`isDownVoted` for the given userId.\n */\nexport const mapShowcaseProjectToAPI = (\n doc: ShowcaseProjectDocument,\n userId?: string\n): ShowcaseProjectAPI => {\n const upvoters: string[] = doc.upvoters ?? [];\n const downvoters: string[] = doc.downvoters ?? [];\n\n // Mongoose Map fields must be converted to plain objects\n const packageDetails: Record<string, string> =\n doc.packageDetails instanceof Map\n ? Object.fromEntries(doc.packageDetails)\n : ((doc.packageDetails as Record<string, string> | undefined) ?? {});\n\n return {\n id: String((doc as any)._id),\n title: doc.title,\n description: doc.description,\n imageUrl: doc.imageUrl,\n logoUrl: doc.logoUrl,\n websiteUrl: doc.websiteUrl,\n githubUrl: doc.githubUrl,\n tags: doc.tags,\n upvotes: upvoters.length,\n isUpVoted: userId ? upvoters.includes(userId) : false,\n isDownVoted: userId ? downvoters.includes(userId) : false,\n downvotes: downvoters.length,\n isOpenSource: doc.isOpenSource,\n createdAt:\n doc.createdAt instanceof Date\n ? doc.createdAt.toISOString()\n : String(doc.createdAt),\n lastScanDate:\n doc.lastScanDate instanceof Date\n ? doc.lastScanDate.toISOString()\n : doc.lastScanDate\n ? String(doc.lastScanDate)\n : undefined,\n intlayerVersion: doc.intlayerVersion,\n libsUsed: doc.libsUsed,\n packageDetails,\n scanDetails: doc.scanDetails,\n owner: doc.owner,\n status: doc.status,\n isOwner: userId ? doc.owner === userId : false,\n };\n};\n\nexport const mapShowcaseProjectsToAPI = (\n docs: ShowcaseProjectDocument[],\n userId?: string\n): ShowcaseProjectAPI[] =>\n docs.map((doc) => mapShowcaseProjectToAPI(doc, userId));\n"],"mappings":";;;;;;AAUA,MAAa,2BACX,KACA,WACuB;CACvB,MAAM,WAAqB,IAAI,YAAY,CAAC;CAC5C,MAAM,aAAuB,IAAI,cAAc,CAAC;CAGhD,MAAM,iBACJ,IAAI,0BAA0B,MAC1B,OAAO,YAAY,IAAI,cAAc,IACnC,IAAI,kBAAyD,CAAC;CAEtE,OAAO;EACL,IAAI,OAAQ,IAAY,GAAG;EAC3B,OAAO,IAAI;EACX,aAAa,IAAI;EACjB,UAAU,IAAI;EACd,SAAS,IAAI;EACb,YAAY,IAAI;EAChB,WAAW,IAAI;EACf,MAAM,IAAI;EACV,SAAS,SAAS;EAClB,WAAW,SAAS,SAAS,SAAS,MAAM,IAAI;EAChD,aAAa,SAAS,WAAW,SAAS,MAAM,IAAI;EACpD,WAAW,WAAW;EACtB,cAAc,IAAI;EAClB,WACE,IAAI,qBAAqB,OACrB,IAAI,UAAU,YAAY,IAC1B,OAAO,IAAI,SAAS;EAC1B,cACE,IAAI,wBAAwB,OACxB,IAAI,aAAa,YAAY,IAC7B,IAAI,eACF,OAAO,IAAI,YAAY,IACvB;EACR,iBAAiB,IAAI;EACrB,UAAU,IAAI;EACd;EACA,aAAa,IAAI;EACjB,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,SAAS,SAAS,IAAI,UAAU,SAAS;CAC3C;AACF;AAEA,MAAa,4BACX,MACA,WAEA,KAAK,KAAK,QAAQ,wBAAwB,KAAK,MAAM,CAAC"}
1
+ {"version":3,"file":"showcaseProject.mjs","names":[],"sources":["../../../../src/utils/mapper/showcaseProject.ts"],"sourcesContent":["import type {\n ShowcaseProjectAPI,\n ShowcaseProjectDocument,\n} from '@/types/showcaseProject.types';\n\n/**\n * Maps a ShowcaseProjectDocument to a ShowcaseProjectAPI response.\n * Reduces the `upvoters` array to a numeric `upvotes` count and\n * optionally computes `isUpvoted`/`isDownVoted` for the given userId.\n */\nexport const mapShowcaseProjectToAPI = (\n doc: ShowcaseProjectDocument,\n userId?: string\n): ShowcaseProjectAPI => {\n const upvoters: string[] = doc.upvoters ?? [];\n const downvoters: string[] = doc.downvoters ?? [];\n\n // Mongoose Map fields must be converted to plain objects\n const packageDetails: Record<string, string> =\n doc.packageDetails instanceof Map\n ? Object.fromEntries(doc.packageDetails)\n : ((doc.packageDetails as Record<string, string> | undefined) ?? {});\n\n return {\n id: String((doc as any)._id),\n title: doc.title,\n description: doc.description,\n imageUrl: doc.imageUrl,\n logoUrl: doc.logoUrl,\n websiteUrl: doc.websiteUrl,\n githubUrl: doc.githubUrl,\n tags: doc.tags,\n upvotes: upvoters.length,\n isUpVoted: userId ? upvoters.includes(userId) : false,\n isDownVoted: userId ? downvoters.includes(userId) : false,\n downvotes: downvoters.length,\n isOpenSource: doc.isOpenSource,\n createdAt:\n doc.createdAt instanceof Date\n ? doc.createdAt.toISOString()\n : String(doc.createdAt),\n lastScanDate:\n doc.lastScanDate instanceof Date\n ? doc.lastScanDate.toISOString()\n : doc.lastScanDate\n ? String(doc.lastScanDate)\n : undefined,\n intlayerVersion: doc.intlayerVersion,\n libsUsed: doc.libsUsed,\n packageDetails,\n scanDetails: doc.scanDetails,\n owner: doc.owner,\n status: doc.status,\n isOwner: userId ? doc.owner === userId : false,\n };\n};\n\nexport const mapShowcaseProjectsToAPI = (\n docs: ShowcaseProjectDocument[],\n userId?: string\n): ShowcaseProjectAPI[] =>\n docs.map((doc) => mapShowcaseProjectToAPI(doc, userId));\n"],"mappings":";;;;;;AAUA,MAAa,2BACX,KACA,WACuB;CACvB,MAAM,WAAqB,IAAI,YAAY,EAAE;CAC7C,MAAM,aAAuB,IAAI,cAAc,EAAE;CAGjD,MAAM,iBACJ,IAAI,0BAA0B,MAC1B,OAAO,YAAY,IAAI,eAAe,GACpC,IAAI,kBAAyD,EAAE;AAEvE,QAAO;EACL,IAAI,OAAQ,IAAY,IAAI;EAC5B,OAAO,IAAI;EACX,aAAa,IAAI;EACjB,UAAU,IAAI;EACd,SAAS,IAAI;EACb,YAAY,IAAI;EAChB,WAAW,IAAI;EACf,MAAM,IAAI;EACV,SAAS,SAAS;EAClB,WAAW,SAAS,SAAS,SAAS,OAAO,GAAG;EAChD,aAAa,SAAS,WAAW,SAAS,OAAO,GAAG;EACpD,WAAW,WAAW;EACtB,cAAc,IAAI;EAClB,WACE,IAAI,qBAAqB,OACrB,IAAI,UAAU,aAAa,GAC3B,OAAO,IAAI,UAAU;EAC3B,cACE,IAAI,wBAAwB,OACxB,IAAI,aAAa,aAAa,GAC9B,IAAI,eACF,OAAO,IAAI,aAAa,GACxB;EACR,iBAAiB,IAAI;EACrB,UAAU,IAAI;EACd;EACA,aAAa,IAAI;EACjB,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,SAAS,SAAS,IAAI,UAAU,SAAS;EAC1C;;AAGH,MAAa,4BACX,MACA,WAEA,KAAK,KAAK,QAAQ,wBAAwB,KAAK,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tag.mjs","names":[],"sources":["../../../../src/utils/mapper/tag.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Tag, TagAPI } from '@/types/tag.types';\n\n/**\n * Maps a tag to an API response.\n * @param tag - The tag to map.\n * @returns The tag mapped to an API response.\n */\nexport const mapTagToAPI = <T extends Tag | TagAPI | null>(\n tag: T\n): T extends null ? null : TagAPI => {\n if (!tag) {\n return null as any;\n }\n\n const tagObject = ensureMongoDocumentToObject(tag);\n\n return tagObject as any;\n};\n\n/**\n * Formats an array of tags for API response. Removes sensitive information.\n * @param tags - The array of tag objects to format.\n * @param user - The user object.\n * @param isTagAdmin - Whether the user is an admin of the tag.\n * @returns The formatted array of user objects.\n */\nexport const mapTagsToAPI = (tags: Tag[]): TagAPI[] =>\n tags.map((tag) => mapTagToAPI(tag));\n"],"mappings":";;;;;;;;AAQA,MAAa,eACX,QACmC;CACnC,IAAI,CAAC,KACH,OAAO;CAKT,OAFkB,4BAA4B,GAE/B;AACjB;;;;;;;;AASA,MAAa,gBAAgB,SAC3B,KAAK,KAAK,QAAQ,YAAY,GAAG,CAAC"}
1
+ {"version":3,"file":"tag.mjs","names":[],"sources":["../../../../src/utils/mapper/tag.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { Tag, TagAPI } from '@/types/tag.types';\n\n/**\n * Maps a tag to an API response.\n * @param tag - The tag to map.\n * @returns The tag mapped to an API response.\n */\nexport const mapTagToAPI = <T extends Tag | TagAPI | null>(\n tag: T\n): T extends null ? null : TagAPI => {\n if (!tag) {\n return null as any;\n }\n\n const tagObject = ensureMongoDocumentToObject(tag);\n\n return tagObject as any;\n};\n\n/**\n * Formats an array of tags for API response. Removes sensitive information.\n * @param tags - The array of tag objects to format.\n * @param user - The user object.\n * @param isTagAdmin - Whether the user is an admin of the tag.\n * @returns The formatted array of user objects.\n */\nexport const mapTagsToAPI = (tags: Tag[]): TagAPI[] =>\n tags.map((tag) => mapTagToAPI(tag));\n"],"mappings":";;;;;;;;AAQA,MAAa,eACX,QACmC;AACnC,KAAI,CAAC,IACH,QAAO;AAKT,QAFkB,4BAA4B,IAE9B;;;;;;;;;AAUlB,MAAa,gBAAgB,SAC3B,KAAK,KAAK,QAAQ,YAAY,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"user.mjs","names":[],"sources":["../../../../src/utils/mapper/user.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { User, UserAPI } from '@/types/user.types';\n\n/**\n * Formats a user for API response. Removes sensitive information and adds role.\n * @param user - The user object to format.\n * @returns The formatted user object.\n */\nexport const mapUserToAPI = <T extends User | UserAPI | null>(\n user?: T\n): T extends null ? null : UserAPI => {\n if (!user) {\n return null as any;\n }\n\n const userObject = ensureMongoDocumentToObject(user);\n\n // biome-ignore lint/correctness/noUnusedVariables: Just filter out provider and session\n const { provider, session, ...userAPI } = userObject as any;\n\n return userAPI as any;\n};\n\n/**\n * Formats an array of users for API response. Removes sensitive information and adds role.\n * @param users - The array of user objects to format.\n * @returns The formatted array of user objects.\n */\nexport const mapUsersToAPI = (users: (User | UserAPI)[]): UserAPI[] =>\n users.map(mapUserToAPI).filter(Boolean) as UserAPI[];\n"],"mappings":";;;;;;;;AAQA,MAAa,gBACX,SACoC;CACpC,IAAI,CAAC,MACH,OAAO;CAMT,MAAM,EAAE,UAAU,SAAS,GAAG,YAHX,4BAA4B,IAGI;CAEnD,OAAO;AACT;;;;;;AAOA,MAAa,iBAAiB,UAC5B,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,OAAO"}
1
+ {"version":3,"file":"user.mjs","names":[],"sources":["../../../../src/utils/mapper/user.ts"],"sourcesContent":["import { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport type { User, UserAPI } from '@/types/user.types';\n\n/**\n * Formats a user for API response. Removes sensitive information and adds role.\n * @param user - The user object to format.\n * @returns The formatted user object.\n */\nexport const mapUserToAPI = <T extends User | UserAPI | null>(\n user?: T\n): T extends null ? null : UserAPI => {\n if (!user) {\n return null as any;\n }\n\n const userObject = ensureMongoDocumentToObject(user);\n\n // biome-ignore lint/correctness/noUnusedVariables: Just filter out provider and session\n const { provider, session, ...userAPI } = userObject as any;\n\n return userAPI as any;\n};\n\n/**\n * Formats an array of users for API response. Removes sensitive information and adds role.\n * @param users - The array of user objects to format.\n * @returns The formatted array of user objects.\n */\nexport const mapUsersToAPI = (users: (User | UserAPI)[]): UserAPI[] =>\n users.map(mapUserToAPI).filter(Boolean) as UserAPI[];\n"],"mappings":";;;;;;;;AAQA,MAAa,gBACX,SACoC;AACpC,KAAI,CAAC,KACH,QAAO;CAMT,MAAM,EAAE,UAAU,SAAS,GAAG,YAHX,4BAA4B,KAGK;AAEpD,QAAO;;;;;;;AAQT,MAAa,iBAAiB,UAC5B,MAAM,IAAI,aAAa,CAAC,OAAO,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"connectDB.mjs","names":[],"sources":["../../../../src/utils/mongoDB/connectDB.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { AccountModel } from '@schemas/account.schema';\nimport { AuditModel } from '@schemas/audit.schema';\nimport { AuditJobModel } from '@schemas/auditJob.schema';\nimport { AuditPageModel } from '@schemas/auditPage.schema';\nimport { DictionaryModel } from '@schemas/dictionary.schema';\nimport { DiscussionModel } from '@schemas/discussion.schema';\nimport { OAuth2AccessTokenModel } from '@schemas/oAuth2.schema';\nimport { OrganizationModel } from '@schemas/organization.schema';\nimport { ProjectModel } from '@schemas/project.schema';\nimport { ShowcaseProjectModel } from '@schemas/showcaseProject.schema';\nimport { TagModel } from '@schemas/tag.schema';\nimport { UserModel } from '@schemas/user.schema';\nimport { connect, type mongo } from 'mongoose';\n\n// Store the DB client singleton\nlet dbClientInstance: mongo.MongoClient | null = null;\n\nexport const connectDB = async (): Promise<mongo.MongoClient> => {\n try {\n const client = await connect(\n `mongodb+srv://${process.env.DB_ID}:${process.env.DB_MDP}@${process.env.DB_CLUSTER}/?retryWrites=true&w=majority&appName=Cluster0`\n );\n\n logger.info('MongoDB connected');\n\n // 2. Drop the old indexes directly\n const db = client.connection.db;\n if (db) {\n const collections = await db.collections();\n for (const col of collections) {\n await col.dropIndex('createdAt_1').catch(() => {});\n }\n }\n\n // Recreate indexes for models\n await ProjectModel.syncIndexes();\n await DiscussionModel.syncIndexes();\n await UserModel.createIndexes();\n await OAuth2AccessTokenModel.createIndexes();\n await TagModel.createIndexes();\n await DictionaryModel.createIndexes();\n await OrganizationModel.createIndexes();\n await AccountModel.createIndexes();\n await ShowcaseProjectModel.syncIndexes();\n await AuditModel.syncIndexes();\n await AuditJobModel.syncIndexes();\n await AuditPageModel.syncIndexes();\n\n dbClientInstance = client.connection.getClient();\n\n return dbClientInstance;\n } catch (error) {\n const errorMessage = `MongoDB connection error - ${(error as Error).message}`;\n\n logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n};\n\n/**\n * Get the MongoDB client instance.\n * Must be called after connectDB() has been executed.\n */\nexport const getDBClient = (): mongo.MongoClient => {\n if (!dbClientInstance) {\n throw new Error('Database not connected. Call connectDB() first.');\n }\n return dbClientInstance;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAI,mBAA6C;AAEjD,MAAa,YAAY,YAAwC;CAC/D,IAAI;EACF,MAAM,SAAS,MAAM,QACnB,iBAAiB,QAAQ,IAAI,MAAM,GAAG,QAAQ,IAAI,OAAO,GAAG,QAAQ,IAAI,WAAW,+CACrF;EAEA,OAAO,KAAK,mBAAmB;EAG/B,MAAM,KAAK,OAAO,WAAW;EAC7B,IAAI,IAAI;GACN,MAAM,cAAc,MAAM,GAAG,YAAY;GACzC,KAAK,MAAM,OAAO,aAChB,MAAM,IAAI,UAAU,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC;EAErD;EAGA,MAAM,aAAa,YAAY;EAC/B,MAAM,gBAAgB,YAAY;EAClC,MAAM,UAAU,cAAc;EAC9B,MAAM,uBAAuB,cAAc;EAC3C,MAAM,SAAS,cAAc;EAC7B,MAAM,gBAAgB,cAAc;EACpC,MAAM,kBAAkB,cAAc;EACtC,MAAM,aAAa,cAAc;EACjC,MAAM,qBAAqB,YAAY;EACvC,MAAM,WAAW,YAAY;EAC7B,MAAM,cAAc,YAAY;EAChC,MAAM,eAAe,YAAY;EAEjC,mBAAmB,OAAO,WAAW,UAAU;EAE/C,OAAO;CACT,SAAS,OAAO;EACd,MAAM,eAAe,8BAA+B,MAAgB;EAEpE,OAAO,MAAM,YAAY;EACzB,MAAM,IAAI,MAAM,YAAY;CAC9B;AACF;;;;;AAMA,MAAa,oBAAuC;CAClD,IAAI,CAAC,kBACH,MAAM,IAAI,MAAM,iDAAiD;CAEnE,OAAO;AACT"}
1
+ {"version":3,"file":"connectDB.mjs","names":[],"sources":["../../../../src/utils/mongoDB/connectDB.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { AccountModel } from '@schemas/account.schema';\nimport { AuditModel } from '@schemas/audit.schema';\nimport { AuditJobModel } from '@schemas/auditJob.schema';\nimport { AuditPageModel } from '@schemas/auditPage.schema';\nimport { DictionaryModel } from '@schemas/dictionary.schema';\nimport { DiscussionModel } from '@schemas/discussion.schema';\nimport { OAuth2AccessTokenModel } from '@schemas/oAuth2.schema';\nimport { OrganizationModel } from '@schemas/organization.schema';\nimport { ProjectModel } from '@schemas/project.schema';\nimport { ShowcaseProjectModel } from '@schemas/showcaseProject.schema';\nimport { TagModel } from '@schemas/tag.schema';\nimport { UserModel } from '@schemas/user.schema';\nimport { connect, type mongo } from 'mongoose';\n\n// Store the DB client singleton\nlet dbClientInstance: mongo.MongoClient | null = null;\n\nexport const connectDB = async (): Promise<mongo.MongoClient> => {\n try {\n const client = await connect(\n `mongodb+srv://${process.env.DB_ID}:${process.env.DB_MDP}@${process.env.DB_CLUSTER}/?retryWrites=true&w=majority&appName=Cluster0`\n );\n\n logger.info('MongoDB connected');\n\n // 2. Drop the old indexes directly\n const db = client.connection.db;\n if (db) {\n const collections = await db.collections();\n for (const col of collections) {\n await col.dropIndex('createdAt_1').catch(() => {});\n }\n }\n\n // Recreate indexes for models\n await ProjectModel.syncIndexes();\n await DiscussionModel.syncIndexes();\n await UserModel.createIndexes();\n await OAuth2AccessTokenModel.createIndexes();\n await TagModel.createIndexes();\n await DictionaryModel.createIndexes();\n await OrganizationModel.createIndexes();\n await AccountModel.createIndexes();\n await ShowcaseProjectModel.syncIndexes();\n await AuditModel.syncIndexes();\n await AuditJobModel.syncIndexes();\n await AuditPageModel.syncIndexes();\n\n dbClientInstance = client.connection.getClient();\n\n return dbClientInstance;\n } catch (error) {\n const errorMessage = `MongoDB connection error - ${(error as Error).message}`;\n\n logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n};\n\n/**\n * Get the MongoDB client instance.\n * Must be called after connectDB() has been executed.\n */\nexport const getDBClient = (): mongo.MongoClient => {\n if (!dbClientInstance) {\n throw new Error('Database not connected. Call connectDB() first.');\n }\n return dbClientInstance;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAI,mBAA6C;AAEjD,MAAa,YAAY,YAAwC;AAC/D,KAAI;EACF,MAAM,SAAS,MAAM,QACnB,iBAAiB,QAAQ,IAAI,MAAM,GAAG,QAAQ,IAAI,OAAO,GAAG,QAAQ,IAAI,WAAW,gDACpF;AAED,SAAO,KAAK,oBAAoB;EAGhC,MAAM,KAAK,OAAO,WAAW;AAC7B,MAAI,IAAI;GACN,MAAM,cAAc,MAAM,GAAG,aAAa;AAC1C,QAAK,MAAM,OAAO,YAChB,OAAM,IAAI,UAAU,cAAc,CAAC,YAAY,GAAG;;AAKtD,QAAM,aAAa,aAAa;AAChC,QAAM,gBAAgB,aAAa;AACnC,QAAM,UAAU,eAAe;AAC/B,QAAM,uBAAuB,eAAe;AAC5C,QAAM,SAAS,eAAe;AAC9B,QAAM,gBAAgB,eAAe;AACrC,QAAM,kBAAkB,eAAe;AACvC,QAAM,aAAa,eAAe;AAClC,QAAM,qBAAqB,aAAa;AACxC,QAAM,WAAW,aAAa;AAC9B,QAAM,cAAc,aAAa;AACjC,QAAM,eAAe,aAAa;AAElC,qBAAmB,OAAO,WAAW,WAAW;AAEhD,SAAO;UACA,OAAO;EACd,MAAM,eAAe,8BAA+B,MAAgB;AAEpE,SAAO,MAAM,aAAa;AAC1B,QAAM,IAAI,MAAM,aAAa;;;;;;;AAQjC,MAAa,oBAAuC;AAClD,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM,kDAAkD;AAEpE,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"oAuth2.mjs","names":[],"sources":["../../../src/utils/oAuth2.ts"],"sourcesContent":["import type OAuth2Server from '@node-oauth/oauth2-server';\nimport type { AuthenticateOptions } from '@node-oauth/oauth2-server';\nimport {\n getAccessToken,\n getClient,\n getUserFromClient,\n saveToken,\n verifyScope,\n} from '@services/oAuth2.service';\n\nexport const ACCESS_TOKEN_EXPIRES_IN = 60 * 60 * 24 * 7; // 7 days\n\n// Sliding refresh: when an access token is used and its remaining lifetime\n// drops below this threshold, push the expiry back to a full\n// ACCESS_TOKEN_EXPIRES_IN window. Keeps actively-used tokens alive without\n// minting a new one on every request.\nexport const ACCESS_TOKEN_REFRESH_THRESHOLD = 60 * 60 * 24; // 1 day\n\nexport const getTokenExpireAt = () =>\n new Date(Date.now() + ACCESS_TOKEN_EXPIRES_IN * 1000);\n\nexport const shouldExtendOAuth2Token = (expiresAt: Date | string): boolean => {\n const remainingMs = new Date(expiresAt).getTime() - Date.now();\n return remainingMs < ACCESS_TOKEN_REFRESH_THRESHOLD * 1000;\n};\n\nexport const authenticateOptions: AuthenticateOptions = {\n scope: undefined,\n addAcceptedScopesHeader: undefined,\n addAuthorizedScopesHeader: undefined,\n allowBearerTokensInQueryString: undefined,\n};\n\nexport const getAuthModel = (): OAuth2Server.ClientCredentialsModel => ({\n getClient,\n saveToken,\n getUserFromClient,\n verifyScope,\n getAccessToken,\n});\n"],"mappings":";;;AAUA,MAAa,0BAA0B,OAAU,KAAK;AAMtD,MAAa,iCAAiC,OAAU;AAExD,MAAa,yBACX,IAAI,KAAK,KAAK,IAAI,IAAI,0BAA0B,GAAI;AAEtD,MAAa,2BAA2B,cAAsC;CAE5E,OADoB,IAAI,KAAK,SAAS,CAAC,CAAC,QAAQ,IAAI,KAAK,IAAI,IACxC,iCAAiC;AACxD;AAEA,MAAa,sBAA2C;CACtD,OAAO;CACP,yBAAyB;CACzB,2BAA2B;CAC3B,gCAAgC;AAClC;AAEA,MAAa,sBAA2D;CACtE;CACA;CACA;CACA;CACA;AACF"}
1
+ {"version":3,"file":"oAuth2.mjs","names":[],"sources":["../../../src/utils/oAuth2.ts"],"sourcesContent":["import type OAuth2Server from '@node-oauth/oauth2-server';\nimport type { AuthenticateOptions } from '@node-oauth/oauth2-server';\nimport {\n getAccessToken,\n getClient,\n getUserFromClient,\n saveToken,\n verifyScope,\n} from '@services/oAuth2.service';\n\nexport const ACCESS_TOKEN_EXPIRES_IN = 60 * 60 * 24 * 7; // 7 days\n\n// Sliding refresh: when an access token is used and its remaining lifetime\n// drops below this threshold, push the expiry back to a full\n// ACCESS_TOKEN_EXPIRES_IN window. Keeps actively-used tokens alive without\n// minting a new one on every request.\nexport const ACCESS_TOKEN_REFRESH_THRESHOLD = 60 * 60 * 24; // 1 day\n\nexport const getTokenExpireAt = () =>\n new Date(Date.now() + ACCESS_TOKEN_EXPIRES_IN * 1000);\n\nexport const shouldExtendOAuth2Token = (expiresAt: Date | string): boolean => {\n const remainingMs = new Date(expiresAt).getTime() - Date.now();\n return remainingMs < ACCESS_TOKEN_REFRESH_THRESHOLD * 1000;\n};\n\nexport const authenticateOptions: AuthenticateOptions = {\n scope: undefined,\n addAcceptedScopesHeader: undefined,\n addAuthorizedScopesHeader: undefined,\n allowBearerTokensInQueryString: undefined,\n};\n\nexport const getAuthModel = (): OAuth2Server.ClientCredentialsModel => ({\n getClient,\n saveToken,\n getUserFromClient,\n verifyScope,\n getAccessToken,\n});\n"],"mappings":";;;AAUA,MAAa,0BAA0B,OAAU,KAAK;AAMtD,MAAa,iCAAiC,OAAU;AAExD,MAAa,yBACX,IAAI,KAAK,KAAK,KAAK,GAAG,0BAA0B,IAAK;AAEvD,MAAa,2BAA2B,cAAsC;AAE5E,QADoB,IAAI,KAAK,UAAU,CAAC,SAAS,GAAG,KAAK,KAAK,GACzC,iCAAiC;;AAGxD,MAAa,sBAA2C;CACtD,OAAO;CACP,yBAAyB;CACzB,2BAA2B;CAC3B,gCAAgC;CACjC;AAED,MAAa,sBAA2D;CACtE;CACA;CACA;CACA;CACA;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.mjs","names":[],"sources":["../../../src/utils/permissions.ts"],"sourcesContent":["import type { Dictionary, DictionaryAPI } from '@/types/dictionary.types';\nimport type { Organization, OrganizationAPI } from '@/types/organization.types';\nimport type { Project, ProjectAPI } from '@/types/project.types';\nimport type { SessionContext } from '@/types/session.types';\nimport type { Tag, TagAPI } from '@/types/tag.types';\nimport type { User, UserAPI } from '@/types/user.types';\n\n/**\n * A named grouping of privileges (e.g. `\"org_admin\"`).\n * Users are *granted* one or more Roles.\n */\nexport type Roles =\n | 'user'\n | 'admin'\n | 'org_admin'\n | 'org_user'\n | 'project_admin'\n | 'project_user'\n | 'project_reviewer';\n\n/**\n * An atomic operation that can be performed on a resource.\n * - **read**: view or list\n * - **write**: create or update\n * - **admin**: delete or change permissions\n */\nexport type Action = 'read' | 'write' | 'admin';\n\n/**\n * A first‑class entity in your domain model that you want to protect.\n */\nexport type Resource = {\n organization: Organization;\n project: Project;\n dictionary: Dictionary;\n tag: Tag;\n user: User;\n};\n\n/**\n * A literal string combining a Resource and an Action, e.g. `\"project:write\"`.\n * This is the *unit* checked at runtime in your middleware.\n */\nexport type Permission = `${keyof Resource}:${Action}`;\n\ntype CheckPrivilege = (\n args: any\n) => boolean | undefined | Promise<boolean> | Promise<undefined>;\n\ntype RolePolicy = Record<Roles, Partial<Record<Permission, CheckPrivilege>>>;\n\nexport const ROLE_POLICY = {\n admin: {\n 'organization:read': () => true,\n 'organization:write': () => true,\n 'organization:admin': () => true,\n 'project:read': () => true,\n 'project:write': () => true,\n 'project:admin': () => true,\n 'dictionary:read': () => true,\n 'dictionary:write': () => true,\n 'dictionary:admin': () => true,\n 'tag:read': () => true,\n 'tag:write': () => true,\n 'tag:admin': () => true,\n 'user:read': () => true,\n 'user:write': () => true,\n 'user:admin': () => true,\n },\n user: {\n 'user:read': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'user:write': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'user:admin': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'organization:read': ({\n user,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every((organization) =>\n organization?.membersIds?.map(String).includes(String(user?.id))\n ),\n },\n org_admin: {\n 'organization:read': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n 'organization:write': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n 'organization:admin': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n\n 'project:read': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'project:write': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'project:admin': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n\n 'tag:read': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'tag:write': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'tag:admin': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n\n 'user:write': ({\n organization,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n organization?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n org_user: {\n 'organization:read': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n\n 'project:read': ({\n user,\n targetProjects,\n }: SessionContext & {\n targetProjects: (Project | ProjectAPI)[];\n }) =>\n targetProjects?.every((project) =>\n project?.membersIds?.map(String).includes(String(user?.id))\n ),\n\n 'user:read': ({\n organization,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n organization?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n project_admin: {\n 'project:read': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n 'project:write': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n 'project:admin': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n\n 'tag:read': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:write': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:admin': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n\n 'user:write': ({\n project,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n project?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n\n 'dictionary:read': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n 'dictionary:write': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n 'dictionary:admin': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n },\n project_user: {\n 'project:read': ({ user, organization, project }: SessionContext) =>\n String(organization?.id) === String(project?.organizationId) &&\n organization?.membersIds?.map(String).includes(String(user?.id)) &&\n project?.membersIds?.map(String).includes(String(user?.id)),\n\n 'dictionary:read': ({\n user,\n project,\n targetDictionaries,\n }: SessionContext & {\n targetDictionaries: (Dictionary | DictionaryAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetDictionaries.every((dictionary) =>\n dictionary?.projectIds?.map(String).includes(String(project?.id))\n ),\n 'dictionary:write': ({ user, project }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n\n 'tag:read': ({\n project,\n targetTags,\n user,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:write': ({\n project,\n targetTags,\n user,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:admin': ({\n user,\n project,\n targetTags,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.adminsIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n\n 'user:read': ({\n project,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n project?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n project_reviewer: {\n 'project:read': ({ user, project }: SessionContext) =>\n (project as any)?.viewersIds?.map(String).includes(String(user?.id)),\n 'dictionary:read': ({ user, project }: SessionContext) =>\n (project as any)?.viewersIds?.map(String).includes(String(user?.id)),\n 'tag:read': () => true,\n },\n} as const satisfies RolePolicy;\n\nexport const getSessionRoles = (session?: SessionContext | null): Roles[] => {\n const { user, organization, project } = session ?? {};\n\n const roles: Roles[] = [];\n\n if (!user) {\n return roles;\n }\n\n roles.push('user');\n\n const isUserAdmin = user.role === 'admin';\n\n if (isUserAdmin) {\n roles.push('admin');\n }\n\n if (!organization) {\n return roles;\n }\n\n const isOrganizationAdmin = organization.adminsIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isOrganizationAdmin) {\n roles.push('org_admin');\n }\n\n const isOrganizationMember = organization.membersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isOrganizationMember) {\n roles.push('org_user');\n }\n\n if (!project) {\n return roles;\n }\n\n const isProjectAdmin = project.adminsIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectAdmin) {\n roles.push('project_admin');\n }\n\n const isProjectMember = project?.membersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectMember) {\n roles.push('project_user');\n }\n\n const isProjectReviewer = (project as any)?.viewersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectReviewer) {\n roles.push('project_reviewer');\n }\n\n return roles;\n};\n\nexport const computeEffectivePermission = (roles: Roles[]): Permission[] =>\n Array.from(\n new Set(\n roles.flatMap((role) => Object.keys(ROLE_POLICY[role]) as Permission[])\n )\n );\n\n/**\n * Intersect two permission lists\n * @param permissionList1 - The first permission list\n * @param permissionList2 - The second permission list\n * @returns The intersection of the two permission lists (only permissions present in both)\n */\nexport const intersectPermissions = (\n permissions1: Permission[],\n permissions2: Permission[]\n): Permission[] =>\n permissions1.filter((permission) => permissions2.includes(permission));\n\ntype PermissionResult<\n R extends Roles,\n P extends Permission,\n> = (typeof ROLE_POLICY)[R] extends infer RolePerms\n ? RolePerms extends Record<string, (args: any) => any>\n ? P extends keyof RolePerms\n ? RolePerms[P] extends undefined\n ? never\n : RolePerms[P]\n : never\n : never\n : never;\n\nexport const getSessionAccessConstraints = (session: SessionContext) => ({\n allowedEnvironmentIds: session.allowedEnvironmentIds ?? null,\n allowedLocales: session.allowedLocales ?? null,\n});\n\nexport const hasPermission = <P extends Permission>(\n roles: Roles[],\n permission: P\n): PermissionResult<Roles, P> => {\n const rolesCheck: any = roles.map(\n (role) =>\n ROLE_POLICY[role]?.[\n permission as keyof (typeof ROLE_POLICY)[typeof role]\n ] ?? (() => false)\n ) as unknown as PermissionResult<Roles, P>[];\n\n return ((args: any) => rolesCheck.some((check: any) => check(args))) as any;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"permissions.mjs","names":[],"sources":["../../../src/utils/permissions.ts"],"sourcesContent":["import type { Dictionary, DictionaryAPI } from '@/types/dictionary.types';\nimport type { Organization, OrganizationAPI } from '@/types/organization.types';\nimport type { Project, ProjectAPI } from '@/types/project.types';\nimport type { SessionContext } from '@/types/session.types';\nimport type { Tag, TagAPI } from '@/types/tag.types';\nimport type { User, UserAPI } from '@/types/user.types';\n\n/**\n * A named grouping of privileges (e.g. `\"org_admin\"`).\n * Users are *granted* one or more Roles.\n */\nexport type Roles =\n | 'user'\n | 'admin'\n | 'org_admin'\n | 'org_user'\n | 'project_admin'\n | 'project_user'\n | 'project_reviewer';\n\n/**\n * An atomic operation that can be performed on a resource.\n * - **read**: view or list\n * - **write**: create or update\n * - **admin**: delete or change permissions\n */\nexport type Action = 'read' | 'write' | 'admin';\n\n/**\n * A first‑class entity in your domain model that you want to protect.\n */\nexport type Resource = {\n organization: Organization;\n project: Project;\n dictionary: Dictionary;\n tag: Tag;\n user: User;\n};\n\n/**\n * A literal string combining a Resource and an Action, e.g. `\"project:write\"`.\n * This is the *unit* checked at runtime in your middleware.\n */\nexport type Permission = `${keyof Resource}:${Action}`;\n\ntype CheckPrivilege = (\n args: any\n) => boolean | undefined | Promise<boolean> | Promise<undefined>;\n\ntype RolePolicy = Record<Roles, Partial<Record<Permission, CheckPrivilege>>>;\n\nexport const ROLE_POLICY = {\n admin: {\n 'organization:read': () => true,\n 'organization:write': () => true,\n 'organization:admin': () => true,\n 'project:read': () => true,\n 'project:write': () => true,\n 'project:admin': () => true,\n 'dictionary:read': () => true,\n 'dictionary:write': () => true,\n 'dictionary:admin': () => true,\n 'tag:read': () => true,\n 'tag:write': () => true,\n 'tag:admin': () => true,\n 'user:read': () => true,\n 'user:write': () => true,\n 'user:admin': () => true,\n },\n user: {\n 'user:read': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'user:write': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'user:admin': ({\n user,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every(\n (targetUser) =>\n String(targetUser.id) === String(user?.id) &&\n targetUser.email === user?.email\n ),\n 'organization:read': ({\n user,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every((organization) =>\n organization?.membersIds?.map(String).includes(String(user?.id))\n ),\n },\n org_admin: {\n 'organization:read': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n 'organization:write': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n 'organization:admin': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n\n 'project:read': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'project:write': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'project:admin': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n\n 'tag:read': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'tag:write': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n 'tag:admin': ({ organization, project }: SessionContext) =>\n String(project?.organizationId) === String(organization?.id),\n\n 'user:write': ({\n organization,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n organization?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n org_user: {\n 'organization:read': ({\n organization,\n targetOrganizations,\n }: SessionContext & {\n targetOrganizations: (Organization | OrganizationAPI)[];\n }) =>\n targetOrganizations.every(\n (targetOrg) => String(targetOrg.id) === String(organization?.id)\n ),\n\n 'project:read': ({\n user,\n targetProjects,\n }: SessionContext & {\n targetProjects: (Project | ProjectAPI)[];\n }) =>\n targetProjects?.every((project) =>\n project?.membersIds?.map(String).includes(String(user?.id))\n ),\n\n 'user:read': ({\n organization,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n organization?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n project_admin: {\n 'project:read': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n 'project:write': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n 'project:admin': ({\n project,\n targetProjectIds,\n }: SessionContext & {\n targetProjectIds?: (Project | ProjectAPI)['id'][];\n }) =>\n targetProjectIds?.every(\n (projectId) => String(project?.id) === String(projectId)\n ),\n\n 'tag:read': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:write': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:admin': ({\n project,\n targetTags,\n }: SessionContext & { targetTags: (Tag | TagAPI)[] }) =>\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n\n 'user:write': ({\n project,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n project?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n\n 'dictionary:read': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n 'dictionary:write': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n 'dictionary:admin': ({ project, user }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n },\n project_user: {\n 'project:read': ({ user, organization, project }: SessionContext) =>\n String(organization?.id) === String(project?.organizationId) &&\n organization?.membersIds?.map(String).includes(String(user?.id)) &&\n project?.membersIds?.map(String).includes(String(user?.id)),\n\n 'dictionary:read': ({\n user,\n project,\n targetDictionaries,\n }: SessionContext & {\n targetDictionaries: (Dictionary | DictionaryAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetDictionaries.every((dictionary) =>\n dictionary?.projectIds?.map(String).includes(String(project?.id))\n ),\n 'dictionary:write': ({ user, project }: SessionContext) =>\n project?.adminsIds?.map(String).includes(String(user?.id)),\n\n 'tag:read': ({\n project,\n targetTags,\n user,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:write': ({\n project,\n targetTags,\n user,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.membersIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n 'tag:admin': ({\n user,\n project,\n targetTags,\n }: SessionContext & {\n targetTags: (Tag | TagAPI)[];\n }) =>\n project?.adminsIds?.map(String).includes(String(user?.id)) &&\n targetTags.every((tag) => String(project?.id) === String(tag?.projectId)),\n\n 'user:read': ({\n project,\n targetUsers,\n }: SessionContext & { targetUsers: (User | UserAPI)[] }) =>\n targetUsers.every((targetUser) =>\n project?.membersIds?.map(String).includes(String(targetUser?.id))\n ),\n },\n project_reviewer: {\n 'project:read': ({ user, project }: SessionContext) =>\n (project as any)?.viewersIds?.map(String).includes(String(user?.id)),\n 'dictionary:read': ({ user, project }: SessionContext) =>\n (project as any)?.viewersIds?.map(String).includes(String(user?.id)),\n 'tag:read': () => true,\n },\n} as const satisfies RolePolicy;\n\nexport const getSessionRoles = (session?: SessionContext | null): Roles[] => {\n const { user, organization, project } = session ?? {};\n\n const roles: Roles[] = [];\n\n if (!user) {\n return roles;\n }\n\n roles.push('user');\n\n const isUserAdmin = user.role === 'admin';\n\n if (isUserAdmin) {\n roles.push('admin');\n }\n\n if (!organization) {\n return roles;\n }\n\n const isOrganizationAdmin = organization.adminsIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isOrganizationAdmin) {\n roles.push('org_admin');\n }\n\n const isOrganizationMember = organization.membersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isOrganizationMember) {\n roles.push('org_user');\n }\n\n if (!project) {\n return roles;\n }\n\n const isProjectAdmin = project.adminsIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectAdmin) {\n roles.push('project_admin');\n }\n\n const isProjectMember = project?.membersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectMember) {\n roles.push('project_user');\n }\n\n const isProjectReviewer = (project as any)?.viewersIds\n ?.map(String)\n .includes(String(user?.id));\n\n if (isProjectReviewer) {\n roles.push('project_reviewer');\n }\n\n return roles;\n};\n\nexport const computeEffectivePermission = (roles: Roles[]): Permission[] =>\n Array.from(\n new Set(\n roles.flatMap((role) => Object.keys(ROLE_POLICY[role]) as Permission[])\n )\n );\n\n/**\n * Intersect two permission lists\n * @param permissionList1 - The first permission list\n * @param permissionList2 - The second permission list\n * @returns The intersection of the two permission lists (only permissions present in both)\n */\nexport const intersectPermissions = (\n permissions1: Permission[],\n permissions2: Permission[]\n): Permission[] =>\n permissions1.filter((permission) => permissions2.includes(permission));\n\ntype PermissionResult<\n R extends Roles,\n P extends Permission,\n> = (typeof ROLE_POLICY)[R] extends infer RolePerms\n ? RolePerms extends Record<string, (args: any) => any>\n ? P extends keyof RolePerms\n ? RolePerms[P] extends undefined\n ? never\n : RolePerms[P]\n : never\n : never\n : never;\n\nexport const getSessionAccessConstraints = (session: SessionContext) => ({\n allowedEnvironmentIds: session.allowedEnvironmentIds ?? null,\n allowedLocales: session.allowedLocales ?? null,\n});\n\nexport const hasPermission = <P extends Permission>(\n roles: Roles[],\n permission: P\n): PermissionResult<Roles, P> => {\n const rolesCheck: any = roles.map(\n (role) =>\n ROLE_POLICY[role]?.[\n permission as keyof (typeof ROLE_POLICY)[typeof role]\n ] ?? (() => false)\n ) as unknown as PermissionResult<Roles, P>[];\n\n return ((args: any) => rolesCheck.some((check: any) => check(args))) as any;\n};\n"],"mappings":"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"}