@intlayer/backend 5.1.7 → 5.1.8

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 (53) hide show
  1. package/dist/cjs/controllers/dictionary.controller.cjs +5 -7
  2. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  3. package/dist/cjs/controllers/{event-listener.cjs → eventListener.controller.cjs} +27 -8
  4. package/dist/cjs/controllers/eventListener.controller.cjs.map +1 -0
  5. package/dist/cjs/export.cjs.map +1 -1
  6. package/dist/cjs/index.cjs +2 -2
  7. package/dist/cjs/index.cjs.map +1 -1
  8. package/dist/cjs/routes/{event-listener.routes.cjs → eventListener.routes.cjs} +6 -6
  9. package/dist/cjs/routes/eventListener.routes.cjs.map +1 -0
  10. package/dist/cjs/services/dictionary.service.cjs +11 -30
  11. package/dist/cjs/services/dictionary.service.cjs.map +1 -1
  12. package/dist/cjs/types/dictionary.types.cjs.map +1 -1
  13. package/dist/cjs/utils/AI/askDocQuestion/embeddings.json +4298 -612
  14. package/dist/cjs/utils/errors/errorCodes.cjs +18 -1
  15. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  16. package/dist/esm/controllers/dictionary.controller.mjs +5 -7
  17. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  18. package/dist/esm/controllers/{event-listener.mjs → eventListener.controller.mjs} +24 -5
  19. package/dist/esm/controllers/eventListener.controller.mjs.map +1 -0
  20. package/dist/esm/export.mjs.map +1 -1
  21. package/dist/esm/index.mjs +1 -1
  22. package/dist/esm/index.mjs.map +1 -1
  23. package/dist/esm/routes/{event-listener.routes.mjs → eventListener.routes.mjs} +2 -2
  24. package/dist/esm/routes/eventListener.routes.mjs.map +1 -0
  25. package/dist/esm/services/dictionary.service.mjs +11 -30
  26. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  27. package/dist/esm/utils/AI/askDocQuestion/embeddings.json +4298 -612
  28. package/dist/esm/utils/errors/errorCodes.mjs +18 -1
  29. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  30. package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
  31. package/dist/types/controllers/{event-listener.d.ts → eventListener.controller.d.ts} +8 -1
  32. package/dist/types/controllers/eventListener.controller.d.ts.map +1 -0
  33. package/dist/types/export.d.ts +1 -0
  34. package/dist/types/export.d.ts.map +1 -1
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/types/models/dictionary.model.d.ts +0 -1
  37. package/dist/types/models/dictionary.model.d.ts.map +1 -1
  38. package/dist/types/routes/{event-listener.routes.d.ts → eventListener.routes.d.ts} +1 -1
  39. package/dist/types/routes/eventListener.routes.d.ts.map +1 -0
  40. package/dist/types/schemas/dictionary.schema.d.ts +0 -1
  41. package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
  42. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  43. package/dist/types/types/dictionary.types.d.ts +0 -1
  44. package/dist/types/types/dictionary.types.d.ts.map +1 -1
  45. package/dist/types/utils/errors/errorCodes.d.ts +18 -1
  46. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  47. package/package.json +8 -8
  48. package/dist/cjs/controllers/event-listener.cjs.map +0 -1
  49. package/dist/cjs/routes/event-listener.routes.cjs.map +0 -1
  50. package/dist/esm/controllers/event-listener.mjs.map +0 -1
  51. package/dist/esm/routes/event-listener.routes.mjs.map +0 -1
  52. package/dist/types/controllers/event-listener.d.ts.map +0 -1
  53. package/dist/types/routes/event-listener.routes.d.ts.map +0 -1
@@ -45,7 +45,7 @@ var import_getDictionaryFiltersAndPagination = require('./../utils/filtersAndPag
45
45
  var import_dictionary = require('./../utils/mapper/dictionary.cjs');
46
46
  var import_responseData = require('./../utils/responseData.cjs');
47
47
  var import_express_intlayer = require("express-intlayer");
48
- var eventListener = __toESM(require('./../controllers/event-listener.cjs'), 1);
48
+ var eventListener = __toESM(require('./../controllers/eventListener.controller.cjs'), 1);
49
49
  const getDictionaries = async (req, res, _next) => {
50
50
  const { user, project, dictionaryRights } = res.locals;
51
51
  const { filters, pageSize, skip, page, getNumberOfPages } = (0, import_getDictionaryFiltersAndPagination.getDictionaryFiltersAndPagination)(req);
@@ -294,12 +294,10 @@ const pushDictionaries = async (req, res, _next) => {
294
294
  let newContent = existingDictionaryDB.content;
295
295
  if (!isSameContent) {
296
296
  const newContentVersion = dictionaryService.incrementVersion(existingDictionaryDB);
297
- newContent = {
298
- ...newContent,
299
- [newContentVersion]: {
300
- content: dictionaryDataEl.content
301
- }
302
- };
297
+ existingDictionaryDB.content.set(newContentVersion, {
298
+ content: dictionaryDataEl.content ?? {}
299
+ });
300
+ newContent = existingDictionaryDB.content;
303
301
  }
304
302
  const dictionary = {
305
303
  ...(0, import_ensureMongoDocumentToObject.ensureMongoDocumentToObject)(existingDictionaryDB),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/controllers/dictionary.controller.ts"],"sourcesContent":["import type {\n ContentNode,\n Dictionary as LocalDictionary,\n} from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport * as dictionaryService from '@services/dictionary.service';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport {\n type DictionaryFiltersParams,\n getDictionaryFiltersAndPagination,\n} from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { mapDictionaryToAPI } from '@utils/mapper/dictionary';\nimport {\n formatPaginatedResponse,\n type ResponseData,\n type PaginatedResponse,\n formatResponse,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport { t } from 'express-intlayer';\nimport * as eventListener from '@/controllers/event-listener';\nimport type {\n Dictionary,\n DictionaryAPI,\n DictionaryCreationData,\n DictionaryData,\n VersionedContent,\n} from '@/types/dictionary.types';\n\nexport type GetDictionariesParams =\n FiltersAndPagination<DictionaryFiltersParams>;\nexport type GetDictionariesResult = PaginatedResponse<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaries = async (\n req: Request<GetDictionariesParams>,\n res: ResponseWithInformation<GetDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, dictionaryRights } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getDictionaryFiltersAndPagination(req);\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.findDictionaries(\n filters,\n skip,\n pageSize\n );\n const totalItems = await dictionaryService.countDictionaries(filters);\n\n const dictionariesAPI = dictionaries.map((el) =>\n mapDictionaryToAPI(el, project._id)\n );\n\n const responseData = formatPaginatedResponse<DictionaryAPI>({\n data: dictionariesAPI,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionariesKeysResult = ResponseData<string[]>;\n\n/**\n * Retrieves a list of dictionaries keys based on filters and pagination.\n */\nexport const getDictionariesKeys = async (\n _req: Request,\n res: ResponseWithInformation<GetDictionariesKeysResult>,\n _next: NextFunction\n) => {\n const { project, dictionaryRights } = res.locals;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionariesKeys = await dictionaryService.getDictionariesKeys(\n project._id\n );\n\n const responseData = formatResponse<string[]>({\n data: dictionariesKeys,\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 GetDictionaryParams = { dictionaryKey: string };\nexport type GetDictionaryQuery = { version?: string };\nexport type GetDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaryByKey = async (\n req: Request<GetDictionaryParams, any, any, GetDictionaryQuery>,\n res: ResponseWithInformation<GetDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const { dictionaryKey } = req.params;\n const version = req.query.version;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionary = await dictionaryService.getDictionaryByKey(\n dictionaryKey,\n project._id\n );\n\n if (!dictionary.projectIds.map(String).includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const apiResult = mapDictionaryToAPI(dictionary, project._id, version);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\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 AddDictionaryBody = { dictionary: DictionaryCreationData };\nexport type AddDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const addDictionary = async (\n req: Request<any, any, AddDictionaryBody>,\n res: ResponseWithInformation<AddDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body.dictionary;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n const dictionary: DictionaryData = {\n key: dictionaryData.key,\n title: dictionaryData.title,\n description: dictionaryData.description,\n content: new Map([\n ['v1', { content: dictionaryData.content ?? ({} as ContentNode) }],\n ]),\n creatorId: user._id,\n filePath: {\n [String(project._id)]: dictionaryData.filePath ?? '',\n },\n projectIds: dictionaryData.projectIds ?? [String(project._id)],\n };\n\n try {\n const newDictionary = await dictionaryService.createDictionary(dictionary);\n\n const apiResult = mapDictionaryToAPI(newDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary created successfully',\n fr: 'Dictionnaire créé avec succès',\n es: 'Diccionario creado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been created successfully',\n fr: 'Votre dictionnaire a été créé avec succès',\n es: 'Su diccionario ha sido creado con éxito',\n }),\n data: apiResult,\n });\n\n res.json(responseData);\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: mapDictionaryToAPI(newDictionary, project._id),\n status: 'ADDED',\n },\n ]);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushDictionariesBody = {\n dictionaries: LocalDictionary[];\n};\ntype PushDictionariesResultData = {\n newDictionaries: string[];\n updatedDictionaries: string[];\n error: { dictionaryId: string; message: string }[];\n};\nexport type PushDictionariesResult = ResponseData<PushDictionariesResultData>;\n\n/**\n * Check each dictionaries, add the new ones and update the existing ones.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response containing the created dictionary.\n */\nexport const pushDictionaries = async (\n req: Request<any, any, PushDictionariesBody>,\n res: ResponseWithInformation<PushDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body.dictionaries;\n const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);\n\n if (\n typeof dictionaryData === 'object' &&\n Array.isArray(dictionaryData) &&\n dictionaryData.length === 0\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARIES_NOT_PROVIDED');\n return;\n } else if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const { existingDictionariesKey, newDictionariesKey } =\n await dictionaryService.getExistingDictionaryKey(\n dictionariesKeys,\n project._id\n );\n\n const existingDictionaries = dictionaryData.filter((dictionary) =>\n existingDictionariesKey.includes(dictionary.key)\n );\n const newDictionaries = dictionaryData.filter((dictionary) =>\n newDictionariesKey.includes(dictionary.key)\n );\n\n const newDictionariesResult: DictionaryAPI[] = [];\n const updatedDictionariesResult: DictionaryAPI[] = [];\n const errorResult: PushDictionariesResultData['error'] = [];\n\n for (const dictionaryDataEl of newDictionaries) {\n const dictionary: DictionaryData = {\n title: dictionaryDataEl.title,\n description: dictionaryDataEl.description,\n projectIds: [String(project._id)],\n creatorId: user._id,\n content: new Map([\n ['v1', { content: dictionaryDataEl.content ?? ({} as ContentNode) }],\n ]),\n filePath: {\n [String(project._id)]: dictionaryDataEl.filePath ?? '',\n },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary =\n await dictionaryService.createDictionary(dictionary);\n newDictionariesResult.push(\n mapDictionaryToAPI(newDictionary, project._id)\n );\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n }\n\n if (existingDictionariesKey.length >= 0) {\n const existingDictionariesDB =\n await dictionaryService.getDictionariesByKeys(\n existingDictionariesKey,\n project._id\n );\n\n for (const dictionaryDataEl of existingDictionaries) {\n const existingDictionaryDB = existingDictionariesDB.find(\n (dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key\n )!;\n\n const versionList = [...(existingDictionaryDB.content.keys() ?? [])];\n const lastVersion = versionList[versionList.length - 1];\n\n const lastContent =\n (existingDictionaryDB.content.get(lastVersion)\n ?.content as DictionaryAPI['content']) ?? null;\n\n const isSameContent =\n JSON.stringify(lastContent) ===\n JSON.stringify(dictionaryDataEl.content);\n\n let newContent: VersionedContent = existingDictionaryDB.content;\n\n if (!isSameContent) {\n const newContentVersion =\n dictionaryService.incrementVersion(existingDictionaryDB);\n\n newContent = {\n ...newContent,\n [newContentVersion]: {\n content: dictionaryDataEl.content,\n },\n };\n }\n\n const dictionary: DictionaryData = {\n ...ensureMongoDocumentToObject(existingDictionaryDB),\n ...dictionaryDataEl,\n content: newContent,\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: {\n [String(project._id)]: dictionaryDataEl.filePath ?? '',\n },\n key: dictionaryDataEl.key,\n };\n\n try {\n const updatedDictionary =\n await dictionaryService.updateDictionaryByKey(\n dictionaryDataEl.key,\n dictionary,\n project._id\n );\n updatedDictionariesResult.push(\n mapDictionaryToAPI(updatedDictionary, project._id)\n );\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n }\n }\n\n const result: PushDictionariesResultData = {\n newDictionaries: newDictionariesResult.map(\n (dictionary) => dictionary.key\n ),\n updatedDictionaries: updatedDictionariesResult.map(\n (dictionary) => dictionary.key\n ),\n error: errorResult,\n };\n\n const responseData = formatResponse<PushDictionariesResultData>({\n message: t({\n en: 'Dictionaries updated successfully',\n fr: 'Dictionnaires mis à jour avec succès',\n es: 'Diccionarios actualizados con éxito',\n }),\n description: t({\n en: 'Your dictionaries have been updated successfully',\n fr: 'Vos dictionnaires ont été mis à jour avec succès',\n es: 'Sus diccionarios han sido actualizados con éxito',\n }),\n data: result,\n });\n\n eventListener.sendDictionaryUpdate([\n ...newDictionariesResult.map(\n (dictionary) =>\n ({\n dictionary,\n status: 'ADDED',\n }) as eventListener.SendDictionaryUpdateArg\n ),\n ...updatedDictionariesResult.map(\n (dictionary) =>\n ({\n dictionary,\n status: 'UPDATED',\n }) as eventListener.SendDictionaryUpdateArg\n ),\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 UpdateDictionaryParam = { dictionaryId: string };\nexport type UpdateDictionaryBody = Partial<Dictionary>;\nexport type UpdateDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Updates an existing dictionary in the database.\n */\nexport const updateDictionary = async (\n req: Request<UpdateDictionaryParam, any, UpdateDictionaryBody>,\n res: ResponseWithInformation<UpdateDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { dictionaryId } = req.params;\n const { project, dictionaryRights } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (typeof dictionaryId === 'undefined') {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n try {\n const updatedDictionary = await dictionaryService.updateDictionaryById(\n dictionaryId,\n dictionaryData\n );\n\n const apiResult = mapDictionaryToAPI(updatedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary updated successfully',\n fr: 'Dictionnaire mis à jour avec succès',\n es: 'Diccionario actualizado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been updated successfully',\n fr: 'Votre dictionnaire a été mis à jour avec succès',\n es: 'Su diccionario ha sido actualizado con éxito',\n }),\n data: apiResult,\n });\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: apiResult,\n status: 'UPDATED',\n },\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 DeleteDictionaryParam = { dictionaryId: string };\nexport type DeleteDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Deletes a dictionary from the database by its ID.\n */\nexport const deleteDictionary = async (\n req: Request<DeleteDictionaryParam>,\n res: ResponseWithInformation<DeleteDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, dictionaryRights } = res.locals;\n const { dictionaryId } = req.params as Partial<DeleteDictionaryParam>;\n\n if (!dictionaryId) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const dictionaryToDelete =\n await dictionaryService.getDictionaryById(dictionaryId);\n\n if (!dictionaryToDelete.projectIds.includes(project._id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const deletedDictionary =\n await dictionaryService.deleteDictionaryById(dictionaryId);\n\n if (!deletedDictionary) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_NOT_FOUND', {\n dictionaryId,\n });\n return;\n }\n\n logger.info(`Dictionary deleted: ${String(deletedDictionary._id)}`);\n\n const apiResult = mapDictionaryToAPI(deletedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary deleted successfully',\n fr: 'Dictionnaire supprimé avec succès',\n es: 'Diccionario eliminado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been deleted successfully',\n fr: 'Votre dictionnaire a été supprimé avec succès',\n es: 'Su diccionario ha sido eliminado con éxito',\n }),\n data: apiResult,\n });\n\n res.json(responseData);\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: apiResult,\n status: 'DELETED',\n },\n ]);\n\n return;\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/dictionary.controller.ts"],"sourcesContent":["import type {\n ContentNode,\n Dictionary as LocalDictionary,\n} from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport * as dictionaryService from '@services/dictionary.service';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport {\n type DictionaryFiltersParams,\n getDictionaryFiltersAndPagination,\n} from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport type { FiltersAndPagination } from '@utils/filtersAndPagination/getFiltersAndPaginationFromBody';\nimport { mapDictionaryToAPI } from '@utils/mapper/dictionary';\nimport {\n formatPaginatedResponse,\n type ResponseData,\n type PaginatedResponse,\n formatResponse,\n} from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport { t } from 'express-intlayer';\nimport * as eventListener from '@controllers/eventListener.controller';\nimport type {\n Dictionary,\n DictionaryAPI,\n DictionaryCreationData,\n DictionaryData,\n VersionedContent,\n} from '@/types/dictionary.types';\n\nexport type GetDictionariesParams =\n FiltersAndPagination<DictionaryFiltersParams>;\nexport type GetDictionariesResult = PaginatedResponse<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaries = async (\n req: Request<GetDictionariesParams>,\n res: ResponseWithInformation<GetDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, dictionaryRights } = res.locals;\n const { filters, pageSize, skip, page, getNumberOfPages } =\n getDictionaryFiltersAndPagination(req);\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionaries = await dictionaryService.findDictionaries(\n filters,\n skip,\n pageSize\n );\n const totalItems = await dictionaryService.countDictionaries(filters);\n\n const dictionariesAPI = dictionaries.map((el) =>\n mapDictionaryToAPI(el, project._id)\n );\n\n const responseData = formatPaginatedResponse<DictionaryAPI>({\n data: dictionariesAPI,\n page,\n pageSize,\n totalPages: getNumberOfPages(totalItems),\n totalItems,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type GetDictionariesKeysResult = ResponseData<string[]>;\n\n/**\n * Retrieves a list of dictionaries keys based on filters and pagination.\n */\nexport const getDictionariesKeys = async (\n _req: Request,\n res: ResponseWithInformation<GetDictionariesKeysResult>,\n _next: NextFunction\n) => {\n const { project, dictionaryRights } = res.locals;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionariesKeys = await dictionaryService.getDictionariesKeys(\n project._id\n );\n\n const responseData = formatResponse<string[]>({\n data: dictionariesKeys,\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 GetDictionaryParams = { dictionaryKey: string };\nexport type GetDictionaryQuery = { version?: string };\nexport type GetDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const getDictionaryByKey = async (\n req: Request<GetDictionaryParams, any, any, GetDictionaryQuery>,\n res: ResponseWithInformation<GetDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const { dictionaryKey } = req.params;\n const version = req.query.version;\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!dictionaryRights?.read) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_READ');\n return;\n }\n\n try {\n const dictionary = await dictionaryService.getDictionaryByKey(\n dictionaryKey,\n project._id\n );\n\n if (!dictionary.projectIds.map(String).includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const apiResult = mapDictionaryToAPI(dictionary, project._id, version);\n\n const responseData = formatResponse<DictionaryAPI>({\n data: apiResult,\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 AddDictionaryBody = { dictionary: DictionaryCreationData };\nexport type AddDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Adds a new dictionary to the database.\n */\nexport const addDictionary = async (\n req: Request<any, any, AddDictionaryBody>,\n res: ResponseWithInformation<AddDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body.dictionary;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n const dictionary: DictionaryData = {\n key: dictionaryData.key,\n title: dictionaryData.title,\n description: dictionaryData.description,\n content: new Map([\n ['v1', { content: dictionaryData.content ?? ({} as ContentNode) }],\n ]),\n creatorId: user._id,\n filePath: {\n [String(project._id)]: dictionaryData.filePath ?? '',\n },\n projectIds: dictionaryData.projectIds ?? [String(project._id)],\n };\n\n try {\n const newDictionary = await dictionaryService.createDictionary(dictionary);\n\n const apiResult = mapDictionaryToAPI(newDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary created successfully',\n fr: 'Dictionnaire créé avec succès',\n es: 'Diccionario creado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been created successfully',\n fr: 'Votre dictionnaire a été créé avec succès',\n es: 'Su diccionario ha sido creado con éxito',\n }),\n data: apiResult,\n });\n\n res.json(responseData);\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: mapDictionaryToAPI(newDictionary, project._id),\n status: 'ADDED',\n },\n ]);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type PushDictionariesBody = {\n dictionaries: LocalDictionary[];\n};\ntype PushDictionariesResultData = {\n newDictionaries: string[];\n updatedDictionaries: string[];\n error: { dictionaryId: string; message: string }[];\n};\nexport type PushDictionariesResult = ResponseData<PushDictionariesResultData>;\n\n/**\n * Check each dictionaries, add the new ones and update the existing ones.\n * @param req - Express request object.\n * @param res - Express response object.\n * @returns Response containing the created dictionary.\n */\nexport const pushDictionaries = async (\n req: Request<any, any, PushDictionariesBody>,\n res: ResponseWithInformation<PushDictionariesResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, user, dictionaryRights } = res.locals;\n const dictionaryData = req.body.dictionaries;\n const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);\n\n if (\n typeof dictionaryData === 'object' &&\n Array.isArray(dictionaryData) &&\n dictionaryData.length === 0\n ) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARIES_NOT_PROVIDED');\n return;\n } else if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const { existingDictionariesKey, newDictionariesKey } =\n await dictionaryService.getExistingDictionaryKey(\n dictionariesKeys,\n project._id\n );\n\n const existingDictionaries = dictionaryData.filter((dictionary) =>\n existingDictionariesKey.includes(dictionary.key)\n );\n const newDictionaries = dictionaryData.filter((dictionary) =>\n newDictionariesKey.includes(dictionary.key)\n );\n\n const newDictionariesResult: DictionaryAPI[] = [];\n const updatedDictionariesResult: DictionaryAPI[] = [];\n const errorResult: PushDictionariesResultData['error'] = [];\n\n for (const dictionaryDataEl of newDictionaries) {\n const dictionary: DictionaryData = {\n title: dictionaryDataEl.title,\n description: dictionaryDataEl.description,\n projectIds: [String(project._id)],\n creatorId: user._id,\n content: new Map([\n ['v1', { content: dictionaryDataEl.content ?? ({} as ContentNode) }],\n ]),\n filePath: {\n [String(project._id)]: dictionaryDataEl.filePath ?? '',\n },\n key: dictionaryDataEl.key,\n };\n\n try {\n const newDictionary =\n await dictionaryService.createDictionary(dictionary);\n newDictionariesResult.push(\n mapDictionaryToAPI(newDictionary, project._id)\n );\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n }\n\n if (existingDictionariesKey.length >= 0) {\n const existingDictionariesDB =\n await dictionaryService.getDictionariesByKeys(\n existingDictionariesKey,\n project._id\n );\n\n for (const dictionaryDataEl of existingDictionaries) {\n const existingDictionaryDB = existingDictionariesDB.find(\n (dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key\n )!;\n\n const versionList = [...(existingDictionaryDB.content.keys() ?? [])];\n const lastVersion = versionList[versionList.length - 1];\n\n const lastContent =\n (existingDictionaryDB.content.get(lastVersion)\n ?.content as DictionaryAPI['content']) ?? null;\n\n const isSameContent =\n JSON.stringify(lastContent) ===\n JSON.stringify(dictionaryDataEl.content);\n\n let newContent: VersionedContent = existingDictionaryDB.content;\n\n if (!isSameContent) {\n const newContentVersion =\n dictionaryService.incrementVersion(existingDictionaryDB);\n\n existingDictionaryDB.content.set(newContentVersion, {\n content: dictionaryDataEl.content ?? ({} as ContentNode),\n });\n\n newContent = existingDictionaryDB.content;\n }\n\n const dictionary: DictionaryData = {\n ...ensureMongoDocumentToObject(existingDictionaryDB),\n ...dictionaryDataEl,\n content: newContent,\n projectIds: [String(project._id)],\n creatorId: user._id,\n filePath: {\n [String(project._id)]: dictionaryDataEl.filePath ?? '',\n },\n key: dictionaryDataEl.key,\n };\n\n try {\n const updatedDictionary =\n await dictionaryService.updateDictionaryByKey(\n dictionaryDataEl.key,\n dictionary,\n project._id\n );\n updatedDictionariesResult.push(\n mapDictionaryToAPI(updatedDictionary, project._id)\n );\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n }\n }\n\n const result: PushDictionariesResultData = {\n newDictionaries: newDictionariesResult.map(\n (dictionary) => dictionary.key\n ),\n updatedDictionaries: updatedDictionariesResult.map(\n (dictionary) => dictionary.key\n ),\n error: errorResult,\n };\n\n const responseData = formatResponse<PushDictionariesResultData>({\n message: t({\n en: 'Dictionaries updated successfully',\n fr: 'Dictionnaires mis à jour avec succès',\n es: 'Diccionarios actualizados con éxito',\n }),\n description: t({\n en: 'Your dictionaries have been updated successfully',\n fr: 'Vos dictionnaires ont été mis à jour avec succès',\n es: 'Sus diccionarios han sido actualizados con éxito',\n }),\n data: result,\n });\n\n eventListener.sendDictionaryUpdate([\n ...newDictionariesResult.map(\n (dictionary) =>\n ({\n dictionary,\n status: 'ADDED',\n }) as eventListener.SendDictionaryUpdateArg\n ),\n ...updatedDictionariesResult.map(\n (dictionary) =>\n ({\n dictionary,\n status: 'UPDATED',\n }) as eventListener.SendDictionaryUpdateArg\n ),\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 UpdateDictionaryParam = { dictionaryId: string };\nexport type UpdateDictionaryBody = Partial<Dictionary>;\nexport type UpdateDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Updates an existing dictionary in the database.\n */\nexport const updateDictionary = async (\n req: Request<UpdateDictionaryParam, any, UpdateDictionaryBody>,\n res: ResponseWithInformation<UpdateDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { dictionaryId } = req.params;\n const { project, dictionaryRights } = res.locals;\n const dictionaryData = req.body;\n\n if (!dictionaryData) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_DATA_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryData.projectIds?.includes(String(project._id))) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_PROJECT_MISMATCH');\n return;\n }\n\n if (typeof dictionaryId === 'undefined') {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!dictionaryRights?.write) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_WRITE');\n return;\n }\n\n try {\n const updatedDictionary = await dictionaryService.updateDictionaryById(\n dictionaryId,\n dictionaryData\n );\n\n const apiResult = mapDictionaryToAPI(updatedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary updated successfully',\n fr: 'Dictionnaire mis à jour avec succès',\n es: 'Diccionario actualizado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been updated successfully',\n fr: 'Votre dictionnaire a été mis à jour avec succès',\n es: 'Su diccionario ha sido actualizado con éxito',\n }),\n data: apiResult,\n });\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: apiResult,\n status: 'UPDATED',\n },\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 DeleteDictionaryParam = { dictionaryId: string };\nexport type DeleteDictionaryResult = ResponseData<DictionaryAPI>;\n\n/**\n * Deletes a dictionary from the database by its ID.\n */\nexport const deleteDictionary = async (\n req: Request<DeleteDictionaryParam>,\n res: ResponseWithInformation<DeleteDictionaryResult>,\n _next: NextFunction\n): Promise<void> => {\n const { project, dictionaryRights } = res.locals;\n const { dictionaryId } = req.params as Partial<DeleteDictionaryParam>;\n\n if (!dictionaryId) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_ID_NOT_FOUND');\n return;\n }\n\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n\n if (!dictionaryRights?.admin) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_RIGHTS_NOT_ADMIN');\n return;\n }\n\n try {\n const dictionaryToDelete =\n await dictionaryService.getDictionaryById(dictionaryId);\n\n if (!dictionaryToDelete.projectIds.includes(project._id)) {\n ErrorHandler.handleGenericErrorResponse(\n res,\n 'DICTIONARY_PROJECT_MISMATCH'\n );\n return;\n }\n\n const deletedDictionary =\n await dictionaryService.deleteDictionaryById(dictionaryId);\n\n if (!deletedDictionary) {\n ErrorHandler.handleGenericErrorResponse(res, 'DICTIONARY_NOT_FOUND', {\n dictionaryId,\n });\n return;\n }\n\n logger.info(`Dictionary deleted: ${String(deletedDictionary._id)}`);\n\n const apiResult = mapDictionaryToAPI(deletedDictionary, project._id);\n\n const responseData = formatResponse<DictionaryAPI>({\n message: t({\n en: 'Dictionary deleted successfully',\n fr: 'Dictionnaire supprimé avec succès',\n es: 'Diccionario eliminado con éxito',\n }),\n description: t({\n en: 'Your dictionary has been deleted successfully',\n fr: 'Votre dictionnaire a été supprimé avec succès',\n es: 'Su diccionario ha sido eliminado con éxito',\n }),\n data: apiResult,\n });\n\n res.json(responseData);\n\n eventListener.sendDictionaryUpdate([\n {\n dictionary: apiResult,\n status: 'DELETED',\n },\n ]);\n\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAAuB;AAEvB,wBAAmC;AACnC,yCAA4C;AAC5C,oBAA4C;AAC5C,+CAGO;AAEP,wBAAmC;AACnC,0BAKO;AAEP,8BAAkB;AAClB,oBAA+B;AAgBxB,MAAM,kBAAkB,OAC7B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,MAAM,SAAS,iBAAiB,IAAI,IAAI;AAChD,QAAM,EAAE,SAAS,UAAU,MAAM,MAAM,iBAAiB,QACtD,4EAAkC,GAAG;AAEvC,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,+BAAa,2BAA2B,KAAK,4BAA4B;AACzE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,MAAM,kBAAkB;AAAA,MAC3C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,aAAa,MAAM,kBAAkB,kBAAkB,OAAO;AAEpE,UAAM,kBAAkB,aAAa;AAAA,MAAI,CAAC,WACxC,sCAAmB,IAAI,QAAQ,GAAG;AAAA,IACpC;AAEA,UAAM,mBAAe,6CAAuC;AAAA,MAC1D,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,YAAY,iBAAiB,UAAU;AAAA,MACvC;AAAA,IACF,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAOO,MAAM,sBAAsB,OACjC,MACA,KACA,UACG;AACH,QAAM,EAAE,SAAS,iBAAiB,IAAI,IAAI;AAE1C,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,+BAAa,2BAA2B,KAAK,4BAA4B;AACzE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,mBAAmB,MAAM,kBAAkB;AAAA,MAC/C,QAAQ;AAAA,IACV;AAEA,UAAM,mBAAe,oCAAyB;AAAA,MAC5C,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AASO,MAAM,qBAAqB,OAChC,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,MAAM,iBAAiB,IAAI,IAAI;AAChD,QAAM,EAAE,cAAc,IAAI,IAAI;AAC9B,QAAM,UAAU,IAAI,MAAM;AAE1B,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,+BAAa,2BAA2B,KAAK,4BAA4B;AACzE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,aAAa,MAAM,kBAAkB;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IACV;AAEA,QAAI,CAAC,WAAW,WAAW,IAAI,MAAM,EAAE,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AACpE,iCAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,gBAAY,sCAAmB,YAAY,QAAQ,KAAK,OAAO;AAErE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAQO,MAAM,gBAAgB,OAC3B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,MAAM,iBAAiB,IAAI,IAAI;AAChD,QAAM,iBAAiB,IAAI,KAAK;AAEhC,MAAI,CAAC,gBAAgB;AACnB,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,YAAY,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC7D,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,QAAM,aAA6B;AAAA,IACjC,KAAK,eAAe;AAAA,IACpB,OAAO,eAAe;AAAA,IACtB,aAAa,eAAe;AAAA,IAC5B,SAAS,oBAAI,IAAI;AAAA,MACf,CAAC,MAAM,EAAE,SAAS,eAAe,WAAY,CAAC,EAAkB,CAAC;AAAA,IACnE,CAAC;AAAA,IACD,WAAW,KAAK;AAAA,IAChB,UAAU;AAAA,MACR,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,eAAe,YAAY;AAAA,IACpD;AAAA,IACA,YAAY,eAAe,cAAc,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC/D;AAEA,MAAI;AACF,UAAM,gBAAgB,MAAM,kBAAkB,iBAAiB,UAAU;AAEzE,UAAM,gBAAY,sCAAmB,eAAe,QAAQ,GAAG;AAE/D,UAAM,mBAAe,oCAA8B;AAAA,MACjD,aAAS,2BAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,iBAAa,2BAAE;AAAA,QACb,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AAErB,kBAAc,qBAAqB;AAAA,MACjC;AAAA,QACE,gBAAY,sCAAmB,eAAe,QAAQ,GAAG;AAAA,QACzD,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AACD;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAkBO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,MAAM,iBAAiB,IAAI,IAAI;AAChD,QAAM,iBAAiB,IAAI,KAAK;AAChC,QAAM,mBAAmB,eAAe,IAAI,CAAC,eAAe,WAAW,GAAG;AAE1E,MACE,OAAO,mBAAmB,YAC1B,MAAM,QAAQ,cAAc,KAC5B,eAAe,WAAW,GAC1B;AACA,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF,WAAW,CAAC,gBAAgB;AAC1B,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,+BAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI;AACF,UAAM,EAAE,yBAAyB,mBAAmB,IAClD,MAAM,kBAAkB;AAAA,MACtB;AAAA,MACA,QAAQ;AAAA,IACV;AAEF,UAAM,uBAAuB,eAAe;AAAA,MAAO,CAAC,eAClD,wBAAwB,SAAS,WAAW,GAAG;AAAA,IACjD;AACA,UAAM,kBAAkB,eAAe;AAAA,MAAO,CAAC,eAC7C,mBAAmB,SAAS,WAAW,GAAG;AAAA,IAC5C;AAEA,UAAM,wBAAyC,CAAC;AAChD,UAAM,4BAA6C,CAAC;AACpD,UAAM,cAAmD,CAAC;AAE1D,eAAW,oBAAoB,iBAAiB;AAC9C,YAAM,aAA6B;AAAA,QACjC,OAAO,iBAAiB;AAAA,QACxB,aAAa,iBAAiB;AAAA,QAC9B,YAAY,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,QAChC,WAAW,KAAK;AAAA,QAChB,SAAS,oBAAI,IAAI;AAAA,UACf,CAAC,MAAM,EAAE,SAAS,iBAAiB,WAAY,CAAC,EAAkB,CAAC;AAAA,QACrE,CAAC;AAAA,QACD,UAAU;AAAA,UACR,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,iBAAiB,YAAY;AAAA,QACtD;AAAA,QACA,KAAK,iBAAiB;AAAA,MACxB;AAEA,UAAI;AACF,cAAM,gBACJ,MAAM,kBAAkB,iBAAiB,UAAU;AACrD,8BAAsB;AAAA,cACpB,sCAAmB,eAAe,QAAQ,GAAG;AAAA,QAC/C;AAAA,MACF,SAAS,OAAO;AACd,mCAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,MACF;AAAA,IACF;AAEA,QAAI,wBAAwB,UAAU,GAAG;AACvC,YAAM,yBACJ,MAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,QAAQ;AAAA,MACV;AAEF,iBAAW,oBAAoB,sBAAsB;AACnD,cAAM,uBAAuB,uBAAuB;AAAA,UAClD,CAAC,iBAAiB,aAAa,QAAQ,iBAAiB;AAAA,QAC1D;AAEA,cAAM,cAAc,CAAC,GAAI,qBAAqB,QAAQ,KAAK,KAAK,CAAC,CAAE;AACnE,cAAM,cAAc,YAAY,YAAY,SAAS,CAAC;AAEtD,cAAM,cACH,qBAAqB,QAAQ,IAAI,WAAW,GACzC,WAAwC;AAE9C,cAAM,gBACJ,KAAK,UAAU,WAAW,MAC1B,KAAK,UAAU,iBAAiB,OAAO;AAEzC,YAAI,aAA+B,qBAAqB;AAExD,YAAI,CAAC,eAAe;AAClB,gBAAM,oBACJ,kBAAkB,iBAAiB,oBAAoB;AAEzD,+BAAqB,QAAQ,IAAI,mBAAmB;AAAA,YAClD,SAAS,iBAAiB,WAAY,CAAC;AAAA,UACzC,CAAC;AAED,uBAAa,qBAAqB;AAAA,QACpC;AAEA,cAAM,aAA6B;AAAA,UACjC,OAAG,gEAA4B,oBAAoB;AAAA,UACnD,GAAG;AAAA,UACH,SAAS;AAAA,UACT,YAAY,CAAC,OAAO,QAAQ,GAAG,CAAC;AAAA,UAChC,WAAW,KAAK;AAAA,UAChB,UAAU;AAAA,YACR,CAAC,OAAO,QAAQ,GAAG,CAAC,GAAG,iBAAiB,YAAY;AAAA,UACtD;AAAA,UACA,KAAK,iBAAiB;AAAA,QACxB;AAEA,YAAI;AACF,gBAAM,oBACJ,MAAM,kBAAkB;AAAA,YACtB,iBAAiB;AAAA,YACjB;AAAA,YACA,QAAQ;AAAA,UACV;AACF,oCAA0B;AAAA,gBACxB,sCAAmB,mBAAmB,QAAQ,GAAG;AAAA,UACnD;AAAA,QACF,SAAS,OAAO;AACd,qCAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAqC;AAAA,MACzC,iBAAiB,sBAAsB;AAAA,QACrC,CAAC,eAAe,WAAW;AAAA,MAC7B;AAAA,MACA,qBAAqB,0BAA0B;AAAA,QAC7C,CAAC,eAAe,WAAW;AAAA,MAC7B;AAAA,MACA,OAAO;AAAA,IACT;AAEA,UAAM,mBAAe,oCAA2C;AAAA,MAC9D,aAAS,2BAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,iBAAa,2BAAE;AAAA,QACb,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC;AAED,kBAAc,qBAAqB;AAAA,MACjC,GAAG,sBAAsB;AAAA,QACvB,CAAC,gBACE;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACJ;AAAA,MACA,GAAG,0BAA0B;AAAA,QAC3B,CAAC,gBACE;AAAA,UACC;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACJ;AAAA,IACF,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AASO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,aAAa,IAAI,IAAI;AAC7B,QAAM,EAAE,SAAS,iBAAiB,IAAI,IAAI;AAC1C,QAAM,iBAAiB,IAAI;AAE3B,MAAI,CAAC,gBAAgB;AACnB,+BAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,YAAY,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC7D,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB,aAAa;AACvC,+BAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI;AACF,UAAM,oBAAoB,MAAM,kBAAkB;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAEA,UAAM,gBAAY,sCAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,aAAS,2BAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,iBAAa,2BAAE;AAAA,QACb,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC;AAED,kBAAc,qBAAqB;AAAA,MACjC;AAAA,QACE,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;AAQO,MAAM,mBAAmB,OAC9B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,SAAS,iBAAiB,IAAI,IAAI;AAC1C,QAAM,EAAE,aAAa,IAAI,IAAI;AAE7B,MAAI,CAAC,cAAc;AACjB,+BAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,+BAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,+BAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI;AACF,UAAM,qBACJ,MAAM,kBAAkB,kBAAkB,YAAY;AAExD,QAAI,CAAC,mBAAmB,WAAW,SAAS,QAAQ,GAAG,GAAG;AACxD,iCAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,oBACJ,MAAM,kBAAkB,qBAAqB,YAAY;AAE3D,QAAI,CAAC,mBAAmB;AACtB,iCAAa,2BAA2B,KAAK,wBAAwB;AAAA,QACnE;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,yBAAO,KAAK,uBAAuB,OAAO,kBAAkB,GAAG,CAAC,EAAE;AAElE,UAAM,gBAAY,sCAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,mBAAe,oCAA8B;AAAA,MACjD,aAAS,2BAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,iBAAa,2BAAE;AAAA,QACb,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AAErB,kBAAc,qBAAqB;AAAA,MACjC;AAAA,QACE,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED;AAAA,EACF,SAAS,OAAO;AACd,+BAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;","names":[]}
@@ -26,41 +26,57 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var event_listener_exports = {};
30
- __export(event_listener_exports, {
29
+ var eventListener_controller_exports = {};
30
+ __export(eventListener_controller_exports, {
31
31
  listenChangeSSE: () => listenChangeSSE,
32
32
  sendDictionaryUpdate: () => sendDictionaryUpdate
33
33
  });
34
- module.exports = __toCommonJS(event_listener_exports);
34
+ module.exports = __toCommonJS(eventListener_controller_exports);
35
35
  var oAuth2Service = __toESM(require('./../services/oAuth2.service.cjs'), 1);
36
36
  var import_errors = require('./../utils/errors/index.cjs');
37
+ var import_logger = require('./../logger/index.cjs');
37
38
  let clients = [];
39
+ const MAX_SSE_CONNECTIONS = 10;
38
40
  const sendDictionaryUpdate = (args) => {
39
41
  const projectIds = args.flatMap((arg) => arg.dictionary.projectIds);
40
42
  const filteredClients = clients.filter(
41
43
  (client) => projectIds.map((id) => String(id)).includes(String(client.projectId))
42
44
  );
43
- for (const client of filteredClients) {
44
- client.res.write(`data: ${JSON.stringify(args)}
45
+ const data = args.map((arg) => ({
46
+ object: "DICTIONARY",
47
+ status: arg.status,
48
+ data: arg.dictionary
49
+ }));
50
+ process.nextTick(() => {
51
+ for (const client of filteredClients) {
52
+ client.res.write(`data: ${JSON.stringify(data)}
45
53
 
46
54
  `);
47
- }
55
+ client.res.flush?.();
56
+ }
57
+ });
48
58
  };
49
59
  const listenChangeSSE = async (req, res) => {
50
60
  const { accessToken } = req.params;
51
61
  if (!accessToken) {
52
62
  import_errors.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_AUTHENTICATED");
63
+ return;
53
64
  }
54
65
  const tokenInformation = await oAuth2Service.getAccessToken(accessToken);
55
66
  if (!tokenInformation) {
56
67
  import_errors.ErrorHandler.handleGenericErrorResponse(res, "AUTH_ERROR");
68
+ return;
69
+ }
70
+ if (clients.length >= MAX_SSE_CONNECTIONS) {
71
+ import_errors.ErrorHandler.handleGenericErrorResponse(res, "TOO_MANY_CONNECTIONS");
72
+ return;
57
73
  }
58
74
  res.setHeader("Content-Type", "text/event-stream;charset=utf-8");
59
75
  res.setHeader("Cache-Control", "no-cache, no-transform");
60
76
  res.setHeader("Connection", "keep-alive");
61
77
  res.setHeader("X-Accel-Buffering", "no");
62
78
  res.write(":\n\n");
63
- res.flushHeaders();
79
+ res.flushHeaders?.();
64
80
  const clientId = Date.now();
65
81
  const newClient = {
66
82
  id: clientId,
@@ -68,6 +84,9 @@ const listenChangeSSE = async (req, res) => {
68
84
  res
69
85
  };
70
86
  clients.push(newClient);
87
+ import_logger.logger.info(
88
+ `New client connected to SSE. Total clients: ${clients.length ?? 0}`
89
+ );
71
90
  req.on("close", () => {
72
91
  clients = clients.filter((client) => client.id !== clientId);
73
92
  });
@@ -77,4 +96,4 @@ const listenChangeSSE = async (req, res) => {
77
96
  listenChangeSSE,
78
97
  sendDictionaryUpdate
79
98
  });
80
- //# sourceMappingURL=event-listener.cjs.map
99
+ //# sourceMappingURL=eventListener.controller.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/controllers/eventListener.controller.ts"],"sourcesContent":["import type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport type { Token } from '@schemas/oAuth2.schema';\nimport * as oAuth2Service from '@services/oAuth2.service';\nimport { ErrorHandler } from '@utils/errors';\nimport type { Response, Request } from 'express';\nimport type { DictionaryAPI } from '@/types/dictionary.types';\nimport { logger } from '@logger';\n\nexport type Object = 'DICTIONARY';\nexport type Status = 'ADDED' | 'UPDATED' | 'DELETED' | 'CREATED';\n\nexport type MessageEventData = {\n object: Object;\n status: Status;\n data: any;\n};\n\nlet clients: Array<{ id: number; projectId: string; res: Response }> = [];\nconst MAX_SSE_CONNECTIONS = 10;\n\nexport type SendDictionaryUpdateArg = {\n dictionary: DictionaryAPI;\n status: 'ADDED' | 'UPDATED' | 'DELETED' | 'CREATED';\n};\n\nexport const sendDictionaryUpdate = (args: SendDictionaryUpdateArg[]) => {\n const projectIds = args.flatMap((arg) => arg.dictionary.projectIds);\n\n const filteredClients = clients.filter((client) =>\n projectIds.map((id) => String(id)).includes(String(client.projectId))\n );\n\n const data: MessageEventData[] = args.map((arg) => ({\n object: 'DICTIONARY',\n status: arg.status,\n data: arg.dictionary,\n }));\n\n process.nextTick(() => {\n for (const client of filteredClients) {\n client.res.write(`data: ${JSON.stringify(data)}\\n\\n`);\n client.res.flush?.(); // Ensure the data is sent immediately\n }\n });\n};\n\nexport type CheckDictionaryChangeSSEParams = { accessToken: string };\n\n/**\n * SSE to check the email verification status\n */\nexport const listenChangeSSE = async (\n req: Request<CheckDictionaryChangeSSEParams, any, any>,\n res: ResponseWithInformation\n) => {\n const { accessToken } = req.params;\n\n if (!accessToken) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_AUTHENTICATED');\n return;\n }\n\n const tokenInformation = await oAuth2Service.getAccessToken(accessToken);\n\n if (!tokenInformation) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUTH_ERROR');\n return;\n }\n\n if (clients.length >= MAX_SSE_CONNECTIONS) {\n ErrorHandler.handleGenericErrorResponse(res, 'TOO_MANY_CONNECTIONS');\n return;\n }\n\n // Set headers for SSE\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'); // For Nginx buffering\n\n // Send initial data to ensure the connection is open\n res.write(':\\n\\n'); // Comment to keep connection alive\n res.flushHeaders?.();\n\n const clientId = Date.now();\n\n // Add client to the list\n const newClient = {\n id: clientId,\n projectId: String((tokenInformation as unknown as Token).project._id),\n res,\n };\n clients.push(newClient);\n\n logger.info(\n `New client connected to SSE. Total clients: ${clients.length ?? 0}`\n );\n\n // Remove client on connection close\n req.on('close', () => {\n clients = clients.filter((client) => client.id !== clientId);\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA+B;AAC/B,oBAA6B;AAG7B,oBAAuB;AAWvB,IAAI,UAAmE,CAAC;AACxE,MAAM,sBAAsB;AAOrB,MAAM,uBAAuB,CAAC,SAAoC;AACvE,QAAM,aAAa,KAAK,QAAQ,CAAC,QAAQ,IAAI,WAAW,UAAU;AAElE,QAAM,kBAAkB,QAAQ;AAAA,IAAO,CAAC,WACtC,WAAW,IAAI,CAAC,OAAO,OAAO,EAAE,CAAC,EAAE,SAAS,OAAO,OAAO,SAAS,CAAC;AAAA,EACtE;AAEA,QAAM,OAA2B,KAAK,IAAI,CAAC,SAAS;AAAA,IAClD,QAAQ;AAAA,IACR,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,EACZ,EAAE;AAEF,UAAQ,SAAS,MAAM;AACrB,eAAW,UAAU,iBAAiB;AACpC,aAAO,IAAI,MAAM,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA;AAAA,CAAM;AACpD,aAAO,IAAI,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAOO,MAAM,kBAAkB,OAC7B,KACA,QACG;AACH,QAAM,EAAE,YAAY,IAAI,IAAI;AAE5B,MAAI,CAAC,aAAa;AAChB,+BAAa,2BAA2B,KAAK,wBAAwB;AACrE;AAAA,EACF;AAEA,QAAM,mBAAmB,MAAM,cAAc,eAAe,WAAW;AAEvE,MAAI,CAAC,kBAAkB;AACrB,+BAAa,2BAA2B,KAAK,YAAY;AACzD;AAAA,EACF;AAEA,MAAI,QAAQ,UAAU,qBAAqB;AACzC,+BAAa,2BAA2B,KAAK,sBAAsB;AACnE;AAAA,EACF;AAGA,MAAI,UAAU,gBAAgB,iCAAiC;AAC/D,MAAI,UAAU,iBAAiB,wBAAwB;AACvD,MAAI,UAAU,cAAc,YAAY;AACxC,MAAI,UAAU,qBAAqB,IAAI;AAGvC,MAAI,MAAM,OAAO;AACjB,MAAI,eAAe;AAEnB,QAAM,WAAW,KAAK,IAAI;AAG1B,QAAM,YAAY;AAAA,IAChB,IAAI;AAAA,IACJ,WAAW,OAAQ,iBAAsC,QAAQ,GAAG;AAAA,IACpE;AAAA,EACF;AACA,UAAQ,KAAK,SAAS;AAEtB,uBAAO;AAAA,IACL,+CAA+C,QAAQ,UAAU,CAAC;AAAA,EACpE;AAGA,MAAI,GAAG,SAAS,MAAM;AACpB,cAAU,QAAQ,OAAO,CAAC,WAAW,OAAO,OAAO,QAAQ;AAAA,EAC7D,CAAC;AACH;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/export.ts"],"sourcesContent":["// Routes\nexport { getUserRoutes } from '@routes/user.routes';\nexport { getOrganizationRoutes } from '@routes/organization.routes';\nexport { getProjectRoutes } from '@routes/project.routes';\nexport { getDictionaryRoutes } from '@routes/dictionary.routes';\nexport { getSessionAuthRoutes } from '@routes/sessionAuth.routes';\n\n// Controllers types\nexport type * from '@controllers/sessionAuth.controller';\nexport type * from '@controllers/oAuth2.controller';\nexport type * from '@controllers/organization.controller';\nexport type * from '@controllers/project.controller';\nexport type * from '@controllers/projectAccessKey.controller';\nexport type * from '@controllers/user.controller';\nexport type * from '@controllers/dictionary.controller';\nexport type * from '@controllers/stripe.controller';\nexport type * from '@controllers/ai.controller';\nexport type * from '@controllers/tag.controller';\n\n// Objects types\nexport type * from '@/types/organization.types';\nexport type * from '@/types/project.types';\nexport type * from '@/types/user.types';\nexport type * from '@/types/dictionary.types';\nexport type * from '@/types/plan.types';\nexport type * from '@/types/tag.types';\nexport type * from '@/types/oAuth2.types';\n\n// Utils\nexport * from '@utils/cookies';\nexport * from '@utils/httpStatusCodes';\nexport * from '@utils/responseData';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAA8B;AAC9B,0BAAsC;AACtC,qBAAiC;AACjC,wBAAoC;AACpC,yBAAqC;AAwBrC,2BAAc,2BA7Bd;AA8BA,2BAAc,mCA9Bd;AA+BA,2BAAc,gCA/Bd;","names":[]}
1
+ {"version":3,"sources":["../../src/export.ts"],"sourcesContent":["// Routes\nexport { getUserRoutes } from '@routes/user.routes';\nexport { getOrganizationRoutes } from '@routes/organization.routes';\nexport { getProjectRoutes } from '@routes/project.routes';\nexport { getDictionaryRoutes } from '@routes/dictionary.routes';\nexport { getSessionAuthRoutes } from '@routes/sessionAuth.routes';\n\n// Controllers types\nexport type * from '@controllers/sessionAuth.controller';\nexport type * from '@controllers/oAuth2.controller';\nexport type * from '@controllers/organization.controller';\nexport type * from '@controllers/eventListener.controller';\nexport type * from '@controllers/project.controller';\nexport type * from '@controllers/projectAccessKey.controller';\nexport type * from '@controllers/user.controller';\nexport type * from '@controllers/dictionary.controller';\nexport type * from '@controllers/stripe.controller';\nexport type * from '@controllers/ai.controller';\nexport type * from '@controllers/tag.controller';\n\n// Objects types\nexport type * from '@/types/organization.types';\nexport type * from '@/types/project.types';\nexport type * from '@/types/user.types';\nexport type * from '@/types/dictionary.types';\nexport type * from '@/types/plan.types';\nexport type * from '@/types/tag.types';\nexport type * from '@/types/oAuth2.types';\n\n// Utils\nexport * from '@utils/cookies';\nexport * from '@utils/httpStatusCodes';\nexport * from '@utils/responseData';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAA8B;AAC9B,0BAAsC;AACtC,qBAAiC;AACjC,wBAAoC;AACpC,yBAAqC;AAyBrC,2BAAc,2BA9Bd;AA+BA,2BAAc,mCA/Bd;AAgCA,2BAAc,gCAhCd;","names":[]}
@@ -49,7 +49,7 @@ var import_sessionAuth2 = require('./routes/sessionAuth.routes.cjs');
49
49
  var import_user = require('./routes/user.routes.cjs');
50
50
  var import_stripe = require('./routes/stripe.routes.cjs');
51
51
  var import_ai = require('./routes/ai.routes.cjs');
52
- var import_event_listener = require('./routes/event-listener.routes.cjs');
52
+ var import_eventListener = require('./routes/eventListener.routes.cjs');
53
53
  var import_stripe2 = require('./webhooks/stripe.webhook.cjs');
54
54
  var import_oAuth22 = require('./controllers/oAuth2.controller.cjs');
55
55
  var import_sessionAuth3 = require('./controllers/sessionAuth.controller.cjs');
@@ -147,7 +147,7 @@ app.use("/api/tag", import_tags.tagRouter);
147
147
  app.use("/api/dictionary", import_dictionary.dictionaryRouter);
148
148
  app.use("/api/stripe", import_stripe.stripeRouter);
149
149
  app.use("/api/ai", import_ai.aiRouter);
150
- app.use("/api/event-listener", import_event_listener.eventListenerRouter);
150
+ app.use("/api/event-listener", import_eventListener.eventListenerRouter);
151
151
  app.listen(process.env.PORT, () => {
152
152
  import_logger.logger.info(`Listening on port ${process.env.PORT}`);
153
153
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["/* eslint-disable import/order */\n\n// Libraries\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport dotenv from 'dotenv';\nimport express, { type Express } from 'express';\nimport { intlayer, t } from 'express-intlayer';\nimport helmet from 'helmet';\n\n// Middlewares\nimport {\n type RequestWithOAuth2Information,\n attachOAuthInstance,\n authenticateOAuth2,\n} from '@middlewares/oAuth2.middleware';\nimport { logAPIRequestURL } from '@middlewares/request.middleware';\nimport {\n type ResponseWithInformation,\n checkUser,\n checkOrganization,\n checkProject,\n checkAdmin,\n} from '@middlewares/sessionAuth.middleware';\n\n// Routes\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport { organizationRouter } from '@routes/organization.routes';\nimport { projectRouter } from '@routes/project.routes';\nimport { tagRouter } from '@routes/tags.routes';\nimport { sessionAuthRouter } from '@routes/sessionAuth.routes';\nimport { userRouter } from '@routes/user.routes';\nimport { stripeRouter } from '@routes/stripe.routes';\nimport { aiRouter } from '@routes/ai.routes';\nimport { eventListenerRouter } from '@routes/event-listener.routes';\n\n// Webhooks\nimport { stripeWebhook } from '@webhooks/stripe.webhook';\n\n// Controllers\nimport { getOAuth2Token } from '@controllers/oAuth2.controller';\nimport {\n getSessionInformation,\n setCSRFToken,\n} from '@controllers/sessionAuth.controller';\n\n// Utils\nimport { doubleCsrfProtection } from '@utils/CSRF';\nimport { connectDB } from '@utils/mongoDB/connectDB';\n\n// Logger\nimport { logger } from './logger/index';\n\nconst app: Express = express();\n\napp.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\napp.use(helmet());\n\n// Environment variables\nconst env = app.get('env');\n\nlogger.info(`run as ${env}`);\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n});\n\n// Parse incoming requests with cookies\napp.use(cookieParser());\n\n// Load internationalization request handler\napp.use(intlayer());\n\nconst isDev = env === 'development';\n\n// Connect to MongoDB\nconnectDB();\n\n// Stripe\napp.post(\n '/webhook/stripe',\n express.raw({ type: 'application/json' }),\n stripeWebhook\n);\n\n// Compress all HTTP responses\napp.use(compression());\n\n// Parse incoming requests with JSON payloads\napp.use(express.json({ limit: '50mb' }));\n\n// Parse incoming requests with urlencoded payloads\napp.use(express.urlencoded({ extended: true }));\n\nconst whitelist = [process.env.CLIENT_URL!];\n\n// CORS\nconst corsOptions: CorsOptions = {\n origin: (origin, callback) => {\n // Allow requests with no origin (like mobile apps or curl requests)\n if (!origin) return callback(null, true);\n\n if (whitelist.includes(origin)) {\n logger.info('whitelisted origin', origin);\n return callback(null, true);\n }\n\n logger.info('non whitelisted origin', origin);\n // Reflect the request's origin (echo back the origin header)\n callback(null, origin);\n },\n allowedHeaders: [\n 'authorization',\n 'Content-Type',\n 'credentials',\n 'cache-control',\n 'Access-Control-Allow-Origin',\n 'private-state-token-redemption',\n 'private-state-token-issuance',\n 'browsing-topics',\n ],\n exposedHeaders: [''],\n preflightContinue: false,\n methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n credentials: true,\n};\napp.use(cors(corsOptions));\n\n// Liveness check\napp.get('/', (_req, res) => {\n res.send(\n t({\n en: 'Ok - locale: en',\n fr: 'Ok - locale: fr',\n es: 'Ok - locale: es',\n })\n );\n});\n\n// middleware - jwt & session auth\napp.use(/(.*)/, checkUser);\napp.use(/(.*)/, checkOrganization);\napp.use(/(.*)/, checkProject);\napp.use(/(.*)/, checkAdmin);\n\n// debug\nif (isDev) {\n app.use(logAPIRequestURL);\n}\n\n// Sessions\napp.get('/session', getSessionInformation);\napp.use('/api/auth', sessionAuthRouter);\n\n// CSRF\napp.get('/csrf-token', setCSRFToken);\n\n// oAuth2\napp.use(/(.*)/, attachOAuthInstance);\napp.post('/oauth2/token', getOAuth2Token); // Route to get the token\napp.use(/(.*)/, (req, res, next) => {\n // If the request is not already authenticated check the oAuth2 token\n if (!res.locals.authType) {\n return authenticateOAuth2(\n req as RequestWithOAuth2Information,\n res as ResponseWithInformation,\n next\n );\n }\n next();\n});\n\n// CSRF protection\napp.use(/(.*)/, (req, res, next) => {\n // If the request is authenticated using the session auth check the CSRF token\n if (res.locals.authType === 'session') {\n return doubleCsrfProtection(req, res, next);\n }\n next();\n});\n\n// Routes\napp.use('/api/user', userRouter);\napp.use('/api/organization', organizationRouter);\napp.use('/api/project', projectRouter);\napp.use('/api/tag', tagRouter);\napp.use('/api/dictionary', dictionaryRouter);\napp.use('/api/stripe', stripeRouter);\napp.use('/api/ai', aiRouter);\napp.use('/api/event-listener', eventListenerRouter);\n\n// Server\napp.listen(process.env.PORT, () => {\n logger.info(`Listening on port ${process.env.PORT}`);\n});\n\n// Export tu use as serverless function\nexport default app;\n"],"mappings":"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","names":["import_sessionAuth","import_stripe","import_oAuth2","express","helmet","dotenv","cookieParser","compression","cors"]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// Libraries\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport cors, { type CorsOptions } from 'cors';\nimport dotenv from 'dotenv';\nimport express, { type Express } from 'express';\nimport { intlayer, t } from 'express-intlayer';\nimport helmet from 'helmet';\n\n// Middlewares\nimport {\n type RequestWithOAuth2Information,\n attachOAuthInstance,\n authenticateOAuth2,\n} from '@middlewares/oAuth2.middleware';\nimport { logAPIRequestURL } from '@middlewares/request.middleware';\nimport {\n type ResponseWithInformation,\n checkUser,\n checkOrganization,\n checkProject,\n checkAdmin,\n} from '@middlewares/sessionAuth.middleware';\n\n// Routes\nimport { dictionaryRouter } from '@routes/dictionary.routes';\nimport { organizationRouter } from '@routes/organization.routes';\nimport { projectRouter } from '@routes/project.routes';\nimport { tagRouter } from '@routes/tags.routes';\nimport { sessionAuthRouter } from '@routes/sessionAuth.routes';\nimport { userRouter } from '@routes/user.routes';\nimport { stripeRouter } from '@routes/stripe.routes';\nimport { aiRouter } from '@routes/ai.routes';\nimport { eventListenerRouter } from '@routes/eventListener.routes';\n\n// Webhooks\nimport { stripeWebhook } from '@webhooks/stripe.webhook';\n\n// Controllers\nimport { getOAuth2Token } from '@controllers/oAuth2.controller';\nimport {\n getSessionInformation,\n setCSRFToken,\n} from '@controllers/sessionAuth.controller';\n\n// Utils\nimport { doubleCsrfProtection } from '@utils/CSRF';\nimport { connectDB } from '@utils/mongoDB/connectDB';\n\n// Logger\nimport { logger } from './logger/index';\n\nconst app: Express = express();\n\napp.disable('x-powered-by'); // Disabled to prevent attackers from knowing that the app is running Express\napp.use(helmet());\n\n// Environment variables\nconst env = app.get('env');\n\nlogger.info(`run as ${env}`);\n\ndotenv.config({\n path: [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'],\n});\n\n// Parse incoming requests with cookies\napp.use(cookieParser());\n\n// Load internationalization request handler\napp.use(intlayer());\n\nconst isDev = env === 'development';\n\n// Connect to MongoDB\nconnectDB();\n\n// Stripe\napp.post(\n '/webhook/stripe',\n express.raw({ type: 'application/json' }),\n stripeWebhook\n);\n\n// Compress all HTTP responses\napp.use(compression());\n\n// Parse incoming requests with JSON payloads\napp.use(express.json({ limit: '50mb' }));\n\n// Parse incoming requests with urlencoded payloads\napp.use(express.urlencoded({ extended: true }));\n\nconst whitelist = [process.env.CLIENT_URL!];\n\n// CORS\nconst corsOptions: CorsOptions = {\n origin: (origin, callback) => {\n // Allow requests with no origin (like mobile apps or curl requests)\n if (!origin) return callback(null, true);\n\n if (whitelist.includes(origin)) {\n logger.info('whitelisted origin', origin);\n return callback(null, true);\n }\n\n logger.info('non whitelisted origin', origin);\n // Reflect the request's origin (echo back the origin header)\n callback(null, origin);\n },\n allowedHeaders: [\n 'authorization',\n 'Content-Type',\n 'credentials',\n 'cache-control',\n 'Access-Control-Allow-Origin',\n 'private-state-token-redemption',\n 'private-state-token-issuance',\n 'browsing-topics',\n ],\n exposedHeaders: [''],\n preflightContinue: false,\n methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n credentials: true,\n};\napp.use(cors(corsOptions));\n\n// Liveness check\napp.get('/', (_req, res) => {\n res.send(\n t({\n en: 'Ok - locale: en',\n fr: 'Ok - locale: fr',\n es: 'Ok - locale: es',\n })\n );\n});\n\n// middleware - jwt & session auth\napp.use(/(.*)/, checkUser);\napp.use(/(.*)/, checkOrganization);\napp.use(/(.*)/, checkProject);\napp.use(/(.*)/, checkAdmin);\n\n// debug\nif (isDev) {\n app.use(logAPIRequestURL);\n}\n\n// Sessions\napp.get('/session', getSessionInformation);\napp.use('/api/auth', sessionAuthRouter);\n\n// CSRF\napp.get('/csrf-token', setCSRFToken);\n\n// oAuth2\napp.use(/(.*)/, attachOAuthInstance);\napp.post('/oauth2/token', getOAuth2Token); // Route to get the token\napp.use(/(.*)/, (req, res, next) => {\n // If the request is not already authenticated check the oAuth2 token\n if (!res.locals.authType) {\n return authenticateOAuth2(\n req as RequestWithOAuth2Information,\n res as ResponseWithInformation,\n next\n );\n }\n next();\n});\n\n// CSRF protection\napp.use(/(.*)/, (req, res, next) => {\n // If the request is authenticated using the session auth check the CSRF token\n if (res.locals.authType === 'session') {\n return doubleCsrfProtection(req, res, next);\n }\n next();\n});\n\n// Routes\napp.use('/api/user', userRouter);\napp.use('/api/organization', organizationRouter);\napp.use('/api/project', projectRouter);\napp.use('/api/tag', tagRouter);\napp.use('/api/dictionary', dictionaryRouter);\napp.use('/api/stripe', stripeRouter);\napp.use('/api/ai', aiRouter);\napp.use('/api/event-listener', eventListenerRouter);\n\n// Server\napp.listen(process.env.PORT, () => {\n logger.info(`Listening on port ${process.env.PORT}`);\n});\n\n// Export tu use as serverless function\nexport default app;\n"],"mappings":"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","names":["import_sessionAuth","import_stripe","import_oAuth2","express","helmet","dotenv","cookieParser","compression","cors"]}
@@ -16,13 +16,13 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var event_listener_routes_exports = {};
20
- __export(event_listener_routes_exports, {
19
+ var eventListener_routes_exports = {};
20
+ __export(eventListener_routes_exports, {
21
21
  eventListenerRouter: () => eventListenerRouter,
22
22
  eventListenerRoutes: () => eventListenerRoutes
23
23
  });
24
- module.exports = __toCommonJS(event_listener_routes_exports);
25
- var import_event_listener = require('./../controllers/event-listener.cjs');
24
+ module.exports = __toCommonJS(eventListener_routes_exports);
25
+ var import_eventListener = require('./../controllers/eventListener.controller.cjs');
26
26
  var import_express = require("express");
27
27
  const eventListenerRouter = (0, import_express.Router)();
28
28
  const baseURL = () => `${process.env.BACKEND_URL}/api/event-listener`;
@@ -35,11 +35,11 @@ const eventListenerRoutes = () => ({
35
35
  });
36
36
  eventListenerRouter.get(
37
37
  eventListenerRoutes().checkDictionaryChangeSSE.urlModel,
38
- import_event_listener.listenChangeSSE
38
+ import_eventListener.listenChangeSSE
39
39
  );
40
40
  // Annotate the CommonJS export names for ESM import in node:
41
41
  0 && (module.exports = {
42
42
  eventListenerRouter,
43
43
  eventListenerRoutes
44
44
  });
45
- //# sourceMappingURL=event-listener.routes.cjs.map
45
+ //# sourceMappingURL=eventListener.routes.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/routes/eventListener.routes.ts"],"sourcesContent":["import { listenChangeSSE } from '@controllers/eventListener.controller';\nimport { Router } from 'express';\nimport type { Routes } from '@/types/Routes';\n\nexport const eventListenerRouter: Router = Router();\n\nconst baseURL = () => `${process.env.BACKEND_URL}/api/event-listener`;\n\nexport const eventListenerRoutes = () =>\n ({\n checkDictionaryChangeSSE: {\n urlModel: '/:accessToken',\n url: ({ accessToken }: { accessToken: string }) =>\n `${baseURL}/${accessToken}`,\n method: 'GET',\n },\n }) satisfies Routes;\n\neventListenerRouter.get(\n eventListenerRoutes().checkDictionaryChangeSSE.urlModel,\n listenChangeSSE\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAgC;AAChC,qBAAuB;AAGhB,MAAM,0BAA8B,uBAAO;AAElD,MAAM,UAAU,MAAM,GAAG,QAAQ,IAAI,WAAW;AAEzC,MAAM,sBAAsB,OAChC;AAAA,EACC,0BAA0B;AAAA,IACxB,UAAU;AAAA,IACV,KAAK,CAAC,EAAE,YAAY,MAClB,GAAG,OAAO,IAAI,WAAW;AAAA,IAC3B,QAAQ;AAAA,EACV;AACF;AAEF,oBAAoB;AAAA,EAClB,oBAAoB,EAAE,yBAAyB;AAAA,EAC/C;AACF;","names":[]}
@@ -46,26 +46,7 @@ const findDictionaries = async (filters, skip = 0, limit = 100) => {
46
46
  // Stage 2: Skip for pagination
47
47
  { $skip: skip },
48
48
  // Stage 3: Limit the number of documents
49
- { $limit: limit },
50
- // Stage 4: Add the 'availableVersions' field
51
- {
52
- $addFields: {
53
- availableVersions: {
54
- $map: {
55
- input: { $objectToArray: "$content" },
56
- as: "version",
57
- in: "$$version.k"
58
- }
59
- }
60
- }
61
- }
62
- // (Optional) Stage 5: Project the fields you want to include/exclude
63
- // For example, to exclude the entire 'content' field and keep only 'availableVersions'
64
- // {
65
- // $project: {
66
- // content: 0 // Exclude the 'content' field
67
- // }
68
- // }
49
+ { $limit: limit }
69
50
  ]);
70
51
  const formattedResults = dictionaries.map(
71
52
  (result) => new import_dictionary.DictionaryModel(result)
@@ -248,18 +229,18 @@ const deleteDictionaryById = async (dictionaryId) => {
248
229
  }
249
230
  return dictionary;
250
231
  };
232
+ const getVersionNumber = (version) => {
233
+ const match = version.match(/^v(\d+)$/);
234
+ if (!match) {
235
+ throw new Error(`Invalid version format: ${version}`);
236
+ }
237
+ return parseInt(match[1], 10);
238
+ };
251
239
  const incrementVersion = (dictionary) => {
252
240
  const VERSION_PREFIX = "v";
253
- const availableVersions = dictionary.availableVersions ?? [];
254
- const currentVersion = availableVersions.length > 0 ? availableVersions[availableVersions.length - 1] : "v1";
255
- const getVersionNumber = (version) => {
256
- const match = version.match(/^v(\d+)$/);
257
- if (!match) {
258
- throw new Error(`Invalid version format: ${version}`);
259
- }
260
- return parseInt(match[1], 10);
261
- };
262
- let newNumber = getVersionNumber(currentVersion) + 1;
241
+ const availableVersions = [...dictionary.content.keys() ?? []];
242
+ const lastVersion = availableVersions[availableVersions.length - 1];
243
+ let newNumber = getVersionNumber(lastVersion) + 1;
263
244
  let newVersion = `${VERSION_PREFIX}${newNumber}`;
264
245
  while (availableVersions.includes(newVersion)) {
265
246
  newNumber += 1;
@@ -1 +1 @@
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 type { 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 const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 dictionaries = 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 (!dictionaries.length) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return new DictionaryModel(dictionaries[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 const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 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
+ {"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 type { 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\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 dictionaries = 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 (!dictionaries.length) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return new DictionaryModel(dictionaries[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 const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\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 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\n// Function to extract the numeric part of the version\nconst 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\nexport const incrementVersion = (dictionary: Dictionary): string => {\n const VERSION_PREFIX = 'v';\n\n const availableVersions = [...(dictionary.content.keys() ?? [])];\n const lastVersion = availableVersions[availableVersions.length - 1];\n\n // Start with the next version number\n let newNumber = getVersionNumber(lastVersion) + 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 +1 @@
1
- {"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport type { Model, ObjectId, Document } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['_id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['_id'] | string)[];\n creatorId: User['_id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n};\n\nexport type Dictionary = DictionaryData & {\n _id: ObjectId;\n createdAt: number;\n updatedAt: number;\n availableVersions?: string[];\n};\n\nexport type DictionaryAPI = DictionaryCore & {\n projectIds: (Project['_id'] | string)[];\n};\n\nexport type DictionaryDocument = Document<unknown, {}, Dictionary> & Dictionary;\nexport type DictionaryModelType = Model<Dictionary>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport type { Model, ObjectId, Document } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['_id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['_id'] | string)[];\n creatorId: User['_id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n};\n\nexport type Dictionary = DictionaryData & {\n _id: ObjectId;\n createdAt: number;\n updatedAt: number;\n};\n\nexport type DictionaryAPI = DictionaryCore & {\n projectIds: (Project['_id'] | string)[];\n};\n\nexport type DictionaryDocument = Document<unknown, {}, Dictionary> & Dictionary;\nexport type DictionaryModelType = Model<Dictionary>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}