@intlayer/backend 3.5.5 → 3.5.7

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 (253) hide show
  1. package/dist/cjs/controllers/ai.controller.cjs +175 -7
  2. package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
  3. package/dist/cjs/controllers/dictionary.controller.cjs +50 -17
  4. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  5. package/dist/cjs/controllers/project.controller.cjs +2 -6
  6. package/dist/cjs/controllers/project.controller.cjs.map +1 -1
  7. package/dist/cjs/controllers/tag.controller.cjs +235 -0
  8. package/dist/cjs/controllers/tag.controller.cjs.map +1 -0
  9. package/dist/cjs/controllers/user.controller.cjs +1 -0
  10. package/dist/cjs/controllers/user.controller.cjs.map +1 -1
  11. package/dist/cjs/export.cjs.map +1 -1
  12. package/dist/cjs/index.cjs +2 -0
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs/models/tag.model.cjs +31 -0
  15. package/dist/cjs/models/tag.model.cjs.map +1 -0
  16. package/dist/cjs/routes/ai.routes.cjs +37 -4
  17. package/dist/cjs/routes/ai.routes.cjs.map +1 -1
  18. package/dist/cjs/routes/dictionary.routes.cjs +4 -4
  19. package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
  20. package/dist/cjs/routes/tags.routes.cjs +60 -0
  21. package/dist/cjs/routes/tags.routes.cjs.map +1 -0
  22. package/dist/cjs/schemas/dictionary.schema.cjs +31 -6
  23. package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
  24. package/dist/cjs/schemas/project.schema.cjs +5 -0
  25. package/dist/cjs/schemas/project.schema.cjs.map +1 -1
  26. package/dist/cjs/schemas/tag.schema.cjs +64 -0
  27. package/dist/cjs/schemas/tag.schema.cjs.map +1 -0
  28. package/dist/cjs/services/dictionary.service.cjs +138 -27
  29. package/dist/cjs/services/dictionary.service.cjs.map +1 -1
  30. package/dist/cjs/services/project.service.cjs +13 -5
  31. package/dist/cjs/services/project.service.cjs.map +1 -1
  32. package/dist/cjs/services/tag.service.cjs +91 -0
  33. package/dist/cjs/services/tag.service.cjs.map +1 -0
  34. package/dist/cjs/types/dictionary.types.cjs.map +1 -1
  35. package/dist/cjs/types/tag.types.cjs +17 -0
  36. package/dist/cjs/types/tag.types.cjs.map +1 -0
  37. package/dist/cjs/utils/AI/askDocQuestion.cjs +185 -0
  38. package/dist/cjs/utils/AI/askDocQuestion.cjs.map +1 -0
  39. package/dist/cjs/utils/AI/embeddings.json +150583 -0
  40. package/dist/cjs/utils/{audit → auditDictionary}/PROMPT.md +6 -1
  41. package/dist/cjs/utils/{audit → auditDictionary}/index.cjs +10 -8
  42. package/dist/cjs/utils/auditDictionary/index.cjs.map +1 -0
  43. package/dist/cjs/utils/auditDictionaryField/PROMPT.md +115 -0
  44. package/dist/cjs/utils/auditDictionaryField/index.cjs +80 -0
  45. package/dist/cjs/utils/auditDictionaryField/index.cjs.map +1 -0
  46. package/dist/cjs/utils/auditDictionaryMetadata/PROMPT.md +76 -0
  47. package/dist/cjs/utils/auditDictionaryMetadata/index.cjs +76 -0
  48. package/dist/cjs/utils/auditDictionaryMetadata/index.cjs.map +1 -0
  49. package/dist/cjs/utils/auditTag/PROMPT.md +34 -0
  50. package/dist/cjs/utils/auditTag/index.cjs +72 -0
  51. package/dist/cjs/utils/auditTag/index.cjs.map +1 -0
  52. package/dist/cjs/utils/ensureArrayQueryFilter.cjs +39 -0
  53. package/dist/cjs/utils/ensureArrayQueryFilter.cjs.map +1 -0
  54. package/dist/cjs/utils/ensureMongoDocumentToObject.cjs +35 -0
  55. package/dist/cjs/utils/ensureMongoDocumentToObject.cjs.map +1 -0
  56. package/dist/cjs/utils/errors/errorCodes.cjs +91 -0
  57. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  58. package/dist/cjs/utils/filtersAndPagination/getDictionaryFiltersAndPagination.cjs +10 -11
  59. package/dist/cjs/utils/filtersAndPagination/getDictionaryFiltersAndPagination.cjs.map +1 -1
  60. package/dist/cjs/utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs +6 -10
  61. package/dist/cjs/utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs.map +1 -1
  62. package/dist/cjs/utils/filtersAndPagination/getProjectFiltersAndPagination.cjs +6 -10
  63. package/dist/cjs/utils/filtersAndPagination/getProjectFiltersAndPagination.cjs.map +1 -1
  64. package/dist/cjs/utils/filtersAndPagination/getTagFiltersAndPagination.cjs +51 -0
  65. package/dist/cjs/utils/filtersAndPagination/getTagFiltersAndPagination.cjs.map +1 -0
  66. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs +2 -9
  67. package/dist/cjs/utils/filtersAndPagination/getUserFiltersAndPagination.cjs.map +1 -1
  68. package/dist/cjs/utils/mapper/dictionary.cjs +8 -4
  69. package/dist/cjs/utils/mapper/dictionary.cjs.map +1 -1
  70. package/dist/cjs/utils/mapper/organization.cjs +2 -4
  71. package/dist/cjs/utils/mapper/organization.cjs.map +1 -1
  72. package/dist/cjs/utils/mapper/project.cjs +2 -4
  73. package/dist/cjs/utils/mapper/project.cjs.map +1 -1
  74. package/dist/cjs/utils/mapper/tag.cjs +37 -0
  75. package/dist/cjs/utils/mapper/tag.cjs.map +1 -0
  76. package/dist/cjs/utils/mapper/user.cjs +2 -4
  77. package/dist/cjs/utils/mapper/user.cjs.map +1 -1
  78. package/dist/cjs/utils/removeObjectKeys.cjs +35 -0
  79. package/dist/cjs/utils/removeObjectKeys.cjs.map +1 -0
  80. package/dist/cjs/utils/validation/validateProject.cjs +17 -10
  81. package/dist/cjs/utils/validation/validateProject.cjs.map +1 -1
  82. package/dist/cjs/utils/validation/validateTag.cjs +93 -0
  83. package/dist/cjs/utils/validation/validateTag.cjs.map +1 -0
  84. package/dist/esm/controllers/ai.controller.mjs +170 -6
  85. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  86. package/dist/esm/controllers/dictionary.controller.mjs +50 -17
  87. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  88. package/dist/esm/controllers/project.controller.mjs +2 -6
  89. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  90. package/dist/esm/controllers/tag.controller.mjs +203 -0
  91. package/dist/esm/controllers/tag.controller.mjs.map +1 -0
  92. package/dist/esm/controllers/user.controller.mjs +1 -0
  93. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  94. package/dist/esm/export.mjs.map +1 -1
  95. package/dist/esm/index.mjs +2 -0
  96. package/dist/esm/index.mjs.map +1 -1
  97. package/dist/esm/models/tag.model.mjs +7 -0
  98. package/dist/esm/models/tag.model.mjs.map +1 -0
  99. package/dist/esm/routes/ai.routes.mjs +44 -5
  100. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  101. package/dist/esm/routes/dictionary.routes.mjs +4 -4
  102. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  103. package/dist/esm/routes/tags.routes.mjs +40 -0
  104. package/dist/esm/routes/tags.routes.mjs.map +1 -0
  105. package/dist/esm/schemas/dictionary.schema.mjs +31 -6
  106. package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
  107. package/dist/esm/schemas/project.schema.mjs +5 -0
  108. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  109. package/dist/esm/schemas/tag.schema.mjs +45 -0
  110. package/dist/esm/schemas/tag.schema.mjs.map +1 -0
  111. package/dist/esm/services/dictionary.service.mjs +136 -27
  112. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  113. package/dist/esm/services/project.service.mjs +13 -5
  114. package/dist/esm/services/project.service.mjs.map +1 -1
  115. package/dist/esm/services/tag.service.mjs +61 -0
  116. package/dist/esm/services/tag.service.mjs.map +1 -0
  117. package/dist/esm/types/tag.types.mjs +1 -0
  118. package/dist/esm/types/tag.types.mjs.map +1 -0
  119. package/dist/esm/utils/AI/askDocQuestion.mjs +148 -0
  120. package/dist/esm/utils/AI/askDocQuestion.mjs.map +1 -0
  121. package/dist/esm/utils/AI/embeddings.json +150583 -0
  122. package/dist/esm/utils/{audit → auditDictionary}/PROMPT.md +6 -1
  123. package/dist/esm/utils/{audit → auditDictionary}/index.mjs +6 -4
  124. package/dist/esm/utils/auditDictionary/index.mjs.map +1 -0
  125. package/dist/esm/utils/auditDictionaryField/PROMPT.md +115 -0
  126. package/dist/esm/utils/auditDictionaryField/index.mjs +55 -0
  127. package/dist/esm/utils/auditDictionaryField/index.mjs.map +1 -0
  128. package/dist/esm/utils/auditDictionaryMetadata/PROMPT.md +76 -0
  129. package/dist/esm/utils/auditDictionaryMetadata/index.mjs +51 -0
  130. package/dist/esm/utils/auditDictionaryMetadata/index.mjs.map +1 -0
  131. package/dist/esm/utils/auditTag/PROMPT.md +34 -0
  132. package/dist/esm/utils/auditTag/index.mjs +47 -0
  133. package/dist/esm/utils/auditTag/index.mjs.map +1 -0
  134. package/dist/esm/utils/ensureArrayQueryFilter.mjs +15 -0
  135. package/dist/esm/utils/ensureArrayQueryFilter.mjs.map +1 -0
  136. package/dist/esm/utils/ensureMongoDocumentToObject.mjs +11 -0
  137. package/dist/esm/utils/ensureMongoDocumentToObject.mjs.map +1 -0
  138. package/dist/esm/utils/errors/errorCodes.mjs +91 -0
  139. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  140. package/dist/esm/utils/filtersAndPagination/getDictionaryFiltersAndPagination.mjs +10 -11
  141. package/dist/esm/utils/filtersAndPagination/getDictionaryFiltersAndPagination.mjs.map +1 -1
  142. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs +6 -10
  143. package/dist/esm/utils/filtersAndPagination/getOrganizationFiltersAndPagination.mjs.map +1 -1
  144. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs +6 -10
  145. package/dist/esm/utils/filtersAndPagination/getProjectFiltersAndPagination.mjs.map +1 -1
  146. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs +29 -0
  147. package/dist/esm/utils/filtersAndPagination/getTagFiltersAndPagination.mjs.map +1 -0
  148. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs +2 -9
  149. package/dist/esm/utils/filtersAndPagination/getUserFiltersAndPagination.mjs.map +1 -1
  150. package/dist/esm/utils/mapper/dictionary.mjs +8 -4
  151. package/dist/esm/utils/mapper/dictionary.mjs.map +1 -1
  152. package/dist/esm/utils/mapper/organization.mjs +2 -4
  153. package/dist/esm/utils/mapper/organization.mjs.map +1 -1
  154. package/dist/esm/utils/mapper/project.mjs +2 -4
  155. package/dist/esm/utils/mapper/project.mjs.map +1 -1
  156. package/dist/esm/utils/mapper/tag.mjs +12 -0
  157. package/dist/esm/utils/mapper/tag.mjs.map +1 -0
  158. package/dist/esm/utils/mapper/user.mjs +2 -4
  159. package/dist/esm/utils/mapper/user.mjs.map +1 -1
  160. package/dist/esm/utils/removeObjectKeys.mjs +11 -0
  161. package/dist/esm/utils/removeObjectKeys.mjs.map +1 -0
  162. package/dist/esm/utils/validation/validateProject.mjs +17 -10
  163. package/dist/esm/utils/validation/validateProject.mjs.map +1 -1
  164. package/dist/esm/utils/validation/validateTag.mjs +65 -0
  165. package/dist/esm/utils/validation/validateTag.mjs.map +1 -0
  166. package/dist/types/controllers/ai.controller.d.ts +51 -4
  167. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  168. package/dist/types/controllers/dictionary.controller.d.ts +6 -3
  169. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  170. package/dist/types/controllers/project.controller.d.ts +2 -4
  171. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  172. package/dist/types/controllers/tag.controller.d.ts +39 -0
  173. package/dist/types/controllers/tag.controller.d.ts.map +1 -0
  174. package/dist/types/controllers/user.controller.d.ts.map +1 -1
  175. package/dist/types/export.d.ts +2 -0
  176. package/dist/types/export.d.ts.map +1 -1
  177. package/dist/types/index.d.ts.map +1 -1
  178. package/dist/types/models/dictionary.model.d.ts +1 -0
  179. package/dist/types/models/dictionary.model.d.ts.map +1 -1
  180. package/dist/types/models/tag.model.d.ts +3 -0
  181. package/dist/types/models/tag.model.d.ts.map +1 -0
  182. package/dist/types/routes/ai.routes.d.ts +21 -1
  183. package/dist/types/routes/ai.routes.d.ts.map +1 -1
  184. package/dist/types/routes/dictionary.routes.d.ts +6 -2
  185. package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
  186. package/dist/types/routes/tags.routes.d.ts +29 -0
  187. package/dist/types/routes/tags.routes.d.ts.map +1 -0
  188. package/dist/types/schemas/dictionary.schema.d.ts +1 -0
  189. package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
  190. package/dist/types/schemas/project.schema.d.ts.map +1 -1
  191. package/dist/types/schemas/tag.schema.d.ts +16 -0
  192. package/dist/types/schemas/tag.schema.d.ts.map +1 -0
  193. package/dist/types/services/dictionary.service.d.ts +10 -2
  194. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  195. package/dist/types/services/project.service.d.ts.map +1 -1
  196. package/dist/types/services/tag.service.d.ts +45 -0
  197. package/dist/types/services/tag.service.d.ts.map +1 -0
  198. package/dist/types/types/dictionary.types.d.ts +14 -4
  199. package/dist/types/types/dictionary.types.d.ts.map +1 -1
  200. package/dist/types/types/tag.types.d.ts +26 -0
  201. package/dist/types/types/tag.types.d.ts.map +1 -0
  202. package/dist/types/utils/AI/askDocQuestion.d.ts +38 -0
  203. package/dist/types/utils/AI/askDocQuestion.d.ts.map +1 -0
  204. package/dist/types/utils/auditDictionary/index.d.ts +24 -0
  205. package/dist/types/utils/auditDictionary/index.d.ts.map +1 -0
  206. package/dist/types/utils/auditDictionaryField/index.d.ts +24 -0
  207. package/dist/types/utils/auditDictionaryField/index.d.ts.map +1 -0
  208. package/dist/types/utils/auditDictionaryMetadata/index.d.ts +21 -0
  209. package/dist/types/utils/auditDictionaryMetadata/index.d.ts.map +1 -0
  210. package/dist/types/utils/{audit → auditTag}/index.d.ts +5 -6
  211. package/dist/types/utils/auditTag/index.d.ts.map +1 -0
  212. package/dist/types/utils/ensureArrayQueryFilter.d.ts +2 -0
  213. package/dist/types/utils/ensureArrayQueryFilter.d.ts.map +1 -0
  214. package/dist/types/utils/ensureMongoDocumentToObject.d.ts +8 -0
  215. package/dist/types/utils/ensureMongoDocumentToObject.d.ts.map +1 -0
  216. package/dist/types/utils/errors/errorCodes.d.ts +91 -0
  217. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  218. package/dist/types/utils/filtersAndPagination/getDictionaryFiltersAndPagination.d.ts +2 -0
  219. package/dist/types/utils/filtersAndPagination/getDictionaryFiltersAndPagination.d.ts.map +1 -1
  220. package/dist/types/utils/filtersAndPagination/getOrganizationFiltersAndPagination.d.ts.map +1 -1
  221. package/dist/types/utils/filtersAndPagination/getProjectFiltersAndPagination.d.ts.map +1 -1
  222. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts +24 -0
  223. package/dist/types/utils/filtersAndPagination/getTagFiltersAndPagination.d.ts.map +1 -0
  224. package/dist/types/utils/filtersAndPagination/getUserFiltersAndPagination.d.ts.map +1 -1
  225. package/dist/types/utils/mapper/dictionary.d.ts +1 -1
  226. package/dist/types/utils/mapper/dictionary.d.ts.map +1 -1
  227. package/dist/types/utils/mapper/organization.d.ts.map +1 -1
  228. package/dist/types/utils/mapper/project.d.ts.map +1 -1
  229. package/dist/types/utils/mapper/tag.d.ts +16 -0
  230. package/dist/types/utils/mapper/tag.d.ts.map +1 -0
  231. package/dist/types/utils/mapper/user.d.ts +2 -2
  232. package/dist/types/utils/mapper/user.d.ts.map +1 -1
  233. package/dist/types/utils/removeObjectKeys.d.ts +2 -0
  234. package/dist/types/utils/removeObjectKeys.d.ts.map +1 -0
  235. package/dist/types/utils/validation/validateProject.d.ts.map +1 -1
  236. package/dist/types/utils/validation/validateTag.d.ts +16 -0
  237. package/dist/types/utils/validation/validateTag.d.ts.map +1 -0
  238. package/package.json +11 -10
  239. package/dist/cjs/utils/audit/index.cjs.map +0 -1
  240. package/dist/esm/utils/audit/index.mjs.map +0 -1
  241. package/dist/types/utils/audit/index.d.ts.map +0 -1
  242. /package/dist/cjs/utils/{audit → auditDictionary}/CJS_FORMAT.md +0 -0
  243. /package/dist/cjs/utils/{audit → auditDictionary}/JSON_FORMAT.md +0 -0
  244. /package/dist/cjs/utils/{audit → auditDictionary}/JSX_FORMAT.md +0 -0
  245. /package/dist/cjs/utils/{audit → auditDictionary}/MJS_FORMAT.md +0 -0
  246. /package/dist/cjs/utils/{audit → auditDictionary}/TSX_FORMAT.md +0 -0
  247. /package/dist/cjs/utils/{audit → auditDictionary}/TS_FORMAT.md +0 -0
  248. /package/dist/esm/utils/{audit → auditDictionary}/CJS_FORMAT.md +0 -0
  249. /package/dist/esm/utils/{audit → auditDictionary}/JSON_FORMAT.md +0 -0
  250. /package/dist/esm/utils/{audit → auditDictionary}/JSX_FORMAT.md +0 -0
  251. /package/dist/esm/utils/{audit → auditDictionary}/MJS_FORMAT.md +0 -0
  252. /package/dist/esm/utils/{audit → auditDictionary}/TSX_FORMAT.md +0 -0
  253. /package/dist/esm/utils/{audit → auditDictionary}/TS_FORMAT.md +0 -0
@@ -0,0 +1,40 @@
1
+ import {
2
+ addTag,
3
+ deleteTag,
4
+ getTags,
5
+ updateTag
6
+ } from './../controllers/tag.controller.mjs';
7
+ import { Router } from "express";
8
+ const tagRouter = Router();
9
+ const baseURL = `${process.env.BACKEND_URL}/api/tag`;
10
+ const tagRoutes = {
11
+ getTags: {
12
+ urlModel: "/",
13
+ url: baseURL,
14
+ method: "GET"
15
+ },
16
+ addTag: {
17
+ urlModel: "/",
18
+ url: baseURL,
19
+ method: "POST"
20
+ },
21
+ updateTag: {
22
+ urlModel: "/:tagId",
23
+ url: ({ tagId }) => `${baseURL}/${tagId}`,
24
+ method: "PUT"
25
+ },
26
+ deleteTag: {
27
+ urlModel: "/:tagId",
28
+ url: ({ tagId }) => `${baseURL}/${tagId}`,
29
+ method: "DELETE"
30
+ }
31
+ };
32
+ tagRouter.get(tagRoutes.getTags.urlModel, getTags);
33
+ tagRouter.post(tagRoutes.addTag.urlModel, addTag);
34
+ tagRouter.put(tagRoutes.updateTag.urlModel, updateTag);
35
+ tagRouter.delete(tagRoutes.deleteTag.urlModel, deleteTag);
36
+ export {
37
+ tagRouter,
38
+ tagRoutes
39
+ };
40
+ //# sourceMappingURL=tags.routes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/routes/tags.routes.ts"],"sourcesContent":["import {\n addTag,\n deleteTag,\n getTags,\n updateTag,\n} from '@controllers/tag.controller';\nimport { Router } from 'express';\nimport { Routes } from '@/types/Routes';\n\nexport const tagRouter: Router = Router();\n\nconst baseURL = `${process.env.BACKEND_URL}/api/tag`;\n\nexport const tagRoutes = {\n getTags: {\n urlModel: '/',\n url: baseURL,\n method: 'GET',\n },\n addTag: {\n urlModel: '/',\n url: baseURL,\n method: 'POST',\n },\n updateTag: {\n urlModel: '/:tagId',\n url: ({ tagId }: { tagId: string }) => `${baseURL}/${tagId}`,\n method: 'PUT',\n },\n deleteTag: {\n urlModel: '/:tagId',\n url: ({ tagId }: { tagId: string }) => `${baseURL}/${tagId}`,\n method: 'DELETE',\n },\n} satisfies Routes;\n\ntagRouter.get(tagRoutes.getTags.urlModel, getTags);\n\ntagRouter.post(tagRoutes.addTag.urlModel, addTag);\ntagRouter.put(tagRoutes.updateTag.urlModel, updateTag);\ntagRouter.delete(tagRoutes.deleteTag.urlModel, deleteTag);\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAGhB,MAAM,YAAoB,OAAO;AAExC,MAAM,UAAU,GAAG,QAAQ,IAAI,WAAW;AAEnC,MAAM,YAAY;AAAA,EACvB,SAAS;AAAA,IACP,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AAAA,EACA,WAAW;AAAA,IACT,UAAU;AAAA,IACV,KAAK,CAAC,EAAE,MAAM,MAAyB,GAAG,OAAO,IAAI,KAAK;AAAA,IAC1D,QAAQ;AAAA,EACV;AAAA,EACA,WAAW;AAAA,IACT,UAAU;AAAA,IACV,KAAK,CAAC,EAAE,MAAM,MAAyB,GAAG,OAAO,IAAI,KAAK;AAAA,IAC1D,QAAQ;AAAA,EACV;AACF;AAEA,UAAU,IAAI,UAAU,QAAQ,UAAU,OAAO;AAEjD,UAAU,KAAK,UAAU,OAAO,UAAU,MAAM;AAChD,UAAU,IAAI,UAAU,UAAU,UAAU,SAAS;AACrD,UAAU,OAAO,UAAU,UAAU,UAAU,SAAS;","names":[]}
@@ -1,4 +1,21 @@
1
1
  import { Schema } from "mongoose";
2
+ const versionedContentElSchema = new Schema(
3
+ {
4
+ name: {
5
+ type: String
6
+ },
7
+ description: {
8
+ type: String
9
+ },
10
+ content: {
11
+ type: Schema.Types.Mixed,
12
+ required: true
13
+ }
14
+ },
15
+ {
16
+ timestamps: true
17
+ }
18
+ );
2
19
  const dictionarySchema = new Schema(
3
20
  {
4
21
  projectIds: {
@@ -18,13 +35,15 @@ const dictionarySchema = new Schema(
18
35
  type: String,
19
36
  default: ""
20
37
  },
21
- version: {
22
- type: Number,
23
- default: 1
38
+ tags: {
39
+ type: [String],
40
+ default: []
24
41
  },
25
42
  content: {
26
- type: [Schema.Types.Mixed],
27
- required: true
43
+ type: Map,
44
+ of: versionedContentElSchema,
45
+ required: true,
46
+ default: null
28
47
  },
29
48
  creatorId: {
30
49
  type: Schema.Types.ObjectId,
@@ -32,7 +51,13 @@ const dictionarySchema = new Schema(
32
51
  required: true
33
52
  },
34
53
  filePath: {
35
- type: Schema.Types.Mixed
54
+ type: Map,
55
+ of: String,
56
+ default: null
57
+ },
58
+ publishedVersion: {
59
+ type: String,
60
+ default: null
36
61
  }
37
62
  },
38
63
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/schemas/dictionary.schema.ts"],"sourcesContent":["import { Schema } from 'mongoose';\nimport type { Dictionary } from '@/types/dictionary.types';\n\nexport const dictionarySchema = new Schema<Dictionary>(\n {\n projectIds: {\n type: [Schema.Types.ObjectId],\n ref: 'Project',\n required: true,\n },\n key: {\n type: String,\n required: true,\n },\n title: {\n type: String,\n default: '',\n },\n description: {\n type: String,\n default: '',\n },\n version: {\n type: Number,\n default: 1,\n },\n content: {\n type: [Schema.Types.Mixed],\n required: true,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n filePath: {\n type: Schema.Types.Mixed,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":"AAAA,SAAS,cAAc;AAGhB,MAAM,mBAAmB,IAAI;AAAA,EAClC;AAAA,IACE,YAAY;AAAA,MACV,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACP,MAAM,CAAC,OAAO,MAAM,KAAK;AAAA,MACzB,UAAU;AAAA,IACZ;AAAA,IACA,WAAW;AAAA,MACT,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM,OAAO,MAAM;AAAA,IACrB;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/schemas/dictionary.schema.ts"],"sourcesContent":["import { Schema } from 'mongoose';\nimport type { Dictionary, VersionedContentEl } from '@/types/dictionary.types';\n\nconst versionedContentElSchema = new Schema<VersionedContentEl>(\n {\n name: {\n type: String,\n },\n description: {\n type: String,\n },\n content: {\n type: Schema.Types.Mixed,\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n\nexport const dictionarySchema = new Schema<Dictionary>(\n {\n projectIds: {\n type: [Schema.Types.ObjectId],\n ref: 'Project',\n required: true,\n },\n key: {\n type: String,\n required: true,\n },\n title: {\n type: String,\n default: '',\n },\n description: {\n type: String,\n default: '',\n },\n tags: {\n type: [String],\n default: [],\n },\n content: {\n type: Map,\n of: versionedContentElSchema,\n required: true,\n default: null,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n filePath: {\n type: Map,\n of: String,\n default: null,\n },\n publishedVersion: {\n type: String,\n default: null,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":"AAAA,SAAS,cAAc;AAGvB,MAAM,2BAA2B,IAAI;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,MACJ,MAAM;AAAA,IACR;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,MAAM,OAAO,MAAM;AAAA,MACnB,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;AAEO,MAAM,mBAAmB,IAAI;AAAA,EAClC;AAAA,IACE,YAAY;AAAA,MACV,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,CAAC,MAAM;AAAA,MACb,SAAS,CAAC;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,SAAS;AAAA,IACX;AAAA,IACA,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
@@ -3,6 +3,7 @@ import {
3
3
  NAME_MAX_LENGTH,
4
4
  MEMBERS_MIN_LENGTH
5
5
  } from './../utils/validation/validateProject.mjs';
6
+ import { Locales } from "intlayer";
6
7
  import { Schema } from "mongoose";
7
8
  const RightsSchema = new Schema({
8
9
  read: { type: Boolean, required: true },
@@ -41,6 +42,10 @@ const projectSchema = new Schema(
41
42
  minlength: NAME_MIN_LENGTH,
42
43
  maxlength: NAME_MAX_LENGTH
43
44
  },
45
+ locales: {
46
+ type: [String],
47
+ enum: Object.values(Locales)
48
+ },
44
49
  oAuth2Access: [oAuth2AccessSchema],
45
50
  membersIds: {
46
51
  type: [Schema.Types.ObjectId],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/schemas/project.schema.ts"],"sourcesContent":["import {\n NAME_MIN_LENGTH,\n NAME_MAX_LENGTH,\n MEMBERS_MIN_LENGTH,\n} from '@utils/validation/validateProject';\nimport { Schema } from 'mongoose';\nimport { Project, Rights, TokenRights } from '@/types/project.types';\n\nconst RightsSchema = new Schema<Rights>({\n read: { type: Boolean, required: true },\n write: { type: Boolean, required: true },\n admin: { type: Boolean, required: true },\n});\n\nexport const TokenRightsSchema = new Schema<TokenRights>({\n dictionary: { type: RightsSchema, required: true },\n project: { type: RightsSchema, required: true },\n organization: { type: RightsSchema, required: true },\n});\n\n// Define the oAuth2Access subdocument schema with timestamps\nconst oAuth2AccessSchema = new Schema(\n {\n clientId: { type: String, required: true, unique: true },\n clientSecret: { type: String, required: true },\n userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },\n name: { type: String, required: true },\n expiresAt: { type: Date },\n accessToken: { type: [String], required: true },\n rights: { type: TokenRightsSchema, required: true },\n },\n {\n timestamps: true,\n }\n);\n\nexport const projectSchema = new Schema<Project>(\n {\n organizationId: {\n type: Schema.Types.ObjectId,\n ref: 'Organization',\n required: true,\n },\n name: {\n type: String,\n required: true,\n minlength: NAME_MIN_LENGTH,\n maxlength: NAME_MAX_LENGTH,\n },\n oAuth2Access: [oAuth2AccessSchema],\n membersIds: {\n type: [Schema.Types.ObjectId],\n ref: 'User',\n required: true,\n minlength: MEMBERS_MIN_LENGTH,\n },\n adminsIds: {\n type: [Schema.Types.ObjectId],\n ref: 'User',\n required: true,\n minlength: MEMBERS_MIN_LENGTH,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAGvB,MAAM,eAAe,IAAI,OAAe;AAAA,EACtC,MAAM,EAAE,MAAM,SAAS,UAAU,KAAK;AAAA,EACtC,OAAO,EAAE,MAAM,SAAS,UAAU,KAAK;AAAA,EACvC,OAAO,EAAE,MAAM,SAAS,UAAU,KAAK;AACzC,CAAC;AAEM,MAAM,oBAAoB,IAAI,OAAoB;AAAA,EACvD,YAAY,EAAE,MAAM,cAAc,UAAU,KAAK;AAAA,EACjD,SAAS,EAAE,MAAM,cAAc,UAAU,KAAK;AAAA,EAC9C,cAAc,EAAE,MAAM,cAAc,UAAU,KAAK;AACrD,CAAC;AAGD,MAAM,qBAAqB,IAAI;AAAA,EAC7B;AAAA,IACE,UAAU,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,IACvD,cAAc,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,IAC7C,QAAQ,EAAE,MAAM,OAAO,MAAM,UAAU,KAAK,QAAQ,UAAU,KAAK;AAAA,IACnE,MAAM,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,IACrC,WAAW,EAAE,MAAM,KAAK;AAAA,IACxB,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,KAAK;AAAA,IAC9C,QAAQ,EAAE,MAAM,mBAAmB,UAAU,KAAK;AAAA,EACpD;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;AAEO,MAAM,gBAAgB,IAAI;AAAA,EAC/B;AAAA,IACE,gBAAgB;AAAA,MACd,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,IACA,cAAc,CAAC,kBAAkB;AAAA,IACjC,YAAY;AAAA,MACV,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/schemas/project.schema.ts"],"sourcesContent":["import {\n NAME_MIN_LENGTH,\n NAME_MAX_LENGTH,\n MEMBERS_MIN_LENGTH,\n} from '@utils/validation/validateProject';\nimport { Locales } from 'intlayer';\nimport { Schema } from 'mongoose';\nimport { Project, Rights, TokenRights } from '@/types/project.types';\n\nconst RightsSchema = new Schema<Rights>({\n read: { type: Boolean, required: true },\n write: { type: Boolean, required: true },\n admin: { type: Boolean, required: true },\n});\n\nexport const TokenRightsSchema = new Schema<TokenRights>({\n dictionary: { type: RightsSchema, required: true },\n project: { type: RightsSchema, required: true },\n organization: { type: RightsSchema, required: true },\n});\n\n// Define the oAuth2Access subdocument schema with timestamps\nconst oAuth2AccessSchema = new Schema(\n {\n clientId: { type: String, required: true, unique: true },\n clientSecret: { type: String, required: true },\n userId: { type: Schema.Types.ObjectId, ref: 'User', required: true },\n name: { type: String, required: true },\n expiresAt: { type: Date },\n accessToken: { type: [String], required: true },\n rights: { type: TokenRightsSchema, required: true },\n },\n {\n timestamps: true,\n }\n);\n\nexport const projectSchema = new Schema<Project>(\n {\n organizationId: {\n type: Schema.Types.ObjectId,\n ref: 'Organization',\n required: true,\n },\n name: {\n type: String,\n required: true,\n minlength: NAME_MIN_LENGTH,\n maxlength: NAME_MAX_LENGTH,\n },\n locales: {\n type: [String],\n enum: Object.values(Locales),\n },\n oAuth2Access: [oAuth2AccessSchema],\n membersIds: {\n type: [Schema.Types.ObjectId],\n ref: 'User',\n required: true,\n minlength: MEMBERS_MIN_LENGTH,\n },\n adminsIds: {\n type: [Schema.Types.ObjectId],\n ref: 'User',\n required: true,\n minlength: MEMBERS_MIN_LENGTH,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,cAAc;AAGvB,MAAM,eAAe,IAAI,OAAe;AAAA,EACtC,MAAM,EAAE,MAAM,SAAS,UAAU,KAAK;AAAA,EACtC,OAAO,EAAE,MAAM,SAAS,UAAU,KAAK;AAAA,EACvC,OAAO,EAAE,MAAM,SAAS,UAAU,KAAK;AACzC,CAAC;AAEM,MAAM,oBAAoB,IAAI,OAAoB;AAAA,EACvD,YAAY,EAAE,MAAM,cAAc,UAAU,KAAK;AAAA,EACjD,SAAS,EAAE,MAAM,cAAc,UAAU,KAAK;AAAA,EAC9C,cAAc,EAAE,MAAM,cAAc,UAAU,KAAK;AACrD,CAAC;AAGD,MAAM,qBAAqB,IAAI;AAAA,EAC7B;AAAA,IACE,UAAU,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,IACvD,cAAc,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,IAC7C,QAAQ,EAAE,MAAM,OAAO,MAAM,UAAU,KAAK,QAAQ,UAAU,KAAK;AAAA,IACnE,MAAM,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,IACrC,WAAW,EAAE,MAAM,KAAK;AAAA,IACxB,aAAa,EAAE,MAAM,CAAC,MAAM,GAAG,UAAU,KAAK;AAAA,IAC9C,QAAQ,EAAE,MAAM,mBAAmB,UAAU,KAAK;AAAA,EACpD;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;AAEO,MAAM,gBAAgB,IAAI;AAAA,EAC/B;AAAA,IACE,gBAAgB;AAAA,MACd,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,MAAM,CAAC,MAAM;AAAA,MACb,MAAM,OAAO,OAAO,OAAO;AAAA,IAC7B;AAAA,IACA,cAAc,CAAC,kBAAkB;AAAA,IACjC,YAAY;AAAA,MACV,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,MAAM,CAAC,OAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
@@ -0,0 +1,45 @@
1
+ import {
2
+ NAME_MIN_LENGTH,
3
+ NAME_MAX_LENGTH,
4
+ KEY_MAX_LENGTH,
5
+ KEY_MIN_LENGTH
6
+ } from './../utils/validation/validateTag.mjs';
7
+ import { Schema } from "mongoose";
8
+ const tagSchema = new Schema(
9
+ {
10
+ organizationId: {
11
+ type: Schema.Types.ObjectId,
12
+ ref: "Organization",
13
+ required: true
14
+ },
15
+ key: {
16
+ type: String,
17
+ required: true,
18
+ minlength: KEY_MIN_LENGTH,
19
+ maxlength: KEY_MAX_LENGTH
20
+ },
21
+ name: {
22
+ type: String,
23
+ minlength: NAME_MIN_LENGTH,
24
+ maxlength: NAME_MAX_LENGTH
25
+ },
26
+ description: {
27
+ type: String
28
+ },
29
+ instructions: {
30
+ type: String
31
+ },
32
+ creatorId: {
33
+ type: Schema.Types.ObjectId,
34
+ ref: "User",
35
+ required: true
36
+ }
37
+ },
38
+ {
39
+ timestamps: true
40
+ }
41
+ );
42
+ export {
43
+ tagSchema
44
+ };
45
+ //# sourceMappingURL=tag.schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/schemas/tag.schema.ts"],"sourcesContent":["import {\n NAME_MIN_LENGTH,\n NAME_MAX_LENGTH,\n KEY_MAX_LENGTH,\n KEY_MIN_LENGTH,\n} from '@utils/validation/validateTag';\nimport { Schema } from 'mongoose';\nimport { Tag } from '@/types/tag.types';\n\nexport const tagSchema = new Schema<Tag>(\n {\n organizationId: {\n type: Schema.Types.ObjectId,\n ref: 'Organization',\n required: true,\n },\n key: {\n type: String,\n required: true,\n minlength: KEY_MIN_LENGTH,\n maxlength: KEY_MAX_LENGTH,\n },\n name: {\n type: String,\n minlength: NAME_MIN_LENGTH,\n maxlength: NAME_MAX_LENGTH,\n },\n description: {\n type: String,\n },\n instructions: {\n type: String,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAGhB,MAAM,YAAY,IAAI;AAAA,EAC3B;AAAA,IACE,gBAAgB;AAAA,MACd,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,IACR;AAAA,IACA,cAAc;AAAA,MACZ,MAAM;AAAA,IACR;AAAA,IACA,WAAW;AAAA,MACT,MAAM,OAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
@@ -1,34 +1,94 @@
1
1
  import { DictionaryModel } from './../models/dictionary.model.mjs';
2
+ import { ensureMongoDocumentToObject } from './../utils/ensureMongoDocumentToObject.mjs';
2
3
  import { GenericError } from './../utils/errors/index.mjs';
4
+ import { removeObjectKeys } from './../utils/removeObjectKeys.mjs';
3
5
  import {
4
6
  validateDictionary
5
7
  } from './../utils/validation/validateDictionary.mjs';
6
- const findDictionaries = async (filters, skip = 0, limit = 100) => await DictionaryModel.find(filters).skip(skip).limit(limit);
8
+ const findDictionaries = async (filters, skip = 0, limit = 100) => {
9
+ try {
10
+ const dictionaries = await DictionaryModel.aggregate([
11
+ // Stage 1: Match the filters
12
+ { $match: filters },
13
+ // Stage 2: Skip for pagination
14
+ { $skip: skip },
15
+ // Stage 3: Limit the number of documents
16
+ { $limit: limit },
17
+ // Stage 4: Add the 'availableVersions' field
18
+ {
19
+ $addFields: {
20
+ availableVersions: {
21
+ $map: {
22
+ input: { $objectToArray: "$content" },
23
+ as: "version",
24
+ in: "$$version.k"
25
+ }
26
+ }
27
+ }
28
+ }
29
+ // (Optional) Stage 5: Project the fields you want to include/exclude
30
+ // For example, to exclude the entire 'content' field and keep only 'availableVersions'
31
+ // {
32
+ // $project: {
33
+ // content: 0 // Exclude the 'content' field
34
+ // }
35
+ // }
36
+ ]);
37
+ return dictionaries;
38
+ } catch (error) {
39
+ console.error("Error fetching dictionaries:", error);
40
+ throw error;
41
+ }
42
+ };
7
43
  const getDictionaryById = async (dictionaryId) => {
8
- const dictionary = await DictionaryModel.findById(dictionaryId);
9
- if (!dictionary) {
44
+ const dictionary = await DictionaryModel.aggregate([
45
+ // Stage 1: Match the document by ID
46
+ { $match: { _id: dictionaryId } },
47
+ // Stage 2: Add the 'availableVersions' field
48
+ {
49
+ $addFields: {
50
+ availableVersions: {
51
+ $map: {
52
+ input: { $objectToArray: "$content" },
53
+ as: "version",
54
+ in: "$$version.k"
55
+ }
56
+ }
57
+ }
58
+ }
59
+ ]);
60
+ if (!dictionary.length) {
10
61
  throw new GenericError("DICTIONARY_NOT_FOUND", { dictionaryId });
11
62
  }
12
- return dictionary;
63
+ return dictionary[0];
13
64
  };
14
65
  const getDictionaryByKey = async (dictionaryKey, projectId) => {
15
- const dictionary = await DictionaryModel.findOne({
16
- key: dictionaryKey,
17
- projectIds: projectId
18
- });
19
- if (!dictionary) {
66
+ const dictionaries = await getDictionariesByKeys([dictionaryKey], projectId);
67
+ return dictionaries[0];
68
+ };
69
+ const getDictionariesByKeys = async (dictionaryKeys, projectId) => {
70
+ const dictionaries = await DictionaryModel.aggregate([
71
+ // Stage 1: Match the document by key
72
+ { $match: { key: { $in: dictionaryKeys }, projectIds: projectId } },
73
+ // Stage 2: Add the 'availableVersions' field
74
+ {
75
+ $addFields: {
76
+ availableVersions: {
77
+ $map: {
78
+ input: { $objectToArray: "$content" },
79
+ as: "version",
80
+ in: "$$version.k"
81
+ }
82
+ }
83
+ }
84
+ }
85
+ ]);
86
+ if (!dictionaries) {
20
87
  throw new GenericError("DICTIONARY_NOT_FOUND", {
21
- dictionaryKey,
88
+ dictionaryKeys,
22
89
  projectId
23
90
  });
24
91
  }
25
- return dictionary;
26
- };
27
- const getDictionariesByKeys = async (dictionaryKey, projectId) => {
28
- const dictionaries = await DictionaryModel.find({
29
- key: dictionaryKey,
30
- projectIds: projectId
31
- });
32
92
  return dictionaries;
33
93
  };
34
94
  const getDictionariesKeys = async (projectId) => {
@@ -37,6 +97,30 @@ const getDictionariesKeys = async (projectId) => {
37
97
  }).select("key");
38
98
  return dictionaries.map((dictionary) => dictionary.key);
39
99
  };
100
+ const getDictionariesByTags = async (tags, projectId) => {
101
+ const dictionaries = await DictionaryModel.aggregate([
102
+ // Stage 1: Match the document by tags
103
+ {
104
+ $match: {
105
+ tags: { $in: tags },
106
+ projectIds: projectId
107
+ }
108
+ },
109
+ // Stage 2: Add the 'availableVersions' field
110
+ {
111
+ $addFields: {
112
+ availableVersions: {
113
+ $map: {
114
+ input: { $objectToArray: "$content" },
115
+ as: "version",
116
+ in: "$$version.k"
117
+ }
118
+ }
119
+ }
120
+ }
121
+ ]);
122
+ return dictionaries;
123
+ };
40
124
  const countDictionaries = async (filters) => {
41
125
  const result = await DictionaryModel.countDocuments(filters);
42
126
  if (typeof result === "undefined") {
@@ -73,27 +157,31 @@ const getExistingDictionaryKey = async (dictionariesKeys, projectId) => {
73
157
  return { existingDictionariesKey, newDictionariesKey };
74
158
  };
75
159
  const updateDictionaryById = async (dictionaryId, dictionary) => {
76
- const updatedKeys = Object.keys(dictionary);
77
- const errors = validateDictionary(dictionary, updatedKeys);
160
+ const dictionaryObject = ensureMongoDocumentToObject(dictionary);
161
+ const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ["_id"]);
162
+ const updatedKeys = Object.keys(dictionaryToUpdate);
163
+ const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);
78
164
  if (Object.keys(errors).length > 0) {
79
165
  throw new GenericError("DICTIONARY_INVALID_FIELDS", {
80
166
  dictionaryId,
81
167
  errors
82
168
  });
83
169
  }
84
- const existingDictionary = await getDictionaryById(dictionaryId);
85
170
  const result = await DictionaryModel.updateOne(
86
171
  { _id: dictionaryId },
87
- { ...dictionary, content: [existingDictionary.content, dictionary.content] }
172
+ dictionaryToUpdate
88
173
  );
89
174
  if (result.matchedCount === 0) {
90
175
  throw new GenericError("DICTIONARY_UPDATE_FAILED", { dictionaryId });
91
176
  }
92
- return await getDictionaryById(dictionaryId);
177
+ const updatedDictionary = await getDictionaryById(dictionaryId);
178
+ return updatedDictionary;
93
179
  };
94
180
  const updateDictionaryByKey = async (dictionaryKey, dictionary, projectId) => {
95
- const updatedKeys = Object.keys(dictionary);
96
- const errors = validateDictionary(dictionary, updatedKeys);
181
+ const dictionaryObject = ensureMongoDocumentToObject(dictionary);
182
+ const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ["_id"]);
183
+ const updatedKeys = Object.keys(dictionaryToUpdate);
184
+ const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);
97
185
  if (Object.keys(errors).length > 0) {
98
186
  throw new GenericError("DICTIONARY_INVALID_FIELDS", {
99
187
  dictionaryKey,
@@ -101,15 +189,15 @@ const updateDictionaryByKey = async (dictionaryKey, dictionary, projectId) => {
101
189
  errors
102
190
  });
103
191
  }
104
- const existingDictionary = await getDictionaryByKey(dictionaryKey, projectId);
105
192
  const result = await DictionaryModel.updateOne(
106
193
  { key: dictionaryKey, projectIds: projectId },
107
- { ...dictionary, content: [existingDictionary.content, dictionary.content] }
194
+ dictionaryToUpdate
108
195
  );
109
196
  if (result.matchedCount === 0) {
110
197
  throw new GenericError("DICTIONARY_UPDATE_FAILED", { dictionaryKey });
111
198
  }
112
- return await getDictionaryByKey(dictionaryKey, projectId);
199
+ const updatedDictionary = await getDictionaryByKey(dictionaryKey, projectId);
200
+ return updatedDictionary;
113
201
  };
114
202
  const deleteDictionaryById = async (dictionaryId) => {
115
203
  const dictionary = await DictionaryModel.findByIdAndDelete(dictionaryId);
@@ -118,16 +206,37 @@ const deleteDictionaryById = async (dictionaryId) => {
118
206
  }
119
207
  return dictionary;
120
208
  };
209
+ const incrementVersion = (dictionary) => {
210
+ const VERSION_PREFIX = "v";
211
+ const availableVersions = dictionary.availableVersions ?? [];
212
+ const currentVersion = availableVersions.length > 0 ? availableVersions[availableVersions.length - 1] : "v1";
213
+ const getVersionNumber = (version) => {
214
+ const match = version.match(/^v(\d+)$/);
215
+ if (!match) {
216
+ throw new Error(`Invalid version format: ${version}`);
217
+ }
218
+ return parseInt(match[1], 10);
219
+ };
220
+ let newNumber = getVersionNumber(currentVersion) + 1;
221
+ let newVersion = `${VERSION_PREFIX}${newNumber}`;
222
+ while (availableVersions.includes(newVersion)) {
223
+ newNumber += 1;
224
+ newVersion = `${VERSION_PREFIX}${newNumber}`;
225
+ }
226
+ return newVersion;
227
+ };
121
228
  export {
122
229
  countDictionaries,
123
230
  createDictionary,
124
231
  deleteDictionaryById,
125
232
  findDictionaries,
126
233
  getDictionariesByKeys,
234
+ getDictionariesByTags,
127
235
  getDictionariesKeys,
128
236
  getDictionaryById,
129
237
  getDictionaryByKey,
130
238
  getExistingDictionaryKey,
239
+ incrementVersion,
131
240
  updateDictionaryById,
132
241
  updateDictionaryByKey
133
242
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/dictionary.service.ts"],"sourcesContent":["import { DictionaryModel } from '@models/dictionary.model';\nimport { GenericError } from '@utils/errors';\nimport type { DictionaryFilters } from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport {\n type DictionaryFields,\n validateDictionary,\n} from '@utils/validation/validateDictionary';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Dictionary,\n DictionaryData,\n DictionaryDocument,\n} from '@/types/dictionary.types';\n\n/**\n * Finds dictionaries based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of dictionaries matching the filters.\n */\nexport const findDictionaries = async (\n filters: DictionaryFilters,\n skip = 0,\n limit = 100\n): Promise<DictionaryDocument[]> =>\n await DictionaryModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\nexport const getDictionaryById = async (\n dictionaryId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findById(dictionaryId);\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary;\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryKey - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\nexport const getDictionaryByKey = async (\n dictionaryKey: string,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findOne({\n key: dictionaryKey,\n projectIds: projectId,\n });\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', {\n dictionaryKey,\n projectId,\n });\n }\n\n return dictionary;\n};\n\nexport const getDictionariesByKeys = async (\n dictionaryKey: string[],\n projectId: string | ObjectId\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.find({\n key: dictionaryKey,\n projectIds: projectId,\n });\n\n return dictionaries;\n};\n\nexport const getDictionariesKeys = async (\n projectId: string | ObjectId\n): Promise<string[]> => {\n const dictionaries = await DictionaryModel.find({\n projectIds: projectId,\n }).select('key');\n\n return dictionaries.map((dictionary) => dictionary.key);\n};\n\n/**\n * Counts the total number of dictionaries that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of dictionaries.\n */\nexport const countDictionaries = async (\n filters: DictionaryFilters\n): Promise<number> => {\n const result = await DictionaryModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('DICTIONARY_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new dictionary in the database.\n * @param dictionary - The dictionary data to create.\n * @returns The created dictionary.\n */\nexport const createDictionary = async (\n dictionary: DictionaryData\n): Promise<DictionaryDocument> => {\n const errors = await validateDictionary(dictionary);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n errors,\n });\n }\n\n return await DictionaryModel.create(dictionary);\n};\n\ntype GetExistingDictionaryResult = {\n existingDictionariesKey: string[];\n newDictionariesKey: string[];\n};\n\n/**\n * Gets the existing dictionaries from the provided list of keys.\n * @param dictionariesKeys - List of dictionary keys to check.\n * @param projectId - The ID of the project to check the dictionaries against.\n * @returns The existing dictionaries and the new dictionaries.\n */\nexport const getExistingDictionaryKey = async (\n dictionariesKeys: string[],\n projectId: string | ObjectId\n): Promise<GetExistingDictionaryResult> => {\n // Fetch dictionaries from the database where the key is in the provided list\n const existingDictionaries = await DictionaryModel.find({\n key: { $in: dictionariesKeys },\n projectIds: projectId,\n });\n\n // Map existing dictionaries to a LocalDictionary object\n const existingDictionariesKey: string[] = [];\n const newDictionariesKey: string[] = [];\n\n for (const key of dictionariesKeys) {\n const isDictionaryExist = existingDictionaries.some(\n (dictionary) => dictionary.key === key\n );\n\n if (isDictionaryExist) {\n existingDictionariesKey.push(key);\n } else {\n newDictionariesKey.push(key);\n }\n }\n\n return { existingDictionariesKey, newDictionariesKey };\n};\n\n/**\n * Updates an existing dictionary in the database by its ID.\n * @param dictionaryId - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryById = async (\n dictionaryId: string | ObjectId,\n dictionary: Partial<Dictionary>\n): Promise<DictionaryDocument> => {\n const updatedKeys = Object.keys(dictionary) as DictionaryFields;\n const errors = validateDictionary(dictionary, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryId,\n errors,\n });\n }\n\n const existingDictionary = await getDictionaryById(dictionaryId);\n\n const result = await DictionaryModel.updateOne(\n { _id: dictionaryId },\n { ...dictionary, content: [existingDictionary.content, dictionary.content] }\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryId });\n }\n\n return await getDictionaryById(dictionaryId);\n};\n\n/**\n * Updates an existing dictionary in the database by its key.\n * @param dictionaryKey - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryByKey = async (\n dictionaryKey: string,\n dictionary: Partial<Dictionary>,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const updatedKeys = Object.keys(dictionary) as DictionaryFields;\n const errors = validateDictionary(dictionary, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryKey,\n projectId,\n errors,\n });\n }\n\n const existingDictionary = await getDictionaryByKey(dictionaryKey, projectId);\n\n const result = await DictionaryModel.updateOne(\n { key: dictionaryKey, projectIds: projectId },\n { ...dictionary, content: [existingDictionary.content, dictionary.content] }\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryKey });\n }\n\n return await getDictionaryByKey(dictionaryKey, projectId);\n};\n\n/**\n * Deletes a dictionary from the database by its ID.\n * @param dictionaryId - The ID of the dictionary to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteDictionaryById = async (\n dictionaryId: string\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findByIdAndDelete(dictionaryId);\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/services/dictionary.service.ts"],"sourcesContent":["import { DictionaryModel } from '@models/dictionary.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { DictionaryFilters } from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type DictionaryFields,\n validateDictionary,\n} from '@utils/validation/validateDictionary';\nimport { ObjectId } from 'mongoose';\nimport type {\n Dictionary,\n DictionaryData,\n DictionaryDocument,\n} from '@/types/dictionary.types';\nimport type { Project } from '@/types/project.types';\n\n/**\n * Finds dictionaries based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of dictionaries matching the filters.\n */\nexport const findDictionaries = async (\n filters: DictionaryFilters,\n skip = 0,\n limit = 100\n): Promise<DictionaryDocument[]> => {\n try {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the filters\n { $match: filters },\n\n // Stage 2: Skip for pagination\n { $skip: skip },\n\n // Stage 3: Limit the number of documents\n { $limit: limit },\n\n // Stage 4: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n\n // (Optional) Stage 5: Project the fields you want to include/exclude\n // For example, to exclude the entire 'content' field and keep only 'availableVersions'\n // {\n // $project: {\n // content: 0 // Exclude the 'content' field\n // }\n // }\n ]);\n\n return dictionaries;\n } catch (error) {\n console.error('Error fetching dictionaries:', error);\n throw error;\n }\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\n/**\n * Finds a dictionary by its ID and includes the 'availableVersions' field.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID with available versions.\n */\nexport const getDictionaryById = async (\n dictionaryId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by ID\n { $match: { _id: dictionaryId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionary.length) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary[0];\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryKey - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\nexport const getDictionaryByKey = async (\n dictionaryKey: string,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaries = await getDictionariesByKeys([dictionaryKey], projectId);\n\n return dictionaries[0];\n};\n\nexport const getDictionariesByKeys = async (\n dictionaryKeys: string[],\n projectId: string | ObjectId\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by key\n { $match: { key: { $in: dictionaryKeys }, projectIds: projectId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionaries) {\n throw new GenericError('DICTIONARY_NOT_FOUND', {\n dictionaryKeys,\n projectId,\n });\n }\n\n return dictionaries;\n};\n\nexport const getDictionariesKeys = async (\n projectId: string | ObjectId\n): Promise<string[]> => {\n const dictionaries = await DictionaryModel.find({\n projectIds: projectId,\n }).select('key');\n\n return dictionaries.map((dictionary) => dictionary.key);\n};\n\nexport const getDictionariesByTags = async (\n tags: string[],\n projectId: string | Project['_id']\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by tags\n {\n $match: {\n tags: { $in: tags },\n projectIds: projectId,\n },\n },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n return dictionaries;\n};\n\n/**\n * Counts the total number of dictionaries that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of dictionaries.\n */\nexport const countDictionaries = async (\n filters: DictionaryFilters\n): Promise<number> => {\n const result = await DictionaryModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('DICTIONARY_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new dictionary in the database.\n * @param dictionary - The dictionary data to create.\n * @returns The created dictionary.\n */\nexport const createDictionary = async (\n dictionary: DictionaryData\n): Promise<DictionaryDocument> => {\n const errors = await validateDictionary(dictionary);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n errors,\n });\n }\n\n return await DictionaryModel.create(dictionary);\n};\n\ntype GetExistingDictionaryResult = {\n existingDictionariesKey: string[];\n newDictionariesKey: string[];\n};\n\n/**\n * Gets the existing dictionaries from the provided list of keys.\n * @param dictionariesKeys - List of dictionary keys to check.\n * @param projectId - The ID of the project to check the dictionaries against.\n * @returns The existing dictionaries and the new dictionaries.\n */\nexport const getExistingDictionaryKey = async (\n dictionariesKeys: string[],\n projectId: string | ObjectId\n): Promise<GetExistingDictionaryResult> => {\n // Fetch dictionaries from the database where the key is in the provided list\n const existingDictionaries = await DictionaryModel.find({\n key: { $in: dictionariesKeys },\n projectIds: projectId,\n });\n\n // Map existing dictionaries to a LocalDictionary object\n const existingDictionariesKey: string[] = [];\n const newDictionariesKey: string[] = [];\n\n for (const key of dictionariesKeys) {\n const isDictionaryExist = existingDictionaries.some(\n (dictionary) => dictionary.key === key\n );\n\n if (isDictionaryExist) {\n existingDictionariesKey.push(key);\n } else {\n newDictionariesKey.push(key);\n }\n }\n\n return { existingDictionariesKey, newDictionariesKey };\n};\n\n/**\n * Updates an existing dictionary in the database by its ID.\n * @param dictionaryId - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryById = async (\n dictionaryId: string | ObjectId,\n dictionary: Partial<Dictionary>\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryId,\n errors,\n });\n }\n\n const result = await DictionaryModel.updateOne(\n { _id: dictionaryId },\n dictionaryToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryId });\n }\n\n const updatedDictionary = await getDictionaryById(dictionaryId);\n\n return updatedDictionary;\n};\n\n/**\n * Updates an existing dictionary in the database by its key.\n * @param dictionaryKey - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryByKey = async (\n dictionaryKey: string,\n dictionary: Partial<Dictionary>,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryKey,\n projectId,\n errors,\n });\n }\n\n const result = await DictionaryModel.updateOne(\n { key: dictionaryKey, projectIds: projectId },\n dictionaryToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryKey });\n }\n\n const updatedDictionary = await getDictionaryByKey(dictionaryKey, projectId);\n\n return updatedDictionary;\n};\n\n/**\n * Deletes a dictionary from the database by its ID.\n * @param dictionaryId - The ID of the dictionary to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteDictionaryById = async (\n dictionaryId: string\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findByIdAndDelete(dictionaryId);\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary;\n};\n\nexport const incrementVersion = (dictionary: Dictionary): string => {\n const VERSION_PREFIX = 'v';\n const availableVersions = dictionary.availableVersions ?? [];\n\n // Get the current version from the version list, default to 'v1' if not present\n const currentVersion =\n availableVersions.length > 0\n ? availableVersions[availableVersions.length - 1]\n : 'v1';\n\n // Function to extract the numeric part of the version\n const getVersionNumber = (version: string): number => {\n const match = version.match(/^v(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid version format: ${version}`);\n }\n return parseInt(match[1], 10);\n };\n\n // Start with the next version number\n let newNumber = getVersionNumber(currentVersion) + 1;\n let newVersion = `${VERSION_PREFIX}${newNumber}`;\n\n // Loop until a unique version is found\n while (availableVersions.includes(newVersion)) {\n newNumber += 1;\n newVersion = `${VERSION_PREFIX}${newNumber}`;\n }\n\n return newVersion;\n};\n"],"mappings":"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","names":[]}
@@ -1,5 +1,7 @@
1
1
  import { ProjectModel } from './../models/project.model.mjs';
2
+ import { ensureMongoDocumentToObject } from './../utils/ensureMongoDocumentToObject.mjs';
2
3
  import { GenericError } from './../utils/errors/index.mjs';
4
+ import { removeObjectKeys } from './../utils/removeObjectKeys.mjs';
3
5
  import {
4
6
  validateProject
5
7
  } from './../utils/validation/validateProject.mjs';
@@ -29,10 +31,13 @@ const createProject = async (project) => {
29
31
  return await ProjectModel.create(project);
30
32
  };
31
33
  const updateProjectById = async (projectId, project) => {
32
- if (project.oAuth2Access) {
33
- delete project.oAuth2Access;
34
- }
35
- const updatedKeys = Object.keys(project);
34
+ const projectObject = ensureMongoDocumentToObject(project);
35
+ const projectToUpdate = removeObjectKeys(projectObject, [
36
+ "_id",
37
+ "oAuth2Access",
38
+ "organizationId"
39
+ ]);
40
+ const updatedKeys = Object.keys(projectToUpdate);
36
41
  const errors = validateProject(project, updatedKeys);
37
42
  if (Object.keys(errors).length > 0) {
38
43
  throw new GenericError("PROJECT_INVALID_FIELDS", {
@@ -40,7 +45,10 @@ const updateProjectById = async (projectId, project) => {
40
45
  errors
41
46
  });
42
47
  }
43
- const result = await ProjectModel.updateOne({ _id: projectId }, project);
48
+ const result = await ProjectModel.updateOne(
49
+ { _id: projectId },
50
+ projectToUpdate
51
+ );
44
52
  if (result.matchedCount === 0) {
45
53
  throw new GenericError("PROJECT_UPDATE_FAILED", { projectId });
46
54
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/project.service.ts"],"sourcesContent":["import { ProjectModel } from '@models/project.model';\nimport { GenericError } from '@utils/errors';\nimport type { ProjectFilters } from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport {\n type ProjectFields,\n validateProject,\n} from '@utils/validation/validateProject';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Project,\n ProjectData,\n ProjectDocument,\n} from '@/types/project.types';\n\n/**\n * Finds projects based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of projects matching the filters.\n */\nexport const findProjects = async (\n filters: ProjectFilters,\n skip = 0,\n limit = 100\n): Promise<ProjectDocument[]> =>\n await ProjectModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a project by its ID.\n * @param projectId - The ID of the project to find.\n * @returns The project matching the ID.\n */\nexport const getProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findById(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n\n/**\n * Counts the total number of projects that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of projects.\n */\nexport const countProjects = async (\n filters: ProjectFilters\n): Promise<number> => {\n const result = await ProjectModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('PROJECT_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new project in the database.\n * @param project - The project data to create.\n * @returns The created project.\n */\nexport const createProject = async (\n project: ProjectData\n): Promise<ProjectDocument> => {\n if ((project as Partial<Project>).oAuth2Access) {\n delete (project as Partial<Project>).oAuth2Access;\n }\n\n const errors = await validateProject(project, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', { errors });\n }\n\n return await ProjectModel.create(project);\n};\n\n/**\n * Updates an existing project in the database by its ID.\n * @param projectId - The ID of the project to update.\n * @param project - The updated project data.\n * @returns The updated project.\n */\nexport const updateProjectById = async (\n projectId: string | ObjectId,\n project: Partial<Project>\n): Promise<ProjectDocument> => {\n if (project.oAuth2Access) {\n delete project.oAuth2Access;\n }\n\n const updatedKeys = Object.keys(project) as ProjectFields;\n\n const errors = validateProject(project, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', {\n projectId,\n errors,\n });\n }\n\n const result = await ProjectModel.updateOne({ _id: projectId }, project);\n\n if (result.matchedCount === 0) {\n throw new GenericError('PROJECT_UPDATE_FAILED', { projectId });\n }\n\n return await getProjectById(projectId);\n};\n\n/**\n * Deletes a project from the database by its ID.\n * @param projectId - The ID of the project to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findByIdAndDelete(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n"],"mappings":"AAAA,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAE7B;AAAA,EAEE;AAAA,OACK;AAeA,MAAM,eAAe,OAC1B,SACA,OAAO,GACP,QAAQ,QAER,MAAM,aAAa,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAOlD,MAAM,iBAAiB,OAC5B,cAC6B;AAC7B,QAAM,UAAU,MAAM,aAAa,SAAS,SAAS;AAErD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,aAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YACoB;AACpB,QAAM,SAAS,MAAM,aAAa,eAAe,OAAO;AAExD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,aAAa,wBAAwB,EAAE,QAAQ,CAAC;AAAA,EAC5D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YAC6B;AAC7B,MAAK,QAA6B,cAAc;AAC9C,WAAQ,QAA6B;AAAA,EACvC;AAEA,QAAM,SAAS,MAAM,gBAAgB,SAAS,CAAC,MAAM,CAAC;AAEtD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,0BAA0B,EAAE,OAAO,CAAC;AAAA,EAC7D;AAEA,SAAO,MAAM,aAAa,OAAO,OAAO;AAC1C;AAQO,MAAM,oBAAoB,OAC/B,WACA,YAC6B;AAC7B,MAAI,QAAQ,cAAc;AACxB,WAAO,QAAQ;AAAA,EACjB;AAEA,QAAM,cAAc,OAAO,KAAK,OAAO;AAEvC,QAAM,SAAS,gBAAgB,SAAS,WAAW;AAEnD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,aAAa,UAAU,EAAE,KAAK,UAAU,GAAG,OAAO;AAEvE,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,aAAa,yBAAyB,EAAE,UAAU,CAAC;AAAA,EAC/D;AAEA,SAAO,MAAM,eAAe,SAAS;AACvC;AAOO,MAAM,oBAAoB,OAC/B,cAC6B;AAC7B,QAAM,UAAU,MAAM,aAAa,kBAAkB,SAAS;AAE9D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,aAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/services/project.service.ts"],"sourcesContent":["import { ProjectModel } from '@models/project.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { ProjectFilters } from '@utils/filtersAndPagination/getProjectFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type ProjectFields,\n validateProject,\n} from '@utils/validation/validateProject';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Project,\n ProjectData,\n ProjectDocument,\n} from '@/types/project.types';\n\n/**\n * Finds projects based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of projects matching the filters.\n */\nexport const findProjects = async (\n filters: ProjectFilters,\n skip = 0,\n limit = 100\n): Promise<ProjectDocument[]> =>\n await ProjectModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a project by its ID.\n * @param projectId - The ID of the project to find.\n * @returns The project matching the ID.\n */\nexport const getProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findById(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n\n/**\n * Counts the total number of projects that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of projects.\n */\nexport const countProjects = async (\n filters: ProjectFilters\n): Promise<number> => {\n const result = await ProjectModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('PROJECT_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new project in the database.\n * @param project - The project data to create.\n * @returns The created project.\n */\nexport const createProject = async (\n project: ProjectData\n): Promise<ProjectDocument> => {\n if ((project as Partial<Project>).oAuth2Access) {\n delete (project as Partial<Project>).oAuth2Access;\n }\n\n const errors = await validateProject(project, ['name']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', { errors });\n }\n\n return await ProjectModel.create(project);\n};\n\n/**\n * Updates an existing project in the database by its ID.\n * @param projectId - The ID of the project to update.\n * @param project - The updated project data.\n * @returns The updated project.\n */\nexport const updateProjectById = async (\n projectId: string | ObjectId,\n project: Partial<Project>\n): Promise<ProjectDocument> => {\n const projectObject = ensureMongoDocumentToObject(project);\n const projectToUpdate = removeObjectKeys(projectObject, [\n '_id',\n 'oAuth2Access',\n 'organizationId',\n ]);\n\n const updatedKeys = Object.keys(projectToUpdate) as ProjectFields;\n\n const errors = validateProject(project, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('PROJECT_INVALID_FIELDS', {\n projectId,\n errors,\n });\n }\n\n const result = await ProjectModel.updateOne(\n { _id: projectId },\n projectToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('PROJECT_UPDATE_FAILED', { projectId });\n }\n\n return await getProjectById(projectId);\n};\n\n/**\n * Deletes a project from the database by its ID.\n * @param projectId - The ID of the project to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteProjectById = async (\n projectId: string | ObjectId\n): Promise<ProjectDocument> => {\n const project = await ProjectModel.findByIdAndDelete(projectId);\n\n if (!project) {\n throw new GenericError('PROJECT_NOT_DEFINED', { projectId });\n }\n\n return project;\n};\n"],"mappings":"AAAA,SAAS,oBAAoB;AAC7B,SAAS,mCAAmC;AAC5C,SAAS,oBAAoB;AAE7B,SAAS,wBAAwB;AACjC;AAAA,EAEE;AAAA,OACK;AAeA,MAAM,eAAe,OAC1B,SACA,OAAO,GACP,QAAQ,QAER,MAAM,aAAa,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAOlD,MAAM,iBAAiB,OAC5B,cAC6B;AAC7B,QAAM,UAAU,MAAM,aAAa,SAAS,SAAS;AAErD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,aAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YACoB;AACpB,QAAM,SAAS,MAAM,aAAa,eAAe,OAAO;AAExD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,aAAa,wBAAwB,EAAE,QAAQ,CAAC;AAAA,EAC5D;AAEA,SAAO;AACT;AAOO,MAAM,gBAAgB,OAC3B,YAC6B;AAC7B,MAAK,QAA6B,cAAc;AAC9C,WAAQ,QAA6B;AAAA,EACvC;AAEA,QAAM,SAAS,MAAM,gBAAgB,SAAS,CAAC,MAAM,CAAC;AAEtD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,0BAA0B,EAAE,OAAO,CAAC;AAAA,EAC7D;AAEA,SAAO,MAAM,aAAa,OAAO,OAAO;AAC1C;AAQO,MAAM,oBAAoB,OAC/B,WACA,YAC6B;AAC7B,QAAM,gBAAgB,4BAA4B,OAAO;AACzD,QAAM,kBAAkB,iBAAiB,eAAe;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,cAAc,OAAO,KAAK,eAAe;AAE/C,QAAM,SAAS,gBAAgB,SAAS,WAAW;AAEnD,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,0BAA0B;AAAA,MAC/C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,aAAa;AAAA,IAChC,EAAE,KAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,aAAa,yBAAyB,EAAE,UAAU,CAAC;AAAA,EAC/D;AAEA,SAAO,MAAM,eAAe,SAAS;AACvC;AAOO,MAAM,oBAAoB,OAC/B,cAC6B;AAC7B,QAAM,UAAU,MAAM,aAAa,kBAAkB,SAAS;AAE9D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,aAAa,uBAAuB,EAAE,UAAU,CAAC;AAAA,EAC7D;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,61 @@
1
+ import { TagModel } from './../models/tag.model.mjs';
2
+ import { GenericError } from './../utils/errors/index.mjs';
3
+ import { validateTag } from './../utils/validation/validateTag.mjs';
4
+ const findTags = async (filters, skip = 0, limit = 100) => await TagModel.find(filters).skip(skip).limit(limit);
5
+ const getTagById = async (tagId) => {
6
+ const tag = await TagModel.findById(tagId);
7
+ if (!tag) {
8
+ throw new GenericError("TAG_NOT_FOUND", { tagId });
9
+ }
10
+ return tag;
11
+ };
12
+ const getTagsByKeys = async (keys, organizationId) => {
13
+ const tags = await TagModel.find({ key: { $in: keys }, organizationId });
14
+ return tags;
15
+ };
16
+ const countTags = async (filters) => {
17
+ const result = await TagModel.countDocuments(filters);
18
+ if (typeof result === "undefined") {
19
+ throw new GenericError("TAG_COUNT_FAILED", { filters });
20
+ }
21
+ return result;
22
+ };
23
+ const createTag = async (tag) => {
24
+ const errors = await validateTag(tag, ["key"]);
25
+ if (Object.keys(errors).length > 0) {
26
+ throw new GenericError("TAG_INVALID_FIELDS", { errors });
27
+ }
28
+ return await TagModel.create(tag);
29
+ };
30
+ const updateTagById = async (tagId, tag) => {
31
+ const updatedKeys = Object.keys(tag);
32
+ const errors = validateTag(tag, updatedKeys);
33
+ if (Object.keys(errors).length > 0) {
34
+ throw new GenericError("TAG_INVALID_FIELDS", {
35
+ tagId,
36
+ errors
37
+ });
38
+ }
39
+ const result = await TagModel.updateOne({ _id: tagId }, tag);
40
+ if (result.matchedCount === 0) {
41
+ throw new GenericError("TAG_UPDATE_FAILED", { tagId });
42
+ }
43
+ return await getTagById(tagId);
44
+ };
45
+ const deleteTagById = async (tagId) => {
46
+ const tag = await TagModel.findByIdAndDelete(tagId);
47
+ if (!tag) {
48
+ throw new GenericError("TAG_NOT_FOUND", { tagId });
49
+ }
50
+ return tag;
51
+ };
52
+ export {
53
+ countTags,
54
+ createTag,
55
+ deleteTagById,
56
+ findTags,
57
+ getTagById,
58
+ getTagsByKeys,
59
+ updateTagById
60
+ };
61
+ //# sourceMappingURL=tag.service.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/services/tag.service.ts"],"sourcesContent":["import { TagModel } from '@models/tag.model';\nimport { GenericError } from '@utils/errors';\nimport type { TagFilters } from '@utils/filtersAndPagination/getTagFiltersAndPagination';\nimport { type TagFields, validateTag } from '@utils/validation/validateTag';\nimport type { ObjectId } from 'mongoose';\nimport { Organization } from '@/export';\nimport type { Tag, TagData, TagDocument } from '@/types/tag.types';\n\n/**\n * Finds tags based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of tags matching the filters.\n */\nexport const findTags = async (\n filters: TagFilters,\n skip = 0,\n limit = 100\n): Promise<TagDocument[]> =>\n await TagModel.find(filters).skip(skip).limit(limit);\n\n/**\n * Finds a tag by its ID.\n * @param tagId - The ID of the tag to find.\n * @returns The tag matching the ID.\n */\nexport const getTagById = async (\n tagId: string | ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findById(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n\nexport const getTagsByKeys = async (\n keys: string[],\n organizationId: string | Organization['_id']\n): Promise<TagDocument[]> => {\n const tags = await TagModel.find({ key: { $in: keys }, organizationId });\n\n return tags;\n};\n\n/**\n * Counts the total number of tags that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of tags.\n */\nexport const countTags = async (filters: TagFilters): Promise<number> => {\n const result = await TagModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('TAG_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new tag in the database.\n * @param tag - The tag data to create.\n * @returns The created tag.\n */\nexport const createTag = async (tag: TagData): Promise<TagDocument> => {\n const errors = await validateTag(tag, ['key']);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', { errors });\n }\n\n return await TagModel.create(tag);\n};\n\n/**\n * Updates an existing tag in the database by its ID.\n * @param tagId - The ID of the tag to update.\n * @param tag - The updated tag data.\n * @returns The updated tag.\n */\nexport const updateTagById = async (\n tagId: string | ObjectId,\n tag: Partial<Tag>\n): Promise<TagDocument> => {\n const updatedKeys = Object.keys(tag) as TagFields;\n\n const errors = validateTag(tag, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('TAG_INVALID_FIELDS', {\n tagId,\n errors,\n });\n }\n\n const result = await TagModel.updateOne({ _id: tagId }, tag);\n\n if (result.matchedCount === 0) {\n throw new GenericError('TAG_UPDATE_FAILED', { tagId });\n }\n\n return await getTagById(tagId);\n};\n\n/**\n * Deletes a tag from the database by its ID.\n * @param tagId - The ID of the tag to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteTagById = async (\n tagId: string | ObjectId\n): Promise<TagDocument> => {\n const tag = await TagModel.findByIdAndDelete(tagId);\n\n if (!tag) {\n throw new GenericError('TAG_NOT_FOUND', { tagId });\n }\n\n return tag;\n};\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAyB,mBAAmB;AAYrC,MAAM,WAAW,OACtB,SACA,OAAO,GACP,QAAQ,QAER,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAO9C,MAAM,aAAa,OACxB,UACyB;AACzB,QAAM,MAAM,MAAM,SAAS,SAAS,KAAK;AAEzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,aAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;AAEO,MAAM,gBAAgB,OAC3B,MACA,mBAC2B;AAC3B,QAAM,OAAO,MAAM,SAAS,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,GAAG,eAAe,CAAC;AAEvE,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,YAAyC;AACvE,QAAM,SAAS,MAAM,SAAS,eAAe,OAAO;AAEpD,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,IAAI,aAAa,oBAAoB,EAAE,QAAQ,CAAC;AAAA,EACxD;AAEA,SAAO;AACT;AAOO,MAAM,YAAY,OAAO,QAAuC;AACrE,QAAM,SAAS,MAAM,YAAY,KAAK,CAAC,KAAK,CAAC;AAE7C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,sBAAsB,EAAE,OAAO,CAAC;AAAA,EACzD;AAEA,SAAO,MAAM,SAAS,OAAO,GAAG;AAClC;AAQO,MAAM,gBAAgB,OAC3B,OACA,QACyB;AACzB,QAAM,cAAc,OAAO,KAAK,GAAG;AAEnC,QAAM,SAAS,YAAY,KAAK,WAAW;AAE3C,MAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC,UAAM,IAAI,aAAa,sBAAsB;AAAA,MAC3C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,SAAS,UAAU,EAAE,KAAK,MAAM,GAAG,GAAG;AAE3D,MAAI,OAAO,iBAAiB,GAAG;AAC7B,UAAM,IAAI,aAAa,qBAAqB,EAAE,MAAM,CAAC;AAAA,EACvD;AAEA,SAAO,MAAM,WAAW,KAAK;AAC/B;AAOO,MAAM,gBAAgB,OAC3B,UACyB;AACzB,QAAM,MAAM,MAAM,SAAS,kBAAkB,KAAK;AAElD,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,aAAa,iBAAiB,EAAE,MAAM,CAAC;AAAA,EACnD;AAEA,SAAO;AACT;","names":[]}