@intlayer/backend 5.6.0 → 5.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (508) hide show
  1. package/README.md +3 -0
  2. package/dist/cjs/controllers/ai.controller.cjs +10 -7
  3. package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
  4. package/dist/cjs/controllers/dictionary.controller.cjs +50 -58
  5. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  6. package/dist/cjs/controllers/eventListener.controller.cjs +2 -18
  7. package/dist/cjs/controllers/eventListener.controller.cjs.map +1 -1
  8. package/dist/cjs/controllers/newsletter.controller.cjs +38 -3
  9. package/dist/cjs/controllers/newsletter.controller.cjs.map +1 -1
  10. package/dist/cjs/controllers/oAuth2.controller.cjs +3 -3
  11. package/dist/cjs/controllers/oAuth2.controller.cjs.map +1 -1
  12. package/dist/cjs/controllers/organization.controller.cjs +92 -106
  13. package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
  14. package/dist/cjs/controllers/project.controller.cjs +81 -83
  15. package/dist/cjs/controllers/project.controller.cjs.map +1 -1
  16. package/dist/cjs/controllers/projectAccessKey.controller.cjs +30 -24
  17. package/dist/cjs/controllers/projectAccessKey.controller.cjs.map +1 -1
  18. package/dist/cjs/controllers/search.controller.cjs.map +1 -1
  19. package/dist/cjs/controllers/stripe.controller.cjs +4 -25
  20. package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
  21. package/dist/cjs/controllers/tag.controller.cjs +27 -16
  22. package/dist/cjs/controllers/tag.controller.cjs.map +1 -1
  23. package/dist/cjs/controllers/user.controller.cjs +88 -24
  24. package/dist/cjs/controllers/user.controller.cjs.map +1 -1
  25. package/dist/cjs/emails/InviteUserEmail.cjs +30 -12
  26. package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
  27. package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs +266 -0
  28. package/dist/cjs/emails/OAuthTokenCreatedEmail.cjs.map +1 -0
  29. package/dist/cjs/emails/ResetUserPassword.cjs +27 -15
  30. package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
  31. package/dist/cjs/emails/ValidateUserEmail.cjs +27 -36
  32. package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
  33. package/dist/cjs/emails/Welcome.cjs +27 -15
  34. package/dist/cjs/emails/Welcome.cjs.map +1 -1
  35. package/dist/cjs/emails/index.cjs +7 -5
  36. package/dist/cjs/emails/index.cjs.map +1 -1
  37. package/dist/cjs/export.cjs +2 -5
  38. package/dist/cjs/export.cjs.map +1 -1
  39. package/dist/cjs/index.cjs +61 -111
  40. package/dist/cjs/index.cjs.map +1 -1
  41. package/dist/cjs/middlewares/oAuth2.middleware.cjs +26 -38
  42. package/dist/cjs/middlewares/oAuth2.middleware.cjs.map +1 -1
  43. package/dist/cjs/middlewares/request.middleware.cjs.map +1 -1
  44. package/dist/cjs/middlewares/sessionAuth.middleware.cjs +17 -138
  45. package/dist/cjs/middlewares/sessionAuth.middleware.cjs.map +1 -1
  46. package/dist/cjs/models/dictionary.model.cjs.map +1 -1
  47. package/dist/cjs/models/discussion.model.cjs.map +1 -1
  48. package/dist/cjs/models/oAuth2.model.cjs +4 -1
  49. package/dist/cjs/models/oAuth2.model.cjs.map +1 -1
  50. package/dist/cjs/models/organization.model.cjs +1 -4
  51. package/dist/cjs/models/organization.model.cjs.map +1 -1
  52. package/dist/cjs/models/project.model.cjs +4 -1
  53. package/dist/cjs/models/project.model.cjs.map +1 -1
  54. package/dist/cjs/models/session.model.cjs +34 -0
  55. package/dist/cjs/models/session.model.cjs.map +1 -0
  56. package/dist/cjs/models/tag.model.cjs.map +1 -1
  57. package/dist/cjs/models/user.model.cjs.map +1 -1
  58. package/dist/cjs/routes/ai.routes.cjs +3 -1
  59. package/dist/cjs/routes/ai.routes.cjs.map +1 -1
  60. package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
  61. package/dist/cjs/routes/eventListener.routes.cjs +1 -1
  62. package/dist/cjs/routes/eventListener.routes.cjs.map +1 -1
  63. package/dist/cjs/routes/newsletter.routes.cjs.map +1 -1
  64. package/dist/cjs/routes/organization.routes.cjs +8 -8
  65. package/dist/cjs/routes/organization.routes.cjs.map +1 -1
  66. package/dist/cjs/routes/project.routes.cjs +23 -14
  67. package/dist/cjs/routes/project.routes.cjs.map +1 -1
  68. package/dist/cjs/routes/search.routes.cjs.map +1 -1
  69. package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
  70. package/dist/cjs/routes/tags.routes.cjs +4 -4
  71. package/dist/cjs/routes/tags.routes.cjs.map +1 -1
  72. package/dist/cjs/routes/user.routes.cjs +12 -12
  73. package/dist/cjs/routes/user.routes.cjs.map +1 -1
  74. package/dist/cjs/schemas/dictionary.schema.cjs +18 -1
  75. package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
  76. package/dist/cjs/schemas/discussion.schema.cjs +18 -1
  77. package/dist/cjs/schemas/discussion.schema.cjs.map +1 -1
  78. package/dist/cjs/schemas/oAuth2.schema.cjs +18 -1
  79. package/dist/cjs/schemas/oAuth2.schema.cjs.map +1 -1
  80. package/dist/cjs/schemas/organization.schema.cjs +21 -1
  81. package/dist/cjs/schemas/organization.schema.cjs.map +1 -1
  82. package/dist/cjs/schemas/plans.schema.cjs +18 -1
  83. package/dist/cjs/schemas/plans.schema.cjs.map +1 -1
  84. package/dist/cjs/schemas/project.schema.cjs +19 -14
  85. package/dist/cjs/schemas/project.schema.cjs.map +1 -1
  86. package/dist/cjs/schemas/session.schema.cjs +63 -0
  87. package/dist/cjs/schemas/session.schema.cjs.map +1 -0
  88. package/dist/cjs/schemas/tag.schema.cjs +18 -1
  89. package/dist/cjs/schemas/tag.schema.cjs.map +1 -1
  90. package/dist/cjs/schemas/user.schema.cjs +18 -48
  91. package/dist/cjs/schemas/user.schema.cjs.map +1 -1
  92. package/dist/cjs/services/dictionary.service.cjs +6 -5
  93. package/dist/cjs/services/dictionary.service.cjs.map +1 -1
  94. package/dist/cjs/services/email.service.cjs +13 -0
  95. package/dist/cjs/services/email.service.cjs.map +1 -1
  96. package/dist/cjs/services/oAuth2.service.cjs +49 -10
  97. package/dist/cjs/services/oAuth2.service.cjs.map +1 -1
  98. package/dist/cjs/services/organization.service.cjs +16 -15
  99. package/dist/cjs/services/organization.service.cjs.map +1 -1
  100. package/dist/cjs/services/project.service.cjs +1 -1
  101. package/dist/cjs/services/project.service.cjs.map +1 -1
  102. package/dist/cjs/services/projectAccessKey.service.cjs +17 -33
  103. package/dist/cjs/services/projectAccessKey.service.cjs.map +1 -1
  104. package/dist/cjs/services/subscription.service.cjs +10 -10
  105. package/dist/cjs/services/subscription.service.cjs.map +1 -1
  106. package/dist/cjs/services/tag.service.cjs.map +1 -1
  107. package/dist/cjs/services/user.service.cjs +2 -42
  108. package/dist/cjs/services/user.service.cjs.map +1 -1
  109. package/dist/cjs/types/dictionary.types.cjs.map +1 -1
  110. package/dist/cjs/types/discussion.types.cjs.map +1 -1
  111. package/dist/cjs/types/oAuth2.types.cjs.map +1 -1
  112. package/dist/cjs/types/organization.types.cjs.map +1 -1
  113. package/dist/cjs/types/plan.types.cjs.map +1 -1
  114. package/dist/cjs/types/project.types.cjs.map +1 -1
  115. package/dist/cjs/types/session.types.cjs.map +1 -1
  116. package/dist/cjs/types/tag.types.cjs.map +1 -1
  117. package/dist/cjs/types/user.types.cjs.map +1 -1
  118. package/dist/cjs/utils/AI/aiSdk.cjs.map +1 -1
  119. package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs +14 -9
  120. package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs.map +1 -1
  121. package/dist/cjs/utils/AI/autocomplete/PROMPT.md +18 -2
  122. package/dist/cjs/utils/AI/autocomplete/index.cjs +8 -5
  123. package/dist/cjs/utils/AI/autocomplete/index.cjs.map +1 -1
  124. package/dist/cjs/utils/access.cjs +2 -0
  125. package/dist/cjs/utils/access.cjs.map +1 -0
  126. package/dist/cjs/utils/accessControl.cjs +7 -0
  127. package/dist/cjs/utils/accessControl.cjs.map +1 -1
  128. package/dist/cjs/utils/auth/getAuth.cjs +248 -0
  129. package/dist/cjs/utils/auth/getAuth.cjs.map +1 -0
  130. package/dist/cjs/utils/cors.cjs +55 -0
  131. package/dist/cjs/utils/cors.cjs.map +1 -0
  132. package/dist/cjs/utils/ensureMongoDocumentToObject.cjs.map +1 -1
  133. package/dist/cjs/utils/errors/ErrorHandler.cjs +2 -2
  134. package/dist/cjs/utils/errors/ErrorHandler.cjs.map +1 -1
  135. package/dist/cjs/utils/errors/errorCodes.cjs +114 -153
  136. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  137. package/dist/cjs/utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs.map +1 -1
  138. package/dist/cjs/utils/filtersAndPagination/getProjectFiltersAndPagination.cjs.map +1 -1
  139. package/dist/cjs/utils/filtersAndPagination/getTagFiltersAndPagination.cjs.map +1 -1
  140. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs +1 -1
  141. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs.map +1 -1
  142. package/dist/cjs/utils/mapper/dictionary.cjs.map +1 -1
  143. package/dist/cjs/utils/mapper/organization.cjs +10 -8
  144. package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
  145. package/dist/cjs/utils/mapper/project.cjs +5 -18
  146. package/dist/cjs/utils/mapper/project.cjs.map +1 -1
  147. package/dist/cjs/utils/mapper/tag.cjs +4 -2
  148. package/dist/cjs/utils/mapper/tag.cjs.map +1 -1
  149. package/dist/cjs/utils/mapper/user.cjs +6 -3
  150. package/dist/cjs/utils/mapper/user.cjs.map +1 -1
  151. package/dist/cjs/utils/mergeFunctionTypes.cjs +17 -0
  152. package/dist/cjs/utils/mergeFunctionTypes.cjs.map +1 -0
  153. package/dist/cjs/utils/mongoDB/connectDB.cjs +3 -1
  154. package/dist/cjs/utils/mongoDB/connectDB.cjs.map +1 -1
  155. package/dist/cjs/utils/mongoDB/types.cjs +17 -0
  156. package/dist/cjs/utils/mongoDB/types.cjs.map +1 -0
  157. package/dist/cjs/utils/oAuth2.cjs.map +1 -1
  158. package/dist/cjs/utils/permissions.cjs +166 -0
  159. package/dist/cjs/utils/permissions.cjs.map +1 -0
  160. package/dist/cjs/utils/rateLimiter.cjs +88 -0
  161. package/dist/cjs/utils/rateLimiter.cjs.map +1 -0
  162. package/dist/esm/controllers/ai.controller.mjs +10 -7
  163. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  164. package/dist/esm/controllers/dictionary.controller.mjs +50 -58
  165. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  166. package/dist/esm/controllers/eventListener.controller.mjs +2 -8
  167. package/dist/esm/controllers/eventListener.controller.mjs.map +1 -1
  168. package/dist/esm/controllers/newsletter.controller.mjs +38 -3
  169. package/dist/esm/controllers/newsletter.controller.mjs.map +1 -1
  170. package/dist/esm/controllers/oAuth2.controller.mjs +2 -2
  171. package/dist/esm/controllers/oAuth2.controller.mjs.map +1 -1
  172. package/dist/esm/controllers/organization.controller.mjs +95 -106
  173. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  174. package/dist/esm/controllers/project.controller.mjs +81 -83
  175. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  176. package/dist/esm/controllers/projectAccessKey.controller.mjs +30 -24
  177. package/dist/esm/controllers/projectAccessKey.controller.mjs.map +1 -1
  178. package/dist/esm/controllers/search.controller.mjs.map +1 -1
  179. package/dist/esm/controllers/stripe.controller.mjs +4 -25
  180. package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
  181. package/dist/esm/controllers/tag.controller.mjs +27 -16
  182. package/dist/esm/controllers/tag.controller.mjs.map +1 -1
  183. package/dist/esm/controllers/user.controller.mjs +85 -22
  184. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  185. package/dist/esm/emails/InviteUserEmail.mjs +32 -14
  186. package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
  187. package/dist/esm/emails/OAuthTokenCreatedEmail.mjs +254 -0
  188. package/dist/esm/emails/OAuthTokenCreatedEmail.mjs.map +1 -0
  189. package/dist/esm/emails/ResetUserPassword.mjs +29 -17
  190. package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
  191. package/dist/esm/emails/ValidateUserEmail.mjs +29 -38
  192. package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
  193. package/dist/esm/emails/Welcome.mjs +29 -17
  194. package/dist/esm/emails/Welcome.mjs.map +1 -1
  195. package/dist/esm/emails/index.mjs +3 -2
  196. package/dist/esm/emails/index.mjs.map +1 -1
  197. package/dist/esm/export.mjs +1 -3
  198. package/dist/esm/export.mjs.map +1 -1
  199. package/dist/esm/index.mjs +60 -111
  200. package/dist/esm/index.mjs.map +1 -1
  201. package/dist/esm/middlewares/oAuth2.middleware.mjs +27 -36
  202. package/dist/esm/middlewares/oAuth2.middleware.mjs.map +1 -1
  203. package/dist/esm/middlewares/request.middleware.mjs.map +1 -1
  204. package/dist/esm/middlewares/sessionAuth.middleware.mjs +16 -127
  205. package/dist/esm/middlewares/sessionAuth.middleware.mjs.map +1 -1
  206. package/dist/esm/models/dictionary.model.mjs.map +1 -1
  207. package/dist/esm/models/discussion.model.mjs.map +1 -1
  208. package/dist/esm/models/oAuth2.model.mjs +4 -1
  209. package/dist/esm/models/oAuth2.model.mjs.map +1 -1
  210. package/dist/esm/models/organization.model.mjs +1 -4
  211. package/dist/esm/models/organization.model.mjs.map +1 -1
  212. package/dist/esm/models/project.model.mjs +4 -1
  213. package/dist/esm/models/project.model.mjs.map +1 -1
  214. package/dist/esm/models/session.model.mjs +10 -0
  215. package/dist/esm/models/session.model.mjs.map +1 -0
  216. package/dist/esm/models/tag.model.mjs.map +1 -1
  217. package/dist/esm/models/user.model.mjs.map +1 -1
  218. package/dist/esm/routes/ai.routes.mjs +3 -1
  219. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  220. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  221. package/dist/esm/routes/eventListener.routes.mjs +1 -1
  222. package/dist/esm/routes/eventListener.routes.mjs.map +1 -1
  223. package/dist/esm/routes/newsletter.routes.mjs.map +1 -1
  224. package/dist/esm/routes/organization.routes.mjs +8 -8
  225. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  226. package/dist/esm/routes/project.routes.mjs +23 -14
  227. package/dist/esm/routes/project.routes.mjs.map +1 -1
  228. package/dist/esm/routes/search.routes.mjs.map +1 -1
  229. package/dist/esm/routes/stripe.routes.mjs.map +1 -1
  230. package/dist/esm/routes/tags.routes.mjs +4 -4
  231. package/dist/esm/routes/tags.routes.mjs.map +1 -1
  232. package/dist/esm/routes/user.routes.mjs +14 -14
  233. package/dist/esm/routes/user.routes.mjs.map +1 -1
  234. package/dist/esm/schemas/dictionary.schema.mjs +18 -1
  235. package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
  236. package/dist/esm/schemas/discussion.schema.mjs +18 -1
  237. package/dist/esm/schemas/discussion.schema.mjs.map +1 -1
  238. package/dist/esm/schemas/oAuth2.schema.mjs +18 -1
  239. package/dist/esm/schemas/oAuth2.schema.mjs.map +1 -1
  240. package/dist/esm/schemas/organization.schema.mjs +21 -1
  241. package/dist/esm/schemas/organization.schema.mjs.map +1 -1
  242. package/dist/esm/schemas/plans.schema.mjs +18 -1
  243. package/dist/esm/schemas/plans.schema.mjs.map +1 -1
  244. package/dist/esm/schemas/project.schema.mjs +21 -15
  245. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  246. package/dist/esm/schemas/session.schema.mjs +39 -0
  247. package/dist/esm/schemas/session.schema.mjs.map +1 -0
  248. package/dist/esm/schemas/tag.schema.mjs +21 -4
  249. package/dist/esm/schemas/tag.schema.mjs.map +1 -1
  250. package/dist/esm/schemas/user.schema.mjs +18 -48
  251. package/dist/esm/schemas/user.schema.mjs.map +1 -1
  252. package/dist/esm/services/dictionary.service.mjs +6 -5
  253. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  254. package/dist/esm/services/email.service.mjs +33 -16
  255. package/dist/esm/services/email.service.mjs.map +1 -1
  256. package/dist/esm/services/oAuth2.service.mjs +47 -10
  257. package/dist/esm/services/oAuth2.service.mjs.map +1 -1
  258. package/dist/esm/services/organization.service.mjs +16 -14
  259. package/dist/esm/services/organization.service.mjs.map +1 -1
  260. package/dist/esm/services/project.service.mjs +1 -1
  261. package/dist/esm/services/project.service.mjs.map +1 -1
  262. package/dist/esm/services/projectAccessKey.service.mjs +15 -31
  263. package/dist/esm/services/projectAccessKey.service.mjs.map +1 -1
  264. package/dist/esm/services/subscription.service.mjs +10 -10
  265. package/dist/esm/services/subscription.service.mjs.map +1 -1
  266. package/dist/esm/services/tag.service.mjs.map +1 -1
  267. package/dist/esm/services/user.service.mjs +2 -40
  268. package/dist/esm/services/user.service.mjs.map +1 -1
  269. package/dist/esm/types/user.types.mjs.map +1 -1
  270. package/dist/esm/utils/AI/aiSdk.mjs.map +1 -1
  271. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs +14 -9
  272. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -1
  273. package/dist/esm/utils/AI/autocomplete/PROMPT.md +18 -2
  274. package/dist/esm/utils/AI/autocomplete/index.mjs +8 -5
  275. package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -1
  276. package/dist/esm/utils/access.mjs +1 -0
  277. package/dist/esm/utils/access.mjs.map +1 -0
  278. package/dist/esm/utils/accessControl.mjs +7 -0
  279. package/dist/esm/utils/accessControl.mjs.map +1 -1
  280. package/dist/esm/utils/auth/getAuth.mjs +227 -0
  281. package/dist/esm/utils/auth/getAuth.mjs.map +1 -0
  282. package/dist/esm/utils/cors.mjs +31 -0
  283. package/dist/esm/utils/cors.mjs.map +1 -0
  284. package/dist/esm/utils/ensureMongoDocumentToObject.mjs.map +1 -1
  285. package/dist/esm/utils/errors/ErrorHandler.mjs +2 -2
  286. package/dist/esm/utils/errors/ErrorHandler.mjs.map +1 -1
  287. package/dist/esm/utils/errors/errorCodes.mjs +114 -153
  288. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  289. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
  290. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
  291. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -1
  292. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs +1 -1
  293. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
  294. package/dist/esm/utils/mapper/dictionary.mjs.map +1 -1
  295. package/dist/esm/utils/mapper/organization.mjs +8 -7
  296. package/dist/esm/utils/mapper/organization.mjs.map +1 -1
  297. package/dist/esm/utils/mapper/project.mjs +5 -18
  298. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  299. package/dist/esm/utils/mapper/tag.mjs +4 -2
  300. package/dist/esm/utils/mapper/tag.mjs.map +1 -1
  301. package/dist/esm/utils/mapper/user.mjs +6 -3
  302. package/dist/esm/utils/mapper/user.mjs.map +1 -1
  303. package/dist/esm/utils/mergeFunctionTypes.mjs +1 -0
  304. package/dist/esm/utils/mergeFunctionTypes.mjs.map +1 -0
  305. package/dist/esm/utils/mongoDB/connectDB.mjs +3 -1
  306. package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
  307. package/dist/esm/utils/mongoDB/types.mjs +1 -0
  308. package/dist/esm/utils/mongoDB/types.mjs.map +1 -0
  309. package/dist/esm/utils/oAuth2.mjs +3 -3
  310. package/dist/esm/utils/oAuth2.mjs.map +1 -1
  311. package/dist/esm/utils/permissions.mjs +138 -0
  312. package/dist/esm/utils/permissions.mjs.map +1 -0
  313. package/dist/esm/utils/rateLimiter.mjs +53 -0
  314. package/dist/esm/utils/rateLimiter.mjs.map +1 -0
  315. package/dist/types/controllers/ai.controller.d.ts +12 -10
  316. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  317. package/dist/types/controllers/dictionary.controller.d.ts +8 -9
  318. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  319. package/dist/types/controllers/eventListener.controller.d.ts +2 -3
  320. package/dist/types/controllers/eventListener.controller.d.ts.map +1 -1
  321. package/dist/types/controllers/newsletter.controller.d.ts +5 -6
  322. package/dist/types/controllers/newsletter.controller.d.ts.map +1 -1
  323. package/dist/types/controllers/oAuth2.controller.d.ts +3 -3
  324. package/dist/types/controllers/oAuth2.controller.d.ts.map +1 -1
  325. package/dist/types/controllers/organization.controller.d.ts +22 -23
  326. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  327. package/dist/types/controllers/project.controller.d.ts +13 -14
  328. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  329. package/dist/types/controllers/projectAccessKey.controller.d.ts +5 -6
  330. package/dist/types/controllers/projectAccessKey.controller.d.ts.map +1 -1
  331. package/dist/types/controllers/search.controller.d.ts +2 -3
  332. package/dist/types/controllers/search.controller.d.ts.map +1 -1
  333. package/dist/types/controllers/stripe.controller.d.ts +5 -6
  334. package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
  335. package/dist/types/controllers/tag.controller.d.ts +9 -10
  336. package/dist/types/controllers/tag.controller.d.ts.map +1 -1
  337. package/dist/types/controllers/user.controller.d.ts +16 -19
  338. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  339. package/dist/types/emails/InviteUserEmail.d.ts.map +1 -1
  340. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts +21 -0
  341. package/dist/types/emails/OAuthTokenCreatedEmail.d.ts.map +1 -0
  342. package/dist/types/emails/ResetUserPassword.d.ts.map +1 -1
  343. package/dist/types/emails/Welcome.d.ts.map +1 -1
  344. package/dist/types/emails/index.d.ts +3 -2
  345. package/dist/types/emails/index.d.ts.map +1 -1
  346. package/dist/types/export.d.ts +2 -3
  347. package/dist/types/export.d.ts.map +1 -1
  348. package/dist/types/index.d.ts +1 -3
  349. package/dist/types/index.d.ts.map +1 -1
  350. package/dist/types/middlewares/oAuth2.middleware.d.ts +1 -2
  351. package/dist/types/middlewares/oAuth2.middleware.d.ts.map +1 -1
  352. package/dist/types/middlewares/request.middleware.d.ts +3 -3
  353. package/dist/types/middlewares/request.middleware.d.ts.map +1 -1
  354. package/dist/types/middlewares/sessionAuth.middleware.d.ts +3 -25
  355. package/dist/types/middlewares/sessionAuth.middleware.d.ts.map +1 -1
  356. package/dist/types/models/dictionary.model.d.ts +6 -5
  357. package/dist/types/models/dictionary.model.d.ts.map +1 -1
  358. package/dist/types/models/discussion.model.d.ts +7 -2
  359. package/dist/types/models/discussion.model.d.ts.map +1 -1
  360. package/dist/types/models/oAuth2.model.d.ts +3 -2
  361. package/dist/types/models/oAuth2.model.d.ts.map +1 -1
  362. package/dist/types/models/organization.model.d.ts +2 -12
  363. package/dist/types/models/organization.model.d.ts.map +1 -1
  364. package/dist/types/models/project.model.d.ts +2 -11
  365. package/dist/types/models/project.model.d.ts.map +1 -1
  366. package/dist/types/models/session.model.d.ts +3 -0
  367. package/dist/types/models/session.model.d.ts.map +1 -0
  368. package/dist/types/models/tag.model.d.ts.map +1 -1
  369. package/dist/types/models/user.model.d.ts.map +1 -1
  370. package/dist/types/routes/ai.routes.d.ts.map +1 -1
  371. package/dist/types/routes/organization.routes.d.ts +4 -4
  372. package/dist/types/routes/project.routes.d.ts +4 -4
  373. package/dist/types/routes/project.routes.d.ts.map +1 -1
  374. package/dist/types/routes/tags.routes.d.ts +2 -2
  375. package/dist/types/routes/user.routes.d.ts +6 -7
  376. package/dist/types/routes/user.routes.d.ts.map +1 -1
  377. package/dist/types/schemas/dictionary.schema.d.ts +6 -8
  378. package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
  379. package/dist/types/schemas/discussion.schema.d.ts +7 -5
  380. package/dist/types/schemas/discussion.schema.d.ts.map +1 -1
  381. package/dist/types/schemas/oAuth2.schema.d.ts +4 -3
  382. package/dist/types/schemas/oAuth2.schema.d.ts.map +1 -1
  383. package/dist/types/schemas/organization.schema.d.ts +6 -10
  384. package/dist/types/schemas/organization.schema.d.ts.map +1 -1
  385. package/dist/types/schemas/plans.schema.d.ts +6 -8
  386. package/dist/types/schemas/plans.schema.d.ts.map +1 -1
  387. package/dist/types/schemas/project.schema.d.ts +5 -17
  388. package/dist/types/schemas/project.schema.d.ts.map +1 -1
  389. package/dist/types/schemas/session.schema.d.ts +14 -0
  390. package/dist/types/schemas/session.schema.d.ts.map +1 -0
  391. package/dist/types/schemas/tag.schema.d.ts +6 -8
  392. package/dist/types/schemas/tag.schema.d.ts.map +1 -1
  393. package/dist/types/schemas/user.schema.d.ts +7 -5
  394. package/dist/types/schemas/user.schema.d.ts.map +1 -1
  395. package/dist/types/services/dictionary.service.d.ts +9 -9
  396. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  397. package/dist/types/services/email.service.d.ts +4 -0
  398. package/dist/types/services/email.service.d.ts.map +1 -1
  399. package/dist/types/services/oAuth2.service.d.ts +23 -14
  400. package/dist/types/services/oAuth2.service.d.ts.map +1 -1
  401. package/dist/types/services/organization.service.d.ts +6 -12
  402. package/dist/types/services/organization.service.d.ts.map +1 -1
  403. package/dist/types/services/project.service.d.ts +5 -5
  404. package/dist/types/services/project.service.d.ts.map +1 -1
  405. package/dist/types/services/projectAccessKey.service.d.ts +5 -5
  406. package/dist/types/services/projectAccessKey.service.d.ts.map +1 -1
  407. package/dist/types/services/subscription.service.d.ts +1 -1
  408. package/dist/types/services/subscription.service.d.ts.map +1 -1
  409. package/dist/types/services/tag.service.d.ts +6 -6
  410. package/dist/types/services/tag.service.d.ts.map +1 -1
  411. package/dist/types/services/user.service.d.ts +7 -21
  412. package/dist/types/services/user.service.d.ts.map +1 -1
  413. package/dist/types/types/dictionary.types.d.ts +11 -9
  414. package/dist/types/types/dictionary.types.d.ts.map +1 -1
  415. package/dist/types/types/discussion.types.d.ts +5 -2
  416. package/dist/types/types/discussion.types.d.ts.map +1 -1
  417. package/dist/types/types/oAuth2.types.d.ts +5 -2
  418. package/dist/types/types/oAuth2.types.d.ts.map +1 -1
  419. package/dist/types/types/organization.types.d.ts +11 -8
  420. package/dist/types/types/organization.types.d.ts.map +1 -1
  421. package/dist/types/types/plan.types.d.ts +6 -3
  422. package/dist/types/types/plan.types.d.ts.map +1 -1
  423. package/dist/types/types/project.types.d.ts +25 -25
  424. package/dist/types/types/project.types.d.ts.map +1 -1
  425. package/dist/types/types/session.types.d.ts +31 -17
  426. package/dist/types/types/session.types.d.ts.map +1 -1
  427. package/dist/types/types/tag.types.d.ts +8 -6
  428. package/dist/types/types/tag.types.d.ts.map +1 -1
  429. package/dist/types/types/user.types.d.ts +14 -21
  430. package/dist/types/types/user.types.d.ts.map +1 -1
  431. package/dist/types/utils/AI/aiSdk.d.ts +2 -2
  432. package/dist/types/utils/AI/aiSdk.d.ts.map +1 -1
  433. package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -1
  434. package/dist/types/utils/AI/autocomplete/index.d.ts +4 -1
  435. package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -1
  436. package/dist/types/utils/access.d.ts +1 -0
  437. package/dist/types/utils/access.d.ts.map +1 -0
  438. package/dist/types/utils/accessControl.d.ts +9 -9
  439. package/dist/types/utils/accessControl.d.ts.map +1 -1
  440. package/dist/types/utils/auth/getAuth.d.ts +7 -0
  441. package/dist/types/utils/auth/getAuth.d.ts.map +1 -0
  442. package/dist/types/utils/cors.d.ts +3 -0
  443. package/dist/types/utils/cors.d.ts.map +1 -0
  444. package/dist/types/utils/ensureMongoDocumentToObject.d.ts +2 -2
  445. package/dist/types/utils/ensureMongoDocumentToObject.d.ts.map +1 -1
  446. package/dist/types/utils/errors/ErrorHandler.d.ts +1 -1
  447. package/dist/types/utils/errors/ErrorHandler.d.ts.map +1 -1
  448. package/dist/types/utils/errors/errorCodes.d.ts +57 -96
  449. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  450. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts +1 -1
  451. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
  452. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts +1 -1
  453. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
  454. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +1 -1
  455. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -1
  456. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts +1 -1
  457. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
  458. package/dist/types/utils/mapper/dictionary.d.ts +1 -1
  459. package/dist/types/utils/mapper/dictionary.d.ts.map +1 -1
  460. package/dist/types/utils/mapper/organization.d.ts +3 -2
  461. package/dist/types/utils/mapper/organization.d.ts.map +1 -1
  462. package/dist/types/utils/mapper/project.d.ts +4 -5
  463. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  464. package/dist/types/utils/mapper/tag.d.ts +1 -1
  465. package/dist/types/utils/mapper/tag.d.ts.map +1 -1
  466. package/dist/types/utils/mapper/user.d.ts +2 -2
  467. package/dist/types/utils/mapper/user.d.ts.map +1 -1
  468. package/dist/types/utils/mergeFunctionTypes.d.ts +18 -0
  469. package/dist/types/utils/mergeFunctionTypes.d.ts.map +1 -0
  470. package/dist/types/utils/mongoDB/connectDB.d.ts +1 -1
  471. package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
  472. package/dist/types/utils/mongoDB/types.d.ts +11 -0
  473. package/dist/types/utils/mongoDB/types.d.ts.map +1 -0
  474. package/dist/types/utils/permissions.d.ts +115 -0
  475. package/dist/types/utils/permissions.d.ts.map +1 -0
  476. package/dist/types/utils/rateLimiter.d.ts +4 -0
  477. package/dist/types/utils/rateLimiter.d.ts.map +1 -0
  478. package/package.json +14 -14
  479. package/dist/cjs/controllers/sessionAuth.controller.cjs +0 -839
  480. package/dist/cjs/controllers/sessionAuth.controller.cjs.map +0 -1
  481. package/dist/cjs/routes/sessionAuth.routes.cjs +0 -154
  482. package/dist/cjs/routes/sessionAuth.routes.cjs.map +0 -1
  483. package/dist/cjs/services/sessionAuth.service.cjs +0 -385
  484. package/dist/cjs/services/sessionAuth.service.cjs.map +0 -1
  485. package/dist/cjs/utils/CSRF.cjs +0 -50
  486. package/dist/cjs/utils/CSRF.cjs.map +0 -1
  487. package/dist/cjs/utils/cookies.cjs +0 -59
  488. package/dist/cjs/utils/cookies.cjs.map +0 -1
  489. package/dist/esm/controllers/sessionAuth.controller.mjs +0 -790
  490. package/dist/esm/controllers/sessionAuth.controller.mjs.map +0 -1
  491. package/dist/esm/routes/sessionAuth.routes.mjs +0 -142
  492. package/dist/esm/routes/sessionAuth.routes.mjs.map +0 -1
  493. package/dist/esm/services/sessionAuth.service.mjs +0 -337
  494. package/dist/esm/services/sessionAuth.service.mjs.map +0 -1
  495. package/dist/esm/utils/CSRF.mjs +0 -24
  496. package/dist/esm/utils/CSRF.mjs.map +0 -1
  497. package/dist/esm/utils/cookies.mjs +0 -32
  498. package/dist/esm/utils/cookies.mjs.map +0 -1
  499. package/dist/types/controllers/sessionAuth.controller.d.ts +0 -140
  500. package/dist/types/controllers/sessionAuth.controller.d.ts.map +0 -1
  501. package/dist/types/routes/sessionAuth.routes.d.ts +0 -77
  502. package/dist/types/routes/sessionAuth.routes.d.ts.map +0 -1
  503. package/dist/types/services/sessionAuth.service.d.ts +0 -141
  504. package/dist/types/services/sessionAuth.service.d.ts.map +0 -1
  505. package/dist/types/utils/CSRF.d.ts +0 -3
  506. package/dist/types/utils/CSRF.d.ts.map +0 -1
  507. package/dist/types/utils/cookies.d.ts +0 -12
  508. package/dist/types/utils/cookies.d.ts.map +0 -1
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var mergeFunctionTypes_exports = {};
16
+ module.exports = __toCommonJS(mergeFunctionTypes_exports);
17
+ //# sourceMappingURL=mergeFunctionTypes.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/mergeFunctionTypes.ts"],"sourcesContent":["/**\n * Convert a union to an intersection\n */\ntype UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (\n x: infer I\n) => void\n ? I\n : never;\n\n/**\n * Extract the (single) parameter type from a function\n */\ntype Arg<T> = T extends (arg: infer A) => any\n ? A extends object\n ? A\n : {}\n : never;\n\n/**\n * Extract the return type from a function (keeps unions)\n */\ntype Ret<T> = T extends (...args: any[]) => infer R ? R : never;\n\n/**\n * Merge the parameter objects and keep the return‑type union\n */\nexport type MergeFunctions<U extends (arg: any) => any> = (\n arg: UnionToIntersection<Arg<U>>\n) => Ret<U>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -34,6 +34,7 @@ module.exports = __toCommonJS(connectDB_exports);
34
34
  var import_logger = require('./../../logger/index.cjs');
35
35
  var import_dictionary = require('./../../models/dictionary.model.cjs');
36
36
  var import_oAuth2 = require('./../../models/oAuth2.model.cjs');
37
+ var import_organization = require('./../../models/organization.model.cjs');
37
38
  var import_project = require('./../../models/project.model.cjs');
38
39
  var import_tag = require('./../../models/tag.model.cjs');
39
40
  var import_user = require('./../../models/user.model.cjs');
@@ -49,7 +50,8 @@ const connectDB = async () => {
49
50
  await import_oAuth2.OAuth2AccessTokenModel.createIndexes();
50
51
  await import_tag.TagModel.createIndexes();
51
52
  await import_dictionary.DictionaryModel.createIndexes();
52
- return client;
53
+ await import_organization.OrganizationModel.createIndexes();
54
+ return client.connection.getClient();
53
55
  } catch (error) {
54
56
  const errorMessage = `MongoDB connection error - ${error.message}`;
55
57
  import_logger.logger.error(errorMessage);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/mongoDB/connectDB.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { DictionaryModel } from '@models/dictionary.model';\nimport { OAuth2AccessTokenModel } from '@models/oAuth2.model';\nimport { ProjectModel } from '@models/project.model';\nimport { TagModel } from '@models/tag.model';\nimport { UserModel } from '@models/user.model';\nimport mongoose from 'mongoose';\n\nexport const connectDB = async () => {\n try {\n const client = await mongoose.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 // Recreate indexes for models\n await ProjectModel.syncIndexes();\n await UserModel.createIndexes();\n await OAuth2AccessTokenModel.createIndexes();\n await TagModel.createIndexes();\n await DictionaryModel.createIndexes();\n\n return client;\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AACvB,wBAAgC;AAChC,oBAAuC;AACvC,qBAA6B;AAC7B,iBAAyB;AACzB,kBAA0B;AAC1B,sBAAqB;AAEd,MAAM,YAAY,YAAY;AACnC,MAAI;AACF,UAAM,SAAS,MAAM,gBAAAA,QAAS;AAAA,MAC5B,iBAAiB,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,IAAI,UAAU;AAAA,IACpF;AAEA,yBAAO,KAAK,mBAAmB;AAG/B,UAAM,4BAAa,YAAY;AAC/B,UAAM,sBAAU,cAAc;AAC9B,UAAM,qCAAuB,cAAc;AAC3C,UAAM,oBAAS,cAAc;AAC7B,UAAM,kCAAgB,cAAc;AAEpC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,eAAe,8BAA+B,MAAgB,OAAO;AAE3E,yBAAO,MAAM,YAAY;AACzB,UAAM,IAAI,MAAM,YAAY;AAAA,EAC9B;AACF;","names":["mongoose"]}
1
+ {"version":3,"sources":["../../../../src/utils/mongoDB/connectDB.ts"],"sourcesContent":["import { logger } from '@logger';\nimport { DictionaryModel } from '@models/dictionary.model';\nimport { OAuth2AccessTokenModel } from '@models/oAuth2.model';\nimport { OrganizationModel } from '@models/organization.model';\nimport { ProjectModel } from '@models/project.model';\nimport { TagModel } from '@models/tag.model';\nimport { UserModel } from '@models/user.model';\nimport mongoose from 'mongoose';\n\nexport const connectDB = async () => {\n try {\n const client = await mongoose.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 // Recreate indexes for models\n await ProjectModel.syncIndexes();\n await UserModel.createIndexes();\n await OAuth2AccessTokenModel.createIndexes();\n await TagModel.createIndexes();\n await DictionaryModel.createIndexes();\n await OrganizationModel.createIndexes();\n\n // Return the underlying MongoDB client for better-auth\n return client.connection.getClient();\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAuB;AACvB,wBAAgC;AAChC,oBAAuC;AACvC,0BAAkC;AAClC,qBAA6B;AAC7B,iBAAyB;AACzB,kBAA0B;AAC1B,sBAAqB;AAEd,MAAM,YAAY,YAAY;AACnC,MAAI;AACF,UAAM,SAAS,MAAM,gBAAAA,QAAS;AAAA,MAC5B,iBAAiB,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,IAAI,UAAU;AAAA,IACpF;AAEA,yBAAO,KAAK,mBAAmB;AAG/B,UAAM,4BAAa,YAAY;AAC/B,UAAM,sBAAU,cAAc;AAC9B,UAAM,qCAAuB,cAAc;AAC3C,UAAM,oBAAS,cAAc;AAC7B,UAAM,kCAAgB,cAAc;AACpC,UAAM,sCAAkB,cAAc;AAGtC,WAAO,OAAO,WAAW,UAAU;AAAA,EACrC,SAAS,OAAO;AACd,UAAM,eAAe,8BAA+B,MAAgB,OAAO;AAE3E,yBAAO,MAAM,YAAY;AACzB,UAAM,IAAI,MAAM,YAAY;AAAA,EAC9B;AACF;","names":["mongoose"]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var types_exports = {};
16
+ module.exports = __toCommonJS(types_exports);
17
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/utils/mongoDB/types.ts"],"sourcesContent":["import type { Types } from 'mongoose';\n\nexport type RenameId<T extends { id: Types.ObjectId }> = Omit<T, 'id'> & {\n _id: T['id'];\n};\n\nexport type OmitId<T extends { id?: any; _id?: any }> = Omit<T, 'id | _id'>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/oAuth2.ts"],"sourcesContent":["import {\n getClient,\n saveToken,\n getAccessToken,\n verifyScope,\n getUserFromClient,\n} from '@services/oAuth2.service';\nimport OAuth2Server, { AuthenticateOptions } from 'oauth2-server';\n\nexport const ACCESS_TOKEN_EXPIRES_IN = 60 * 60 * 2; // 2 hour\n\nexport const getTokenExpireAt = () =>\n new Date(Date.now() + ACCESS_TOKEN_EXPIRES_IN * 1000);\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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMO;AAGA,MAAM,0BAA0B,KAAK,KAAK;AAE1C,MAAM,mBAAmB,MAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,0BAA0B,GAAI;AAE/C,MAAM,sBAA2C;AAAA,EACtD,OAAO;AAAA,EACP,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,gCAAgC;AAClC;AAEO,MAAM,eAAe,OAA4C;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/oAuth2.ts"],"sourcesContent":["import {\n getAccessToken,\n getClient,\n getUserFromClient,\n saveToken,\n verifyScope,\n} from '@services/oAuth2.service';\nimport OAuth2Server, { AuthenticateOptions } from 'oauth2-server';\n\nexport const ACCESS_TOKEN_EXPIRES_IN = 60 * 60 * 2; // 2 hour\n\nexport const getTokenExpireAt = () =>\n new Date(Date.now() + ACCESS_TOKEN_EXPIRES_IN * 1000);\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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAMO;AAGA,MAAM,0BAA0B,KAAK,KAAK;AAE1C,MAAM,mBAAmB,MAC9B,IAAI,KAAK,KAAK,IAAI,IAAI,0BAA0B,GAAI;AAE/C,MAAM,sBAA2C;AAAA,EACtD,OAAO;AAAA,EACP,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,gCAAgC;AAClC;AAEO,MAAM,eAAe,OAA4C;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var permissions_exports = {};
20
+ __export(permissions_exports, {
21
+ ROLE_POLICY: () => ROLE_POLICY,
22
+ computeEffectivePermission: () => computeEffectivePermission,
23
+ getSessionRoles: () => getSessionRoles,
24
+ hasPermission: () => hasPermission,
25
+ intersectPermissions: () => intersectPermissions
26
+ });
27
+ module.exports = __toCommonJS(permissions_exports);
28
+ const ROLE_POLICY = {
29
+ admin: {
30
+ "organization:read": () => true,
31
+ "organization:write": () => true,
32
+ "organization:admin": () => true,
33
+ "project:read": () => true,
34
+ "project:write": () => true,
35
+ "project:admin": () => true,
36
+ "dictionary:read": () => true,
37
+ "dictionary:write": () => true,
38
+ "dictionary:admin": () => true,
39
+ "tag:read": () => true,
40
+ "tag:write": () => true,
41
+ "tag:admin": () => true,
42
+ "user:read": () => true,
43
+ "user:write": () => true,
44
+ "user:admin": () => true
45
+ },
46
+ org_admin: {
47
+ "organization:read": () => true,
48
+ "organization:write": () => true,
49
+ "organization:admin": () => true,
50
+ "project:read": () => true,
51
+ "project:write": () => true,
52
+ "project:admin": () => true,
53
+ "dictionary:read": () => true,
54
+ "dictionary:write": () => true,
55
+ "dictionary:admin": () => true,
56
+ "tag:read": () => true,
57
+ "tag:write": () => true,
58
+ "tag:admin": () => true,
59
+ "user:write": ({
60
+ organization,
61
+ targetUserIds
62
+ }) => targetUserIds.every(
63
+ (targetUserId) => organization?.membersIds?.map(String).includes(String(targetUserId))
64
+ )
65
+ },
66
+ org_user: {
67
+ "organization:read": () => true,
68
+ "user:read": ({
69
+ organization,
70
+ targetUserIds
71
+ }) => targetUserIds.every(
72
+ (targetUserId) => organization?.membersIds?.map(String).includes(String(targetUserId))
73
+ )
74
+ },
75
+ project_admin: {
76
+ "project:read": () => true,
77
+ "project:write": () => true,
78
+ "project:admin": () => true,
79
+ "tag:read": () => true,
80
+ "tag:write": () => true,
81
+ "tag:admin": () => true,
82
+ "user:write": ({
83
+ project,
84
+ targetUserIds
85
+ }) => targetUserIds.every(
86
+ (targetUserId) => project?.membersIds?.map(String).includes(String(targetUserId))
87
+ )
88
+ },
89
+ project_user: {
90
+ "project:read": ({ user, project }) => project?.membersIds?.map(String).includes(String(user?.id)),
91
+ "dictionary:read": ({ user, project }) => project?.membersIds?.map(String).includes(String(user?.id)),
92
+ "dictionary:write": ({ user, project }) => project?.membersIds?.map(String).includes(String(user?.id)),
93
+ "tag:read": () => true,
94
+ "tag:write": () => true,
95
+ "tag:admin": ({ user, organization }) => organization?.adminsIds?.map(String).includes(String(user?.id)),
96
+ "user:read": ({
97
+ project,
98
+ targetUserIds
99
+ }) => targetUserIds.every(
100
+ (targetUserId) => project?.membersIds?.map(String).includes(String(targetUserId))
101
+ )
102
+ },
103
+ project_reviewer: {
104
+ "dictionary:read": ({ user, project }) => project?.membersIds?.map(String).includes(String(user?.id)),
105
+ "dictionary:write": ({ user, project }) => project?.membersIds?.map(String).includes(String(user?.id)),
106
+ "tag:read": () => true
107
+ }
108
+ };
109
+ const getSessionRoles = ({
110
+ user,
111
+ organization,
112
+ project
113
+ }) => {
114
+ const roles = [];
115
+ if (!user) {
116
+ return roles;
117
+ }
118
+ const isUserAdmin = user.role === "admin";
119
+ if (isUserAdmin) {
120
+ roles.push("admin");
121
+ }
122
+ if (!organization) {
123
+ return roles;
124
+ }
125
+ const isOrganizationAdmin = organization.adminsIds?.map(String).includes(String(user.id));
126
+ if (isOrganizationAdmin) {
127
+ roles.push("org_admin");
128
+ }
129
+ const isOrganizationMember = organization.membersIds?.map(String).includes(String(user.id));
130
+ if (isOrganizationMember) {
131
+ roles.push("org_user");
132
+ }
133
+ if (!project) {
134
+ return roles;
135
+ }
136
+ const isProjectAdmin = project.adminsIds?.map(String).includes(String(user.id));
137
+ if (isProjectAdmin) {
138
+ roles.push("project_admin");
139
+ }
140
+ const isProjectMember = project?.membersIds?.map(String).includes(String(user.id));
141
+ if (isProjectMember) {
142
+ roles.push("project_user");
143
+ }
144
+ return roles;
145
+ };
146
+ const computeEffectivePermission = (roles) => Array.from(
147
+ new Set(
148
+ roles.flatMap((role) => Object.keys(ROLE_POLICY[role]))
149
+ )
150
+ );
151
+ const intersectPermissions = (permissions1, permissions2) => permissions1.filter((permission) => permissions2.includes(permission));
152
+ const hasPermission = (roles, permission) => {
153
+ const rolesCheck = roles.map(
154
+ (role) => ROLE_POLICY[role]?.[permission] ?? (() => false)
155
+ );
156
+ return (args) => rolesCheck.some((check) => check(args));
157
+ };
158
+ // Annotate the CommonJS export names for ESM import in node:
159
+ 0 && (module.exports = {
160
+ ROLE_POLICY,
161
+ computeEffectivePermission,
162
+ getSessionRoles,
163
+ hasPermission,
164
+ intersectPermissions
165
+ });
166
+ //# sourceMappingURL=permissions.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/permissions.ts"],"sourcesContent":["import { Dictionary, Organization, Project, Tag, User } from '@/export';\nimport { SessionContext } from '@/types/session.types';\n\n/**\n * @description\n * A named grouping of privileges (e.g. `\"org_admin\"`).\n * Users are *granted* one or more Roles.\n */\nexport type Roles =\n | 'admin'\n | 'org_admin'\n | 'org_user'\n | 'project_admin'\n | 'project_user'\n | 'project_reviewer';\n\n/**\n * @description\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 * @description\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 * @description\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 org_admin: {\n 'organization:read': () => true,\n 'organization:write': () => true,\n 'organization:admin': () => true,\n\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\n 'user:write': ({\n organization,\n targetUserIds,\n }: SessionContext & { targetUserIds: User['id'][] }) =>\n targetUserIds.every((targetUserId) =>\n organization?.membersIds?.map(String).includes(String(targetUserId))\n ),\n },\n org_user: {\n 'organization:read': () => true,\n\n 'user:read': ({\n organization,\n targetUserIds,\n }: SessionContext & { targetUserIds: User['id'][] }) =>\n targetUserIds.every((targetUserId) =>\n organization?.membersIds?.map(String).includes(String(targetUserId))\n ),\n },\n project_admin: {\n 'project:read': () => true,\n 'project:write': () => true,\n 'project:admin': () => true,\n 'tag:read': () => true,\n 'tag:write': () => true,\n 'tag:admin': () => true,\n\n 'user:write': ({\n project,\n targetUserIds,\n }: SessionContext & { targetUserIds: User['id'][] }) =>\n targetUserIds.every((targetUserId) =>\n project?.membersIds?.map(String).includes(String(targetUserId))\n ),\n },\n project_user: {\n 'project:read': ({ user, project }: SessionContext) =>\n project?.membersIds?.map(String).includes(String(user?.id)),\n\n 'dictionary:read': ({ user, project }: SessionContext) =>\n project?.membersIds?.map(String).includes(String(user?.id)),\n 'dictionary:write': ({ user, project }: SessionContext) =>\n project?.membersIds?.map(String).includes(String(user?.id)),\n\n 'tag:read': () => true,\n 'tag:write': () => true,\n 'tag:admin': ({ user, organization }: SessionContext) =>\n organization?.adminsIds?.map(String).includes(String(user?.id)),\n\n 'user:read': ({\n project,\n targetUserIds,\n }: SessionContext & { targetUserIds: User['id'][] }) =>\n targetUserIds.every((targetUserId) =>\n project?.membersIds?.map(String).includes(String(targetUserId))\n ),\n },\n project_reviewer: {\n 'dictionary:read': ({ user, project }: SessionContext) =>\n project?.membersIds?.map(String).includes(String(user?.id)),\n 'dictionary:write': ({ user, project }: SessionContext) =>\n project?.membersIds?.map(String).includes(String(user?.id)),\n\n 'tag:read': () => true,\n },\n} as const satisfies RolePolicy;\n\nexport const getSessionRoles = ({\n user,\n organization,\n project,\n}: SessionContext): Roles[] => {\n const roles: Roles[] = [];\n\n if (!user) {\n return roles;\n }\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 =\n // session.project?.reviewersIds?.includes(session.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 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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","names":[]}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var rateLimiter_exports = {};
30
+ __export(rateLimiter_exports, {
31
+ ipLimiter: () => ipLimiter,
32
+ unauthenticatedChatBotLimiter: () => unauthenticatedChatBotLimiter
33
+ });
34
+ module.exports = __toCommonJS(rateLimiter_exports);
35
+ var import_express_rate_limit = __toESM(require("express-rate-limit"), 1);
36
+ var import_errors = require('./errors/index.cjs');
37
+ const ipLimiter = (0, import_express_rate_limit.default)({
38
+ windowMs: 60 * 1e3,
39
+ // 1-minute window
40
+ limit: 500,
41
+ // 500 requests / IP / window
42
+ standardHeaders: "draft-8",
43
+ legacyHeaders: false,
44
+ // Use a custom key generator that handles proxy headers securely
45
+ keyGenerator: (req) => {
46
+ return req.ip ?? req.socket?.remoteAddress ?? "unknown";
47
+ },
48
+ handler: (req, res, _next) => {
49
+ const { limit, remaining, resetTime } = req.rateLimit;
50
+ import_errors.ErrorHandler.handleGenericErrorResponse(res, "RATE_LIMIT_EXCEEDED", {
51
+ limit: `${limit} per minute`,
52
+ retryAfter: Math.ceil((resetTime.getTime() - Date.now()) / 1e3),
53
+ remaining
54
+ });
55
+ }
56
+ });
57
+ const unauthenticatedChatBotLimiter = (0, import_express_rate_limit.default)({
58
+ windowMs: 60 * 60 * 1e3,
59
+ // 1-hour window
60
+ limit: 3,
61
+ // 3 requests / IP / window
62
+ standardHeaders: "draft-8",
63
+ skip: (_req, res) => Boolean(res.locals.user),
64
+ // authenticated? then skip
65
+ legacyHeaders: false,
66
+ // Use a custom key generator that handles proxy headers securely
67
+ keyGenerator: (req) => {
68
+ return req.ip ?? req.socket?.remoteAddress ?? "unknown";
69
+ },
70
+ handler: (req, res) => {
71
+ const { limit, remaining, resetTime } = req.rateLimit;
72
+ import_errors.ErrorHandler.handleGenericErrorResponse(
73
+ res,
74
+ "RATE_LIMIT_EXCEEDED_UNAUTHENTICATED",
75
+ {
76
+ limit: `${limit} per hour`,
77
+ retryAfter: Math.ceil((resetTime.getTime() - Date.now()) / 1e3),
78
+ remaining
79
+ }
80
+ );
81
+ }
82
+ });
83
+ // Annotate the CommonJS export names for ESM import in node:
84
+ 0 && (module.exports = {
85
+ ipLimiter,
86
+ unauthenticatedChatBotLimiter
87
+ });
88
+ //# sourceMappingURL=rateLimiter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/rateLimiter.ts"],"sourcesContent":["import type { NextFunction, Request, Response } from 'express';\nimport rateLimit from 'express-rate-limit';\nimport { ErrorHandler } from './errors';\n\n// -------------------------------------------------------------\n// Create the rate-limiter instances once at module load-time so\n// that the hit counters are shared across every incoming request.\n// -------------------------------------------------------------\n\nexport const ipLimiter: (\n req: Request,\n res: Response,\n next: NextFunction\n) => void | Promise<void> = rateLimit({\n windowMs: 60 * 1000, // 1-minute window\n limit: 500, // 500 requests / IP / window\n standardHeaders: 'draft-8',\n legacyHeaders: false,\n // Use a custom key generator that handles proxy headers securely\n keyGenerator: (req) => {\n // Use the real IP address, falling back to socket remote address\n return req.ip ?? req.socket?.remoteAddress ?? 'unknown';\n },\n handler: (req, res, _next) => {\n const { limit, remaining, resetTime } = (req as any).rateLimit;\n\n ErrorHandler.handleGenericErrorResponse(res, 'RATE_LIMIT_EXCEEDED', {\n limit: `${limit} per minute`,\n retryAfter: Math.ceil((resetTime!.getTime() - Date.now()) / 1000),\n remaining,\n });\n },\n});\n\nexport const unauthenticatedChatBotLimiter: (\n req: Request,\n res: Response,\n next: NextFunction\n) => any = rateLimit({\n windowMs: 60 * 60 * 1000, // 1-hour window\n limit: 3, // 3 requests / IP / window\n standardHeaders: 'draft-8',\n skip: (_req, res) => Boolean(res.locals.user), // authenticated? then skip\n legacyHeaders: false,\n // Use a custom key generator that handles proxy headers securely\n keyGenerator: (req) => {\n // Use the real IP address, falling back to socket remote address\n return req.ip ?? req.socket?.remoteAddress ?? 'unknown';\n },\n handler: (req, res) => {\n const { limit, remaining, resetTime } = (req as any).rateLimit;\n\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'RATE_LIMIT_EXCEEDED_UNAUTHENTICATED',\n {\n limit: `${limit} per hour`,\n retryAfter: Math.ceil((resetTime!.getTime() - Date.now()) / 1000),\n remaining,\n }\n );\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,gCAAsB;AACtB,oBAA6B;AAOtB,MAAM,gBAIe,0BAAAA,SAAU;AAAA,EACpC,UAAU,KAAK;AAAA;AAAA,EACf,OAAO;AAAA;AAAA,EACP,iBAAiB;AAAA,EACjB,eAAe;AAAA;AAAA,EAEf,cAAc,CAAC,QAAQ;AAErB,WAAO,IAAI,MAAM,IAAI,QAAQ,iBAAiB;AAAA,EAChD;AAAA,EACA,SAAS,CAAC,KAAK,KAAK,UAAU;AAC5B,UAAM,EAAE,OAAO,WAAW,UAAU,IAAK,IAAY;AAErD,+BAAa,2BAA2B,KAAK,uBAAuB;AAAA,MAClE,OAAO,GAAG,KAAK;AAAA,MACf,YAAY,KAAK,MAAM,UAAW,QAAQ,IAAI,KAAK,IAAI,KAAK,GAAI;AAAA,MAChE;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;AAEM,MAAM,oCAIF,0BAAAA,SAAU;AAAA,EACnB,UAAU,KAAK,KAAK;AAAA;AAAA,EACpB,OAAO;AAAA;AAAA,EACP,iBAAiB;AAAA,EACjB,MAAM,CAAC,MAAM,QAAQ,QAAQ,IAAI,OAAO,IAAI;AAAA;AAAA,EAC5C,eAAe;AAAA;AAAA,EAEf,cAAc,CAAC,QAAQ;AAErB,WAAO,IAAI,MAAM,IAAI,QAAQ,iBAAiB;AAAA,EAChD;AAAA,EACA,SAAS,CAAC,KAAK,QAAQ;AACrB,UAAM,EAAE,OAAO,WAAW,UAAU,IAAK,IAAY;AAErD,+BAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO,GAAG,KAAK;AAAA,QACf,YAAY,KAAK,MAAM,UAAW,QAAQ,IAAI,KAAK,IAAI,KAAK,GAAI;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,CAAC;","names":["rateLimit"]}
@@ -187,7 +187,7 @@ const auditContentDeclarationMetadata = async (req, res, _next) => {
187
187
  try {
188
188
  const tags = await tagService.findTags(
189
189
  {
190
- organizationId: organization?._id
190
+ organizationId: organization?.id
191
191
  },
192
192
  0,
193
193
  1e3
@@ -229,7 +229,7 @@ const auditTag = async (req, res, _next) => {
229
229
  try {
230
230
  let dictionaries = [];
231
231
  if (project?.organizationId) {
232
- dictionaries = await getDictionariesByTags([tag.key], project._id);
232
+ dictionaries = await getDictionariesByTags([tag.key], project.id);
233
233
  }
234
234
  const auditResponse = await auditTagUtil.auditTag({
235
235
  aiConfig,
@@ -290,9 +290,9 @@ const askDocQuestion = async (req, res) => {
290
290
  {
291
291
  $set: {
292
292
  discutionId,
293
- userId: user?._id,
294
- projectId: project?._id,
295
- organizationId: organization?._id,
293
+ userId: user?.id,
294
+ projectId: project?.id,
295
+ organizationId: organization?.id,
296
296
  messages: [
297
297
  ...messages.map((msg) => ({
298
298
  role: msg.role,
@@ -329,7 +329,7 @@ data: ${JSON.stringify({ message: err.message })}
329
329
  };
330
330
  const autocomplete = async (req, res) => {
331
331
  try {
332
- const { text, aiOptions } = req.body;
332
+ const { text, aiOptions, contextBefore, currentLine, contextAfter } = req.body;
333
333
  let aiConfig;
334
334
  try {
335
335
  aiConfig = await getAIConfig(res, {
@@ -344,7 +344,10 @@ const autocomplete = async (req, res) => {
344
344
  const response = await autocompleteUtil.autocomplete({
345
345
  text,
346
346
  aiConfig,
347
- applicationContext: aiOptions?.applicationContext
347
+ applicationContext: aiOptions?.applicationContext,
348
+ contextBefore,
349
+ currentLine,
350
+ contextAfter
348
351
  }) ?? {
349
352
  autocompletion: "",
350
353
  tokenUsed: 0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/controllers/ai.controller.ts"],"sourcesContent":["import { DiscussionModel } from '@/models/discussion.model';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\nimport { type KeyPath } from '@intlayer/core';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { getDictionariesByTags } from '@services/dictionary.service';\nimport * as tagService from '@services/tag.service';\nimport { getTagsByKeys } from '@services/tag.service';\nimport {\n AIConfig,\n getAIConfig,\n type AIOptions,\n type ChatCompletionRequestMessage,\n} from '@utils/AI/aiSdk';\nimport * as askDocQuestionUtil from '@utils/AI/askDocQuestion/askDocQuestion';\nimport * as auditContentDeclarationUtil from '@utils/AI/auditDictionary';\nimport * as auditContentDeclarationFieldUtil from '@utils/AI/auditDictionaryField';\nimport * as auditContentDeclarationMetadataUtil from '@utils/AI/auditDictionaryMetadata';\nimport * as auditTagUtil from '@utils/AI/auditTag';\nimport * as autocompleteUtil from '@utils/AI/autocomplete';\nimport * as customQueryUtil from '@utils/AI/customQuery';\nimport * as translateJSONUtil from '@utils/AI/translateJSON';\nimport { ErrorHandler, type AppError } from '@utils/errors';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { Locales } from 'intlayer';\n\ntype ReplaceAIConfigByOptions<T> = Omit<T, 'aiConfig'> & {\n aiOptions?: AIOptions;\n};\n\nexport type CustomQueryBody =\n ReplaceAIConfigByOptions<customQueryUtil.CustomQueryOptions>;\nexport type CustomQueryResult =\n ResponseData<customQueryUtil.CustomQueryResultData>;\n\nexport const customQuery = async (\n req: Request<AuditContentDeclarationBody>,\n res: ResponseWithInformation<CustomQueryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { aiOptions, tagsKeys, ...rest } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: customQueryUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n const auditResponse = await customQueryUtil.customQuery({\n ...rest,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'QUERY_FAILED');\n return;\n }\n\n const responseData = formatResponse<customQueryUtil.CustomQueryResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type TranslateJSONBody = Omit<\n ReplaceAIConfigByOptions<translateJSONUtil.TranslateJSONOptions>,\n 'tags'\n> & {\n tagsKeys?: string[];\n};\nexport type TranslateJSONResult =\n ResponseData<translateJSONUtil.TranslateJSONResultData>;\n\nexport const translateJSON = async (\n req: Request<AuditContentDeclarationBody>,\n res: ResponseWithInformation<TranslateJSONResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { aiOptions, tagsKeys, ...rest } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: translateJSONUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await translateJSONUtil.translateJSON({\n ...rest,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<translateJSONUtil.TranslateJSONResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationBody = {\n aiOptions?: AIOptions;\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n tagsKeys?: string[];\n};\nexport type AuditContentDeclarationResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclaration = async (\n req: Request<AuditContentDeclarationBody>,\n res: ResponseWithInformation<AuditContentDeclarationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { fileContent, filePath, aiOptions, locales, defaultLocale, tagsKeys } =\n req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await auditContentDeclarationUtil.auditDictionary({\n fileContent,\n filePath,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n locales,\n defaultLocale,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationFieldBody = {\n aiOptions?: AIOptions;\n locales: Locales[];\n fileContent: string;\n filePath?: string;\n tagsKeys?: string[];\n keyPath: KeyPath[];\n};\nexport type AuditContentDeclarationFieldResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationField = async (\n req: Request<AuditContentDeclarationFieldBody>,\n res: ResponseWithInformation<AuditContentDeclarationFieldResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { fileContent, aiOptions, locales, tagsKeys, keyPath } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationFieldUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse =\n await auditContentDeclarationFieldUtil.auditDictionaryField({\n fileContent,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n locales,\n tags,\n keyPath,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationMetadataBody = {\n aiOptions?: AIOptions;\n fileContent: string;\n};\nexport type AuditContentDeclarationMetadataResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationMetadata = async (\n req: Request<AuditContentDeclarationMetadataBody>,\n res: ResponseWithInformation<AuditContentDeclarationMetadataResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization } = res.locals;\n const { fileContent, aiOptions } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationMetadataUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n const tags: Tag[] = await tagService.findTags(\n {\n organizationId: organization?._id,\n },\n 0,\n 1000\n );\n\n const auditResponse =\n await auditContentDeclarationMetadataUtil.auditDictionaryMetadata({\n fileContent,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditTagBody = {\n aiOptions?: AIOptions;\n tag: Tag;\n};\nexport type AuditTagResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditTag = async (\n req: Request<undefined, undefined, AuditTagBody>,\n res: ResponseWithInformation<AuditTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { aiOptions, tag } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditTagUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let dictionaries: Dictionary[] = [];\n if (project?.organizationId) {\n dictionaries = await getDictionariesByTags([tag.key], project._id);\n }\n\n const auditResponse = await auditTagUtil.auditTag({\n aiConfig,\n dictionaries,\n tag,\n applicationContext: aiOptions?.applicationContext,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AskDocQuestionBody = {\n messages: ChatCompletionRequestMessage[];\n discutionId: string;\n};\nexport type AskDocQuestionResult =\n ResponseData<askDocQuestionUtil.AskDocQuestionResult>;\n\nexport const askDocQuestion = async (\n req: Request<undefined, undefined, AskDocQuestionBody>,\n res: ResponseWithInformation<AskDocQuestionResult>\n) => {\n const { messages, discutionId } = req.body;\n const { user, project, organization } = res.locals;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: {},\n defaultOptions: askDocQuestionUtil.aiDefaultOptions,\n accessType: ['public'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n // 1. Prepare SSE headers and flush them NOW\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');\n res.setHeader('Cache-Control', 'no-cache, no-transform');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no'); // disable nginx buffering\n res.flushHeaders?.();\n res.write(': connected\\n\\n'); // initial comment keeps some browsers happy\n res.flush?.();\n\n // 2. Kick off the upstream stream WITHOUT awaiting it\n askDocQuestionUtil\n .askDocQuestion(messages, aiConfig, {\n onMessage: (chunk) => {\n res.write(`data: ${JSON.stringify({ chunk })}\\n\\n`);\n res.flush?.();\n },\n })\n .then(async (fullResponse) => {\n const lastUserMessageContent = messages.findLast(\n (msg) => msg.role === 'user'\n )?.content;\n const lastUserMessageNbWords = lastUserMessageContent\n ? lastUserMessageContent.split(' ').length\n : 0;\n if (lastUserMessageNbWords > 2) {\n // If the last user message is less than 3 words, don't persist the discussion\n // Example: \"Hello\", \"Hi\", \"Hey\", \"test\", etc.\n\n // 3. Persist discussion while the client already has all chunks\n await DiscussionModel.findOneAndUpdate(\n { discutionId },\n {\n $set: {\n discutionId,\n userId: user?._id,\n projectId: project?._id,\n organizationId: organization?._id,\n messages: [\n ...messages.map((msg) => ({\n role: msg.role,\n content: msg.content,\n timestamp: msg.timestamp,\n })),\n {\n role: 'assistant',\n content: fullResponse.response,\n relatedFiles: fullResponse.relatedFiles,\n timestamp: new Date(),\n },\n ],\n },\n },\n { upsert: true, new: true }\n );\n }\n\n // 4. Tell the client we're done and close the stream\n res.write(\n `data: ${JSON.stringify({ done: true, response: fullResponse })}\\n\\n`\n );\n res.end();\n })\n .catch((err) => {\n // propagate error as an SSE event so the client knows why it closed\n res.write(\n `event: error\\ndata: ${JSON.stringify({ message: err.message })}\\n\\n`\n );\n res.end();\n });\n};\n\nexport type AutocompleteBody = {\n text: string;\n aiOptions?: AIOptions;\n};\n\nexport type AutocompleteResponse = ResponseData<{\n autocompletion: string;\n}>;\n\nexport const autocomplete = async (\n req: Request<undefined, undefined, AutocompleteBody>,\n res: ResponseWithInformation<AutocompleteResponse>\n) => {\n try {\n const { text, aiOptions } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: autocompleteUtil.aiDefaultOptions,\n accessType: ['public'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n const response = (await autocompleteUtil.autocomplete({\n text,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n })) ?? {\n autocompletion: '',\n tokenUsed: 0,\n };\n\n const responseData =\n formatResponse<autocompleteUtil.AutocompleteFileResultData>({\n data: response,\n });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/controllers/ai.controller.ts"],"sourcesContent":["import { DiscussionModel } from '@/models/discussion.model';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\nimport { type KeyPath } from '@intlayer/core';\nimport { getDictionariesByTags } from '@services/dictionary.service';\nimport * as tagService from '@services/tag.service';\nimport { getTagsByKeys } from '@services/tag.service';\nimport {\n AIConfig,\n getAIConfig,\n type AIOptions,\n type ChatCompletionRequestMessage,\n} from '@utils/AI/aiSdk';\nimport * as askDocQuestionUtil from '@utils/AI/askDocQuestion/askDocQuestion';\nimport * as auditContentDeclarationUtil from '@utils/AI/auditDictionary';\nimport * as auditContentDeclarationFieldUtil from '@utils/AI/auditDictionaryField';\nimport * as auditContentDeclarationMetadataUtil from '@utils/AI/auditDictionaryMetadata';\nimport * as auditTagUtil from '@utils/AI/auditTag';\nimport * as autocompleteUtil from '@utils/AI/autocomplete';\nimport * as customQueryUtil from '@utils/AI/customQuery';\nimport * as translateJSONUtil from '@utils/AI/translateJSON';\nimport { ErrorHandler, type AppError } from '@utils/errors';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request, Response } from 'express';\nimport type { Locales } from 'intlayer';\n\ntype ReplaceAIConfigByOptions<T> = Omit<T, 'aiConfig'> & {\n aiOptions?: AIOptions;\n};\n\nexport type CustomQueryBody =\n ReplaceAIConfigByOptions<customQueryUtil.CustomQueryOptions>;\nexport type CustomQueryResult =\n ResponseData<customQueryUtil.CustomQueryResultData>;\n\nexport const customQuery = async (\n req: Request<AuditContentDeclarationBody>,\n res: Response<CustomQueryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { aiOptions, tagsKeys, ...rest } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: customQueryUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n const auditResponse = await customQueryUtil.customQuery({\n ...rest,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'QUERY_FAILED');\n return;\n }\n\n const responseData = formatResponse<customQueryUtil.CustomQueryResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type TranslateJSONBody = Omit<\n ReplaceAIConfigByOptions<translateJSONUtil.TranslateJSONOptions>,\n 'tags'\n> & {\n tagsKeys?: string[];\n};\nexport type TranslateJSONResult =\n ResponseData<translateJSONUtil.TranslateJSONResultData>;\n\nexport const translateJSON = async (\n req: Request<AuditContentDeclarationBody>,\n res: Response<TranslateJSONResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { aiOptions, tagsKeys, ...rest } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: translateJSONUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await translateJSONUtil.translateJSON({\n ...rest,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<translateJSONUtil.TranslateJSONResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationBody = {\n aiOptions?: AIOptions;\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n tagsKeys?: string[];\n};\nexport type AuditContentDeclarationResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclaration = async (\n req: Request<AuditContentDeclarationBody>,\n res: Response<AuditContentDeclarationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { fileContent, filePath, aiOptions, locales, defaultLocale, tagsKeys } =\n req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await auditContentDeclarationUtil.auditDictionary({\n fileContent,\n filePath,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n locales,\n defaultLocale,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationFieldBody = {\n aiOptions?: AIOptions;\n locales: Locales[];\n fileContent: string;\n filePath?: string;\n tagsKeys?: string[];\n keyPath: KeyPath[];\n};\nexport type AuditContentDeclarationFieldResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationField = async (\n req: Request<AuditContentDeclarationFieldBody>,\n res: Response<AuditContentDeclarationFieldResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { fileContent, aiOptions, locales, tagsKeys, keyPath } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationFieldUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse =\n await auditContentDeclarationFieldUtil.auditDictionaryField({\n fileContent,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n locales,\n tags,\n keyPath,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationMetadataBody = {\n aiOptions?: AIOptions;\n fileContent: string;\n};\nexport type AuditContentDeclarationMetadataResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationMetadata = async (\n req: Request<AuditContentDeclarationMetadataBody>,\n res: Response<AuditContentDeclarationMetadataResult>,\n _next: NextFunction\n): Promise<void> => {\n const { organization } = res.locals;\n const { fileContent, aiOptions } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditContentDeclarationMetadataUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n const tags: Tag[] = await tagService.findTags(\n {\n organizationId: organization?.id,\n },\n 0,\n 1000\n );\n\n const auditResponse =\n await auditContentDeclarationMetadataUtil.auditDictionaryMetadata({\n fileContent,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditTagBody = {\n aiOptions?: AIOptions;\n tag: Tag;\n};\nexport type AuditTagResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditTag = async (\n req: Request<undefined, undefined, AuditTagBody>,\n res: Response<AuditTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project } = res.locals;\n const { aiOptions, tag } = req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: auditTagUtil.aiDefaultOptions,\n accessType: ['registered_user', 'apiKey'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n try {\n let dictionaries: Dictionary[] = [];\n if (project?.organizationId) {\n dictionaries = await getDictionariesByTags([tag.key], project.id);\n }\n\n const auditResponse = await auditTagUtil.auditTag({\n aiConfig,\n dictionaries,\n tag,\n applicationContext: aiOptions?.applicationContext,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AskDocQuestionBody = {\n messages: ChatCompletionRequestMessage[];\n discutionId: string;\n};\nexport type AskDocQuestionResult =\n ResponseData<askDocQuestionUtil.AskDocQuestionResult>;\n\nexport const askDocQuestion = async (\n req: Request<undefined, undefined, AskDocQuestionBody>,\n res: Response<AskDocQuestionResult>\n) => {\n const { messages, discutionId } = req.body;\n const { user, project, organization } = res.locals;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: {},\n defaultOptions: askDocQuestionUtil.aiDefaultOptions,\n accessType: ['public'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n // 1. Prepare SSE headers and flush them NOW\n res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');\n res.setHeader('Cache-Control', 'no-cache, no-transform');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no'); // disable nginx buffering\n res.flushHeaders?.();\n res.write(': connected\\n\\n'); // initial comment keeps some browsers happy\n res.flush?.();\n\n // 2. Kick off the upstream stream WITHOUT awaiting it\n askDocQuestionUtil\n .askDocQuestion(messages, aiConfig, {\n onMessage: (chunk) => {\n res.write(`data: ${JSON.stringify({ chunk })}\\n\\n`);\n res.flush?.();\n },\n })\n .then(async (fullResponse) => {\n const lastUserMessageContent = messages.findLast(\n (msg) => msg.role === 'user'\n )?.content;\n const lastUserMessageNbWords = lastUserMessageContent\n ? lastUserMessageContent.split(' ').length\n : 0;\n if (lastUserMessageNbWords > 2) {\n // If the last user message is less than 3 words, don't persist the discussion\n // Example: \"Hello\", \"Hi\", \"Hey\", \"test\", etc.\n\n // 3. Persist discussion while the client already has all chunks\n await DiscussionModel.findOneAndUpdate(\n { discutionId },\n {\n $set: {\n discutionId,\n userId: user?.id,\n projectId: project?.id,\n organizationId: organization?.id,\n messages: [\n ...messages.map((msg) => ({\n role: msg.role,\n content: msg.content,\n timestamp: msg.timestamp,\n })),\n {\n role: 'assistant',\n content: fullResponse.response,\n relatedFiles: fullResponse.relatedFiles,\n timestamp: new Date(),\n },\n ],\n },\n },\n { upsert: true, new: true }\n );\n }\n\n // 4. Tell the client we're done and close the stream\n res.write(\n `data: ${JSON.stringify({ done: true, response: fullResponse })}\\n\\n`\n );\n res.end();\n })\n .catch((err) => {\n // propagate error as an SSE event so the client knows why it closed\n res.write(\n `event: error\\ndata: ${JSON.stringify({ message: err.message })}\\n\\n`\n );\n res.end();\n });\n};\n\nexport type AutocompleteBody = {\n text: string;\n aiOptions?: AIOptions;\n contextBefore?: string;\n currentLine?: string;\n contextAfter?: string;\n};\n\nexport type AutocompleteResponse = ResponseData<{\n autocompletion: string;\n}>;\n\nexport const autocomplete = async (\n req: Request<undefined, undefined, AutocompleteBody>,\n res: Response<AutocompleteResponse>\n) => {\n try {\n const { text, aiOptions, contextBefore, currentLine, contextAfter } =\n req.body;\n\n let aiConfig: AIConfig;\n try {\n aiConfig = await getAIConfig(res, {\n userOptions: aiOptions,\n defaultOptions: autocompleteUtil.aiDefaultOptions,\n accessType: ['public'],\n });\n } catch (error) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n\n const response = (await autocompleteUtil.autocomplete({\n text,\n aiConfig,\n applicationContext: aiOptions?.applicationContext,\n contextBefore,\n currentLine,\n contextAfter,\n })) ?? {\n autocompletion: '',\n tokenUsed: 0,\n };\n\n const responseData =\n formatResponse<autocompleteUtil.AutocompleteFileResultData>({\n data: response,\n });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"AAAA,SAAS,uBAAuB;AAIhC,SAAS,6BAA6B;AACtC,YAAY,gBAAgB;AAC5B,SAAS,qBAAqB;AAC9B;AAAA,EAEE;AAAA,OAGK;AACP,YAAY,wBAAwB;AACpC,YAAY,iCAAiC;AAC7C,YAAY,sCAAsC;AAClD,YAAY,yCAAyC;AACrD,YAAY,kBAAkB;AAC9B,YAAY,sBAAsB;AAClC,YAAY,qBAAqB;AACjC,YAAY,uBAAuB;AACnC,SAAS,oBAAmC;AAC5C,SAAS,sBAAyC;AAa3C,MAAM,cAAc,OACzB,KACA,KACA,UACkB;AAClB,QAAM,EAAE,WAAW,UAAU,GAAG,KAAK,IAAI,IAAI;AAE7C,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,gBAAgB;AAAA,MAChC,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,gBAAgB,YAAY;AAAA,MACtD,GAAG;AAAA,MACH;AAAA,MACA,oBAAoB,WAAW;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eAAe,eAAsD;AAAA,MACzE,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAWO,MAAM,gBAAgB,OAC3B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,WAAW,UAAU,GAAG,KAAK,IAAI,IAAI;AAE7C,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,kBAAkB;AAAA,MAClC,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,QAAI,OAAc,CAAC;AAEnB,QAAI,SAAS,gBAAgB;AAC3B,aAAO,MAAM,cAAc,UAAU,QAAQ,cAAc;AAAA,IAC7D;AAEA,UAAM,gBAAgB,MAAM,kBAAkB,cAAc;AAAA,MAC1D,GAAG;AAAA,MACH;AAAA,MACA,oBAAoB,WAAW;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eACJ,eAA0D;AAAA,MACxD,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAgBO,MAAM,0BAA0B,OACrC,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,aAAa,UAAU,WAAW,SAAS,eAAe,SAAS,IACzE,IAAI;AAEN,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,4BAA4B;AAAA,MAC5C,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,QAAI,OAAc,CAAC;AAEnB,QAAI,SAAS,gBAAgB;AAC3B,aAAO,MAAM,cAAc,UAAU,QAAQ,cAAc;AAAA,IAC7D;AAEA,UAAM,gBAAgB,MAAM,4BAA4B,gBAAgB;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,WAAW;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eACJ,eAAgE;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAgBO,MAAM,+BAA+B,OAC1C,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,aAAa,WAAW,SAAS,UAAU,QAAQ,IAAI,IAAI;AAEnE,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,iCAAiC;AAAA,MACjD,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,QAAI,OAAc,CAAC;AAEnB,QAAI,SAAS,gBAAgB;AAC3B,aAAO,MAAM,cAAc,UAAU,QAAQ,cAAc;AAAA,IAC7D;AAEA,UAAM,gBACJ,MAAM,iCAAiC,qBAAqB;AAAA,MAC1D;AAAA,MACA;AAAA,MACA,oBAAoB,WAAW;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEH,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eACJ,eAAgE;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAYO,MAAM,kCAAkC,OAC7C,KACA,KACA,UACkB;AAClB,QAAM,EAAE,aAAa,IAAI,IAAI;AAC7B,QAAM,EAAE,aAAa,UAAU,IAAI,IAAI;AAEvC,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,oCAAoC;AAAA,MACpD,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAc,MAAM,WAAW;AAAA,MACnC;AAAA,QACE,gBAAgB,cAAc;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,gBACJ,MAAM,oCAAoC,wBAAwB;AAAA,MAChE;AAAA,MACA;AAAA,MACA,oBAAoB,WAAW;AAAA,MAC/B;AAAA,IACF,CAAC;AAEH,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eACJ,eAAgE;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAYO,MAAM,WAAW,OACtB,KACA,KACA,UACkB;AAClB,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,EAAE,WAAW,IAAI,IAAI,IAAI;AAE/B,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa;AAAA,MACb,gBAAgB,aAAa;AAAA,MAC7B,YAAY,CAAC,mBAAmB,QAAQ;AAAA,IAC1C,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI;AACF,QAAI,eAA6B,CAAC;AAClC,QAAI,SAAS,gBAAgB;AAC3B,qBAAe,MAAM,sBAAsB,CAAC,IAAI,GAAG,GAAG,QAAQ,EAAE;AAAA,IAClE;AAEA,UAAM,gBAAgB,MAAM,aAAa,SAAS;AAAA,MAChD;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,WAAW;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,eAAe;AAClB,mBAAa,2BAA2B,KAAK,cAAc;AAC3D;AAAA,IACF;AAEA,UAAM,eACJ,eAAgE;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AASO,MAAM,iBAAiB,OAC5B,KACA,QACG;AACH,QAAM,EAAE,UAAU,YAAY,IAAI,IAAI;AACtC,QAAM,EAAE,MAAM,SAAS,aAAa,IAAI,IAAI;AAE5C,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,YAAY,KAAK;AAAA,MAChC,aAAa,CAAC;AAAA,MACd,gBAAgB,mBAAmB;AAAA,MACnC,YAAY,CAAC,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAGA,MAAI,UAAU,gBAAgB,kCAAkC;AAChE,MAAI,UAAU,iBAAiB,wBAAwB;AACvD,MAAI,UAAU,cAAc,YAAY;AACxC,MAAI,UAAU,qBAAqB,IAAI;AACvC,MAAI,eAAe;AACnB,MAAI,MAAM,iBAAiB;AAC3B,MAAI,QAAQ;AAGZ,qBACG,eAAe,UAAU,UAAU;AAAA,IAClC,WAAW,CAAC,UAAU;AACpB,UAAI,MAAM,SAAS,KAAK,UAAU,EAAE,MAAM,CAAC,CAAC;AAAA;AAAA,CAAM;AAClD,UAAI,QAAQ;AAAA,IACd;AAAA,EACF,CAAC,EACA,KAAK,OAAO,iBAAiB;AAC5B,UAAM,yBAAyB,SAAS;AAAA,MACtC,CAAC,QAAQ,IAAI,SAAS;AAAA,IACxB,GAAG;AACH,UAAM,yBAAyB,yBAC3B,uBAAuB,MAAM,GAAG,EAAE,SAClC;AACJ,QAAI,yBAAyB,GAAG;AAK9B,YAAM,gBAAgB;AAAA,QACpB,EAAE,YAAY;AAAA,QACd;AAAA,UACE,MAAM;AAAA,YACJ;AAAA,YACA,QAAQ,MAAM;AAAA,YACd,WAAW,SAAS;AAAA,YACpB,gBAAgB,cAAc;AAAA,YAC9B,UAAU;AAAA,cACR,GAAG,SAAS,IAAI,CAAC,SAAS;AAAA,gBACxB,MAAM,IAAI;AAAA,gBACV,SAAS,IAAI;AAAA,gBACb,WAAW,IAAI;AAAA,cACjB,EAAE;AAAA,cACF;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,aAAa;AAAA,gBACtB,cAAc,aAAa;AAAA,gBAC3B,WAAW,oBAAI,KAAK;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,EAAE,QAAQ,MAAM,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAGA,QAAI;AAAA,MACF,SAAS,KAAK,UAAU,EAAE,MAAM,MAAM,UAAU,aAAa,CAAC,CAAC;AAAA;AAAA;AAAA,IACjE;AACA,QAAI,IAAI;AAAA,EACV,CAAC,EACA,MAAM,CAAC,QAAQ;AAEd,QAAI;AAAA,MACF;AAAA,QAAuB,KAAK,UAAU,EAAE,SAAS,IAAI,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA,IACjE;AACA,QAAI,IAAI;AAAA,EACV,CAAC;AACL;AAcO,MAAM,eAAe,OAC1B,KACA,QACG;AACH,MAAI;AACF,UAAM,EAAE,MAAM,WAAW,eAAe,aAAa,aAAa,IAChE,IAAI;AAEN,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,YAAY,KAAK;AAAA,QAChC,aAAa;AAAA,QACb,gBAAgB,iBAAiB;AAAA,QACjC,YAAY,CAAC,QAAQ;AAAA,MACvB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,mBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,IACF;AAEA,UAAM,WAAY,MAAM,iBAAiB,aAAa;AAAA,MACpD;AAAA,MACA;AAAA,MACA,oBAAoB,WAAW;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC,KAAM;AAAA,MACL,gBAAgB;AAAA,MAChB,WAAW;AAAA,IACb;AAEA,UAAM,eACJ,eAA4D;AAAA,MAC1D,MAAM;AAAA,IACR,CAAC;AAEH,QAAI,KAAK,YAAY;AAAA,EACvB,SAAS,OAAO;AACd,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;","names":[]}