@intlayer/backend 5.1.4 → 5.1.6
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.
- package/dist/cjs/controllers/ai.controller.cjs +61 -43
- package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
- package/dist/cjs/controllers/dictionary.controller.cjs +8 -12
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/controllers/organization.controller.cjs +17 -1
- package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
- package/dist/cjs/controllers/project.controller.cjs +1 -0
- package/dist/cjs/controllers/project.controller.cjs.map +1 -1
- package/dist/cjs/controllers/sessionAuth.controller.cjs +6 -12
- package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
- package/dist/cjs/controllers/stripe.controller.cjs +31 -10
- package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
- package/dist/cjs/controllers/tag.controller.cjs +0 -7
- package/dist/cjs/controllers/tag.controller.cjs.map +1 -1
- package/dist/cjs/controllers/user.controller.cjs +1 -1
- package/dist/cjs/controllers/user.controller.cjs.map +1 -1
- package/dist/cjs/emails/InviteUserEmail.cjs +3 -3
- package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/PasswordChangeConfirmation.cjs +3 -3
- package/dist/cjs/emails/PasswordChangeConfirmation.cjs.map +1 -1
- package/dist/cjs/emails/ResetUserPassword.cjs +3 -3
- package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs +19 -3
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentError.cjs +19 -3
- package/dist/cjs/emails/SubscriptionPaymentError.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs +19 -3
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs.map +1 -1
- package/dist/cjs/emails/ValidateUserEmail.cjs +3 -3
- package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/Welcome.cjs +3 -3
- package/dist/cjs/emails/Welcome.cjs.map +1 -1
- package/dist/cjs/export.cjs +10 -10
- package/dist/cjs/export.cjs.map +1 -1
- package/dist/cjs/routes/ai.routes.cjs +21 -15
- package/dist/cjs/routes/ai.routes.cjs.map +1 -1
- package/dist/cjs/routes/dictionary.routes.cjs +15 -12
- package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
- package/dist/cjs/routes/event-listener.routes.cjs +4 -4
- package/dist/cjs/routes/event-listener.routes.cjs.map +1 -1
- package/dist/cjs/routes/organization.routes.cjs +15 -15
- package/dist/cjs/routes/organization.routes.cjs.map +1 -1
- package/dist/cjs/routes/project.routes.cjs +30 -18
- package/dist/cjs/routes/project.routes.cjs.map +1 -1
- package/dist/cjs/routes/sessionAuth.routes.cjs +38 -35
- package/dist/cjs/routes/sessionAuth.routes.cjs.map +1 -1
- package/dist/cjs/routes/stripe.routes.cjs +23 -11
- package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
- package/dist/cjs/routes/tags.routes.cjs +11 -11
- package/dist/cjs/routes/tags.routes.cjs.map +1 -1
- package/dist/cjs/routes/user.routes.cjs +13 -13
- package/dist/cjs/routes/user.routes.cjs.map +1 -1
- package/dist/cjs/schemas/dictionary.schema.cjs +0 -4
- package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
- package/dist/cjs/schemas/project.schema.cjs +2 -2
- package/dist/cjs/schemas/project.schema.cjs.map +1 -1
- package/dist/cjs/services/dictionary.service.cjs.map +1 -1
- package/dist/cjs/services/email.service.cjs +1 -1
- package/dist/cjs/services/email.service.cjs.map +1 -1
- package/dist/cjs/services/subscription.service.cjs +81 -2
- package/dist/cjs/services/subscription.service.cjs.map +1 -1
- package/dist/cjs/types/dictionary.types.cjs.map +1 -1
- package/dist/cjs/utils/AI/{askDocQuestion.cjs → askDocQuestion/askDocQuestion.cjs} +1 -1
- package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs.map +1 -0
- package/dist/{esm/utils/AI → cjs/utils/AI/askDocQuestion}/embeddings.json +4288 -4288
- package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/index.cjs +5 -3
- package/dist/cjs/utils/AI/auditDictionary/index.cjs.map +1 -0
- package/dist/cjs/utils/{auditDictionaryField → AI/auditDictionaryField}/PROMPT.md +17 -7
- package/dist/cjs/utils/{auditDictionaryField → AI/auditDictionaryField}/index.cjs +5 -3
- package/dist/cjs/utils/AI/auditDictionaryField/index.cjs.map +1 -0
- package/dist/cjs/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.cjs +5 -3
- package/dist/cjs/utils/AI/auditDictionaryMetadata/index.cjs.map +1 -0
- package/dist/cjs/utils/AI/autocomplete/PROMPT.md +13 -0
- package/dist/cjs/utils/AI/autocomplete/index.cjs +73 -0
- package/dist/cjs/utils/AI/autocomplete/index.cjs.map +1 -0
- package/dist/cjs/utils/auditTag/index.cjs +4 -2
- package/dist/cjs/utils/auditTag/index.cjs.map +1 -1
- package/dist/cjs/utils/errors/errorCodes.cjs +26 -0
- package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
- package/dist/cjs/utils/mongoDB/connectDB.cjs +10 -0
- package/dist/cjs/utils/mongoDB/connectDB.cjs.map +1 -1
- package/dist/cjs/webhooks/stripe.webhook.cjs +42 -0
- package/dist/cjs/webhooks/stripe.webhook.cjs.map +1 -1
- package/dist/esm/controllers/ai.controller.mjs +59 -42
- package/dist/esm/controllers/ai.controller.mjs.map +1 -1
- package/dist/esm/controllers/dictionary.controller.mjs +8 -12
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/controllers/organization.controller.mjs +18 -2
- package/dist/esm/controllers/organization.controller.mjs.map +1 -1
- package/dist/esm/controllers/project.controller.mjs +1 -0
- package/dist/esm/controllers/project.controller.mjs.map +1 -1
- package/dist/esm/controllers/sessionAuth.controller.mjs +6 -12
- package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
- package/dist/esm/controllers/stripe.controller.mjs +30 -10
- package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
- package/dist/esm/controllers/tag.controller.mjs +0 -7
- package/dist/esm/controllers/tag.controller.mjs.map +1 -1
- package/dist/esm/controllers/user.controller.mjs +2 -2
- package/dist/esm/controllers/user.controller.mjs.map +1 -1
- package/dist/esm/emails/InviteUserEmail.mjs +3 -3
- package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
- package/dist/esm/emails/PasswordChangeConfirmation.mjs +3 -3
- package/dist/esm/emails/PasswordChangeConfirmation.mjs.map +1 -1
- package/dist/esm/emails/ResetUserPassword.mjs +3 -3
- package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs +19 -3
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentError.mjs +19 -3
- package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs +19 -3
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -1
- package/dist/esm/emails/ValidateUserEmail.mjs +3 -3
- package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
- package/dist/esm/emails/Welcome.mjs +3 -3
- package/dist/esm/emails/Welcome.mjs.map +1 -1
- package/dist/esm/export.mjs +10 -10
- package/dist/esm/export.mjs.map +1 -1
- package/dist/esm/routes/ai.routes.mjs +22 -15
- package/dist/esm/routes/ai.routes.mjs.map +1 -1
- package/dist/esm/routes/dictionary.routes.mjs +14 -11
- package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
- package/dist/esm/routes/event-listener.routes.mjs +4 -4
- package/dist/esm/routes/event-listener.routes.mjs.map +1 -1
- package/dist/esm/routes/organization.routes.mjs +13 -13
- package/dist/esm/routes/organization.routes.mjs.map +1 -1
- package/dist/esm/routes/project.routes.mjs +28 -16
- package/dist/esm/routes/project.routes.mjs.map +1 -1
- package/dist/esm/routes/sessionAuth.routes.mjs +37 -34
- package/dist/esm/routes/sessionAuth.routes.mjs.map +1 -1
- package/dist/esm/routes/stripe.routes.mjs +22 -9
- package/dist/esm/routes/stripe.routes.mjs.map +1 -1
- package/dist/esm/routes/tags.routes.mjs +9 -9
- package/dist/esm/routes/tags.routes.mjs.map +1 -1
- package/dist/esm/routes/user.routes.mjs +11 -11
- package/dist/esm/routes/user.routes.mjs.map +1 -1
- package/dist/esm/schemas/dictionary.schema.mjs +0 -4
- package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
- package/dist/esm/schemas/project.schema.mjs +2 -2
- package/dist/esm/schemas/project.schema.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/services/email.service.mjs +1 -1
- package/dist/esm/services/email.service.mjs.map +1 -1
- package/dist/esm/services/subscription.service.mjs +78 -1
- package/dist/esm/services/subscription.service.mjs.map +1 -1
- package/dist/esm/utils/AI/{askDocQuestion.mjs → askDocQuestion/askDocQuestion.mjs} +1 -1
- package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -0
- package/dist/{cjs/utils/AI → esm/utils/AI/askDocQuestion}/embeddings.json +4288 -4288
- package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/index.mjs +5 -3
- package/dist/esm/utils/AI/auditDictionary/index.mjs.map +1 -0
- package/dist/esm/utils/{auditDictionaryField → AI/auditDictionaryField}/PROMPT.md +17 -7
- package/dist/esm/utils/{auditDictionaryField → AI/auditDictionaryField}/index.mjs +5 -3
- package/dist/esm/utils/AI/auditDictionaryField/index.mjs.map +1 -0
- package/dist/esm/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.mjs +5 -3
- package/dist/esm/utils/AI/auditDictionaryMetadata/index.mjs.map +1 -0
- package/dist/esm/utils/AI/autocomplete/PROMPT.md +13 -0
- package/dist/esm/utils/AI/autocomplete/index.mjs +48 -0
- package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -0
- package/dist/esm/utils/auditTag/index.mjs +4 -2
- package/dist/esm/utils/auditTag/index.mjs.map +1 -1
- package/dist/esm/utils/errors/errorCodes.mjs +26 -0
- package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
- package/dist/esm/utils/mongoDB/connectDB.mjs +10 -0
- package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
- package/dist/esm/webhooks/stripe.webhook.mjs +32 -0
- package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -1
- package/dist/types/controllers/ai.controller.d.ts +17 -2
- package/dist/types/controllers/ai.controller.d.ts.map +1 -1
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/controllers/organization.controller.d.ts.map +1 -1
- package/dist/types/controllers/project.controller.d.ts.map +1 -1
- package/dist/types/controllers/sessionAuth.controller.d.ts +4 -3
- package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
- package/dist/types/controllers/stripe.controller.d.ts +15 -7
- package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
- package/dist/types/controllers/tag.controller.d.ts.map +1 -1
- package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +4 -3
- package/dist/types/emails/SubscriptionPaymentCancellation.d.ts.map +1 -1
- package/dist/types/emails/SubscriptionPaymentError.d.ts +4 -3
- package/dist/types/emails/SubscriptionPaymentError.d.ts.map +1 -1
- package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +4 -3
- package/dist/types/emails/SubscriptionPaymentSuccess.d.ts.map +1 -1
- package/dist/types/export.d.ts +5 -5
- package/dist/types/export.d.ts.map +1 -1
- package/dist/types/routes/ai.routes.d.ts +6 -1
- package/dist/types/routes/ai.routes.d.ts.map +1 -1
- package/dist/types/routes/dictionary.routes.d.ts +4 -4
- package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
- package/dist/types/routes/event-listener.routes.d.ts +1 -1
- package/dist/types/routes/event-listener.routes.d.ts.map +1 -1
- package/dist/types/routes/organization.routes.d.ts +5 -5
- package/dist/types/routes/organization.routes.d.ts.map +1 -1
- package/dist/types/routes/project.routes.d.ts +5 -5
- package/dist/types/routes/project.routes.d.ts.map +1 -1
- package/dist/types/routes/sessionAuth.routes.d.ts +4 -7
- package/dist/types/routes/sessionAuth.routes.d.ts.map +1 -1
- package/dist/types/routes/stripe.routes.d.ts +6 -1
- package/dist/types/routes/stripe.routes.d.ts.map +1 -1
- package/dist/types/routes/tags.routes.d.ts +3 -3
- package/dist/types/routes/tags.routes.d.ts.map +1 -1
- package/dist/types/routes/user.routes.d.ts +4 -4
- package/dist/types/routes/user.routes.d.ts.map +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
- package/dist/types/services/dictionary.service.d.ts.map +1 -1
- package/dist/types/services/subscription.service.d.ts +9 -0
- package/dist/types/services/subscription.service.d.ts.map +1 -1
- package/dist/types/types/dictionary.types.d.ts +0 -1
- package/dist/types/types/dictionary.types.d.ts.map +1 -1
- package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -0
- package/dist/types/utils/{auditDictionary → AI/auditDictionary}/index.d.ts +8 -5
- package/dist/types/utils/AI/auditDictionary/index.d.ts.map +1 -0
- package/dist/types/utils/{auditDictionaryField → AI/auditDictionaryField}/index.d.ts +8 -5
- package/dist/types/utils/AI/auditDictionaryField/index.d.ts.map +1 -0
- package/dist/types/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.d.ts +8 -5
- package/dist/types/utils/AI/auditDictionaryMetadata/index.d.ts.map +1 -0
- package/dist/types/utils/AI/autocomplete/index.d.ts +22 -0
- package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -0
- package/dist/types/utils/auditTag/index.d.ts +7 -4
- package/dist/types/utils/auditTag/index.d.ts.map +1 -1
- package/dist/types/utils/errors/errorCodes.d.ts +26 -0
- package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
- package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
- package/dist/types/webhooks/stripe.webhook.d.ts.map +1 -1
- package/package.json +11 -10
- package/dist/cjs/utils/AI/askDocQuestion.cjs.map +0 -1
- package/dist/cjs/utils/auditDictionary/index.cjs.map +0 -1
- package/dist/cjs/utils/auditDictionaryField/index.cjs.map +0 -1
- package/dist/cjs/utils/auditDictionaryMetadata/index.cjs.map +0 -1
- package/dist/esm/utils/AI/askDocQuestion.mjs.map +0 -1
- package/dist/esm/utils/auditDictionary/index.mjs.map +0 -1
- package/dist/esm/utils/auditDictionaryField/index.mjs.map +0 -1
- package/dist/esm/utils/auditDictionaryMetadata/index.mjs.map +0 -1
- package/dist/types/utils/AI/askDocQuestion.d.ts.map +0 -1
- package/dist/types/utils/auditDictionary/index.d.ts.map +0 -1
- package/dist/types/utils/auditDictionaryField/index.d.ts.map +0 -1
- package/dist/types/utils/auditDictionaryMetadata/index.d.ts.map +0 -1
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/CJS_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/JSON_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/JSX_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/MJS_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/PROMPT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/TSX_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/TS_FORMAT.md +0 -0
- /package/dist/cjs/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/PROMPT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/CJS_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/JSON_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/JSX_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/MJS_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/PROMPT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/TSX_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/TS_FORMAT.md +0 -0
- /package/dist/esm/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/PROMPT.md +0 -0
- /package/dist/types/utils/AI/{askDocQuestion.d.ts → askDocQuestion/askDocQuestion.d.ts} +0 -0
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
import { getDictionariesByTags } from "./../services/dictionary.service.mjs";
|
|
2
2
|
import { getTagsByKeys } from "./../services/tag.service.mjs";
|
|
3
3
|
import * as tagService from "./../services/tag.service.mjs";
|
|
4
|
-
import * as askDocQuestionUtil from "./../utils/AI/askDocQuestion.mjs";
|
|
5
|
-
import * as auditContentDeclarationUtil from "./../utils/auditDictionary/index.mjs";
|
|
6
|
-
import * as auditContentDeclarationFieldUtil from "./../utils/auditDictionaryField/index.mjs";
|
|
7
|
-
import * as auditContentDeclarationMetadataUtil from "./../utils/auditDictionaryMetadata/index.mjs";
|
|
4
|
+
import * as askDocQuestionUtil from "./../utils/AI/askDocQuestion/askDocQuestion.mjs";
|
|
5
|
+
import * as auditContentDeclarationUtil from "./../utils/AI/auditDictionary/index.mjs";
|
|
6
|
+
import * as auditContentDeclarationFieldUtil from "./../utils/AI/auditDictionaryField/index.mjs";
|
|
7
|
+
import * as auditContentDeclarationMetadataUtil from "./../utils/AI/auditDictionaryMetadata/index.mjs";
|
|
8
|
+
import * as autocompleteUtil from "./../utils/AI/autocomplete/index.mjs";
|
|
8
9
|
import * as auditTagUtil from "./../utils/auditTag/index.mjs";
|
|
9
10
|
import { ErrorHandler } from "./../utils/errors/index.mjs";
|
|
10
11
|
import { formatResponse } from "./../utils/responseData.mjs";
|
|
11
12
|
const auditContentDeclaration = async (req, res, _next) => {
|
|
12
|
-
const { user, project } = res.locals;
|
|
13
|
+
const { user, project, organization } = res.locals;
|
|
13
14
|
const {
|
|
14
15
|
fileContent,
|
|
15
16
|
filePath,
|
|
16
17
|
openAiApiKey,
|
|
17
18
|
customPrompt,
|
|
18
19
|
model,
|
|
20
|
+
temperature,
|
|
19
21
|
locales,
|
|
20
22
|
defaultLocale,
|
|
21
23
|
tagsKeys
|
|
22
24
|
} = req.body;
|
|
23
25
|
if (!openAiApiKey) {
|
|
24
|
-
if (!user) {
|
|
25
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (!project) {
|
|
29
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
26
|
+
if (!user || !project || !organization) {
|
|
27
|
+
ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
32
30
|
}
|
|
@@ -39,7 +37,8 @@ const auditContentDeclaration = async (req, res, _next) => {
|
|
|
39
37
|
fileContent,
|
|
40
38
|
filePath,
|
|
41
39
|
model,
|
|
42
|
-
|
|
40
|
+
temperature,
|
|
41
|
+
openAiApiKey,
|
|
43
42
|
customPrompt,
|
|
44
43
|
locales,
|
|
45
44
|
defaultLocale,
|
|
@@ -60,23 +59,20 @@ const auditContentDeclaration = async (req, res, _next) => {
|
|
|
60
59
|
}
|
|
61
60
|
};
|
|
62
61
|
const auditContentDeclarationField = async (req, res, _next) => {
|
|
63
|
-
const { user, project } = res.locals;
|
|
62
|
+
const { user, project, organization } = res.locals;
|
|
64
63
|
const {
|
|
65
64
|
fileContent,
|
|
66
65
|
openAiApiKey,
|
|
67
66
|
customPrompt,
|
|
68
67
|
model,
|
|
68
|
+
temperature,
|
|
69
69
|
locales,
|
|
70
70
|
tagsKeys,
|
|
71
71
|
keyPath
|
|
72
72
|
} = req.body;
|
|
73
73
|
if (!openAiApiKey) {
|
|
74
|
-
if (!user) {
|
|
75
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (!project) {
|
|
79
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
74
|
+
if (!user || !project || !organization) {
|
|
75
|
+
ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
|
|
80
76
|
return;
|
|
81
77
|
}
|
|
82
78
|
}
|
|
@@ -88,7 +84,8 @@ const auditContentDeclarationField = async (req, res, _next) => {
|
|
|
88
84
|
const auditResponse = await auditContentDeclarationFieldUtil.auditDictionaryField({
|
|
89
85
|
fileContent,
|
|
90
86
|
model,
|
|
91
|
-
|
|
87
|
+
temperature,
|
|
88
|
+
openAiApiKey,
|
|
92
89
|
customPrompt,
|
|
93
90
|
locales,
|
|
94
91
|
tags,
|
|
@@ -110,18 +107,10 @@ const auditContentDeclarationField = async (req, res, _next) => {
|
|
|
110
107
|
};
|
|
111
108
|
const auditContentDeclarationMetadata = async (req, res, _next) => {
|
|
112
109
|
const { user, organization, project } = res.locals;
|
|
113
|
-
const { fileContent, openAiApiKey, customPrompt, model } = req.body;
|
|
110
|
+
const { fileContent, openAiApiKey, customPrompt, model, temperature } = req.body;
|
|
114
111
|
if (!openAiApiKey) {
|
|
115
|
-
if (!user) {
|
|
116
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (!organization) {
|
|
120
|
-
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (!project) {
|
|
124
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
112
|
+
if (!user || !project || !organization) {
|
|
113
|
+
ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
|
|
125
114
|
return;
|
|
126
115
|
}
|
|
127
116
|
}
|
|
@@ -136,7 +125,8 @@ const auditContentDeclarationMetadata = async (req, res, _next) => {
|
|
|
136
125
|
const auditResponse = await auditContentDeclarationMetadataUtil.auditDictionaryMetadata({
|
|
137
126
|
fileContent,
|
|
138
127
|
model,
|
|
139
|
-
openAiApiKey
|
|
128
|
+
openAiApiKey,
|
|
129
|
+
temperature,
|
|
140
130
|
customPrompt,
|
|
141
131
|
tags
|
|
142
132
|
});
|
|
@@ -155,15 +145,11 @@ const auditContentDeclarationMetadata = async (req, res, _next) => {
|
|
|
155
145
|
}
|
|
156
146
|
};
|
|
157
147
|
const auditTag = async (req, res, _next) => {
|
|
158
|
-
const { user, project } = res.locals;
|
|
159
|
-
const { openAiApiKey, customPrompt, model, tag } = req.body;
|
|
148
|
+
const { user, project, organization } = res.locals;
|
|
149
|
+
const { openAiApiKey, customPrompt, model, temperature, tag } = req.body;
|
|
160
150
|
if (!openAiApiKey) {
|
|
161
|
-
if (!user) {
|
|
162
|
-
ErrorHandler.handleGenericErrorResponse(res, "
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (!project) {
|
|
166
|
-
ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
|
|
151
|
+
if (!user || !project || !organization) {
|
|
152
|
+
ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
|
|
167
153
|
return;
|
|
168
154
|
}
|
|
169
155
|
}
|
|
@@ -174,7 +160,8 @@ const auditTag = async (req, res, _next) => {
|
|
|
174
160
|
}
|
|
175
161
|
const auditResponse = await auditTagUtil.auditTag({
|
|
176
162
|
model,
|
|
177
|
-
openAiApiKey
|
|
163
|
+
openAiApiKey,
|
|
164
|
+
temperature,
|
|
178
165
|
customPrompt,
|
|
179
166
|
dictionaries,
|
|
180
167
|
tag
|
|
@@ -206,11 +193,41 @@ const askDocQuestion = async (req, res) => {
|
|
|
206
193
|
return;
|
|
207
194
|
}
|
|
208
195
|
};
|
|
196
|
+
const autocomplete = async (req, res) => {
|
|
197
|
+
try {
|
|
198
|
+
const { text, model, openAiApiKey, customPrompt, temperature } = req.body;
|
|
199
|
+
const { user, project, organization } = res.locals;
|
|
200
|
+
if (!openAiApiKey) {
|
|
201
|
+
if (!user || !project || !organization) {
|
|
202
|
+
ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const response = await autocompleteUtil.autocomplete({
|
|
207
|
+
text,
|
|
208
|
+
model,
|
|
209
|
+
openAiApiKey,
|
|
210
|
+
temperature,
|
|
211
|
+
customPrompt
|
|
212
|
+
}) ?? {
|
|
213
|
+
autocompletion: "",
|
|
214
|
+
tokenUsed: 0
|
|
215
|
+
};
|
|
216
|
+
const responseData = formatResponse({
|
|
217
|
+
data: response
|
|
218
|
+
});
|
|
219
|
+
res.json(responseData);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
ErrorHandler.handleAppErrorResponse(res, error);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
209
225
|
export {
|
|
210
226
|
askDocQuestion,
|
|
211
227
|
auditContentDeclaration,
|
|
212
228
|
auditContentDeclarationField,
|
|
213
229
|
auditContentDeclarationMetadata,
|
|
214
|
-
auditTag
|
|
230
|
+
auditTag,
|
|
231
|
+
autocomplete
|
|
215
232
|
};
|
|
216
233
|
//# sourceMappingURL=ai.controller.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/controllers/ai.controller.ts"],"sourcesContent":["import { type KeyPath } from '@intlayer/core';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { getDictionariesByTags } from '@services/dictionary.service';\nimport { getTagsByKeys } from '@services/tag.service';\nimport * as tagService from '@services/tag.service';\nimport * as askDocQuestionUtil from '@utils/AI/askDocQuestion';\nimport * as auditContentDeclarationUtil from '@utils/auditDictionary';\nimport * as auditContentDeclarationFieldUtil from '@utils/auditDictionaryField';\nimport * as auditContentDeclarationMetadataUtil from '@utils/auditDictionaryMetadata';\nimport * as auditTagUtil from '@utils/auditTag';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { Locales } from 'intlayer';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\n\nexport type AuditContentDeclarationBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n model?: string;\n tagsKeys?: string[];\n};\nexport type AuditContentDeclarationResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclaration = async (\n req: Request<AuditContentDeclarationBody>,\n res: ResponseWithInformation<AuditContentDeclarationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project } = res.locals;\n const {\n fileContent,\n filePath,\n openAiApiKey,\n customPrompt,\n model,\n locales,\n defaultLocale,\n tagsKeys,\n } = req.body;\n\n if (!openAiApiKey) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await auditContentDeclarationUtil.auditDictionary({\n fileContent,\n filePath,\n model,\n openAiApiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n customPrompt,\n locales,\n defaultLocale,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationFieldBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n locales: Locales[];\n fileContent: string;\n filePath?: string;\n model?: string;\n tagsKeys?: string[];\n keyPath: KeyPath[];\n};\nexport type AuditContentDeclarationFieldResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationField = async (\n req: Request<AuditContentDeclarationFieldBody>,\n res: ResponseWithInformation<AuditContentDeclarationFieldResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project } = res.locals;\n const {\n fileContent,\n openAiApiKey,\n customPrompt,\n model,\n locales,\n tagsKeys,\n keyPath,\n } = req.body;\n\n if (!openAiApiKey) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse =\n await auditContentDeclarationFieldUtil.auditDictionaryField({\n fileContent,\n model,\n openAiApiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n customPrompt,\n locales,\n tags,\n keyPath,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationMetadataBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n fileContent: string;\n model?: string;\n};\nexport type AuditContentDeclarationMetadataResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationMetadata = async (\n req: Request<AuditContentDeclarationMetadataBody>,\n res: ResponseWithInformation<AuditContentDeclarationMetadataResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, project } = res.locals;\n const { fileContent, openAiApiKey, customPrompt, model } = req.body;\n\n if (!openAiApiKey) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'ORGANIZATION_NOT_DEFINED');\n return;\n }\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n }\n\n try {\n const tags: Tag[] = await tagService.findTags(\n {\n organizationId: organization?._id,\n },\n 0,\n 1000\n );\n\n const auditResponse =\n await auditContentDeclarationMetadataUtil.auditDictionaryMetadata({\n fileContent,\n model,\n openAiApiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n customPrompt,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditTagBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n filePath?: string;\n model?: string;\n tag: Tag;\n};\nexport type AuditTagResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditTag = async (\n req: Request<undefined, undefined, AuditTagBody>,\n res: ResponseWithInformation<AuditTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project } = res.locals;\n const { openAiApiKey, customPrompt, model, tag } = req.body;\n\n if (!openAiApiKey) {\n if (!user) {\n ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED');\n return;\n }\n if (!project) {\n ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED');\n return;\n }\n }\n\n try {\n let dictionaries: Dictionary[] = [];\n if (project?.organizationId) {\n dictionaries = await getDictionariesByTags([tag.key], project._id);\n }\n\n const auditResponse = await auditTagUtil.auditTag({\n model,\n openAiApiKey: openAiApiKey ?? process.env.OPENAI_API_KEY!,\n customPrompt,\n dictionaries,\n tag,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AskDocQuestionBody = {\n messages: askDocQuestionUtil.ChatCompletionRequestMessage[];\n};\nexport type AskDocQuestionResult =\n ResponseData<askDocQuestionUtil.AskDocQuestionResult>;\n\nexport const askDocQuestion = async (\n req: Request<undefined, undefined, AskDocQuestionBody>,\n res: ResponseWithInformation<AskDocQuestionResult>\n) => {\n const { messages } = req.body;\n try {\n const response = await askDocQuestionUtil.askDocQuestion(messages);\n\n const responseData =\n formatResponse<askDocQuestionUtil.AskDocQuestionResult>({\n data: response,\n });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/ai.controller.ts"],"sourcesContent":["import { type KeyPath } from '@intlayer/core';\nimport type { ResponseWithInformation } from '@middlewares/sessionAuth.middleware';\nimport { getDictionariesByTags } from '@services/dictionary.service';\nimport { getTagsByKeys } from '@services/tag.service';\nimport * as tagService from '@services/tag.service';\nimport * as askDocQuestionUtil from '@utils/AI/askDocQuestion/askDocQuestion';\nimport * as auditContentDeclarationUtil from '@utils/AI/auditDictionary';\nimport * as auditContentDeclarationFieldUtil from '@utils/AI/auditDictionaryField';\nimport * as auditContentDeclarationMetadataUtil from '@utils/AI/auditDictionaryMetadata';\nimport * as autocompleteUtil from '@utils/AI/autocomplete';\nimport * as auditTagUtil from '@utils/auditTag';\nimport { type AppError, ErrorHandler } from '@utils/errors';\nimport { formatResponse, type ResponseData } from '@utils/responseData';\nimport type { NextFunction, Request } from 'express';\nimport type { Locales } from 'intlayer';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\n\nexport type AuditContentDeclarationBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n model?: string;\n temperature?: number;\n tagsKeys?: string[];\n};\nexport type AuditContentDeclarationResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclaration = async (\n req: Request<AuditContentDeclarationBody>,\n res: ResponseWithInformation<AuditContentDeclarationResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, organization } = res.locals;\n const {\n fileContent,\n filePath,\n openAiApiKey,\n customPrompt,\n model,\n temperature,\n locales,\n defaultLocale,\n tagsKeys,\n } = req.body;\n\n if (!openAiApiKey) {\n if (!user || !project || !organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse = await auditContentDeclarationUtil.auditDictionary({\n fileContent,\n filePath,\n model,\n temperature,\n openAiApiKey,\n customPrompt,\n locales,\n defaultLocale,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationFieldBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n locales: Locales[];\n fileContent: string;\n filePath?: string;\n model?: string;\n temperature?: number;\n tagsKeys?: string[];\n keyPath: KeyPath[];\n};\nexport type AuditContentDeclarationFieldResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationField = async (\n req: Request<AuditContentDeclarationFieldBody>,\n res: ResponseWithInformation<AuditContentDeclarationFieldResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, organization } = res.locals;\n const {\n fileContent,\n openAiApiKey,\n customPrompt,\n model,\n temperature,\n locales,\n tagsKeys,\n keyPath,\n } = req.body;\n\n if (!openAiApiKey) {\n if (!user || !project || !organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n }\n\n try {\n let tags: Tag[] = [];\n\n if (project?.organizationId) {\n tags = await getTagsByKeys(tagsKeys, project.organizationId);\n }\n\n const auditResponse =\n await auditContentDeclarationFieldUtil.auditDictionaryField({\n fileContent,\n model,\n temperature,\n openAiApiKey,\n customPrompt,\n locales,\n tags,\n keyPath,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditContentDeclarationMetadataBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n fileContent: string;\n model?: string;\n temperature?: number;\n};\nexport type AuditContentDeclarationMetadataResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditContentDeclarationMetadata = async (\n req: Request<AuditContentDeclarationMetadataBody>,\n res: ResponseWithInformation<AuditContentDeclarationMetadataResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, organization, project } = res.locals;\n const { fileContent, openAiApiKey, customPrompt, model, temperature } =\n req.body;\n\n if (!openAiApiKey) {\n if (!user || !project || !organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n }\n\n try {\n const tags: Tag[] = await tagService.findTags(\n {\n organizationId: organization?._id,\n },\n 0,\n 1000\n );\n\n const auditResponse =\n await auditContentDeclarationMetadataUtil.auditDictionaryMetadata({\n fileContent,\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n tags,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AuditTagBody = {\n openAiApiKey?: string;\n customPrompt?: string;\n filePath?: string;\n model?: string;\n temperature?: number;\n tag: Tag;\n};\nexport type AuditTagResult =\n ResponseData<auditContentDeclarationUtil.AuditFileResultData>;\n\n/**\n * Retrieves a list of dictionaries based on filters and pagination.\n */\nexport const auditTag = async (\n req: Request<undefined, undefined, AuditTagBody>,\n res: ResponseWithInformation<AuditTagResult>,\n _next: NextFunction\n): Promise<void> => {\n const { user, project, organization } = res.locals;\n const { openAiApiKey, customPrompt, model, temperature, tag } = req.body;\n\n if (!openAiApiKey) {\n if (!user || !project || !organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n }\n\n try {\n let dictionaries: Dictionary[] = [];\n if (project?.organizationId) {\n dictionaries = await getDictionariesByTags([tag.key], project._id);\n }\n\n const auditResponse = await auditTagUtil.auditTag({\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n dictionaries,\n tag,\n });\n\n if (!auditResponse) {\n ErrorHandler.handleGenericErrorResponse(res, 'AUDIT_FAILED');\n return;\n }\n\n const responseData =\n formatResponse<auditContentDeclarationUtil.AuditFileResultData>({\n data: auditResponse,\n });\n\n res.json(responseData);\n return;\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AskDocQuestionBody = {\n messages: askDocQuestionUtil.ChatCompletionRequestMessage[];\n};\nexport type AskDocQuestionResult =\n ResponseData<askDocQuestionUtil.AskDocQuestionResult>;\n\nexport const askDocQuestion = async (\n req: Request<undefined, undefined, AskDocQuestionBody>,\n res: ResponseWithInformation<AskDocQuestionResult>\n) => {\n const { messages } = req.body;\n try {\n const response = await askDocQuestionUtil.askDocQuestion(messages);\n\n const responseData =\n formatResponse<askDocQuestionUtil.AskDocQuestionResult>({\n data: response,\n });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n\nexport type AutocompleteBody = {\n text: string;\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n customPrompt?: string;\n};\n\nexport type AutocompleteResponse = ResponseData<{\n autocompletion: string;\n}>;\n\nexport const autocomplete = async (\n req: Request<undefined, undefined, AutocompleteBody>,\n res: ResponseWithInformation<AutocompleteResponse>\n) => {\n try {\n const { text, model, openAiApiKey, customPrompt, temperature } = req.body;\n const { user, project, organization } = res.locals;\n\n if (!openAiApiKey) {\n if (!user || !project || !organization) {\n ErrorHandler.handleGenericErrorResponse(res, 'AI_ACCESS_DENIED');\n return;\n }\n }\n\n const response = (await autocompleteUtil.autocomplete({\n text,\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n })) ?? {\n autocompletion: '',\n tokenUsed: 0,\n };\n\n const responseData =\n formatResponse<autocompleteUtil.AutocompleteFileResultData>({\n data: response,\n });\n\n res.json(responseData);\n } catch (error) {\n ErrorHandler.handleAppErrorResponse(res, error as AppError);\n return;\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { logger } from "./../logger/index.mjs";
|
|
2
2
|
import * as dictionaryService from "./../services/dictionary.service.mjs";
|
|
3
|
+
import { ensureMongoDocumentToObject } from "./../utils/ensureMongoDocumentToObject.mjs";
|
|
3
4
|
import { ErrorHandler } from "./../utils/errors/index.mjs";
|
|
4
5
|
import {
|
|
5
6
|
getDictionaryFiltersAndPagination
|
|
@@ -34,7 +35,7 @@ const getDictionaries = async (req, res, _next) => {
|
|
|
34
35
|
);
|
|
35
36
|
const totalItems = await dictionaryService.countDictionaries(filters);
|
|
36
37
|
const dictionariesAPI = dictionaries.map(
|
|
37
|
-
(el) => mapDictionaryToAPI(el, project._id
|
|
38
|
+
(el) => mapDictionaryToAPI(el, project._id)
|
|
38
39
|
);
|
|
39
40
|
const responseData = formatPaginatedResponse({
|
|
40
41
|
data: dictionariesAPI,
|
|
@@ -128,7 +129,7 @@ const addDictionary = async (req, res, _next) => {
|
|
|
128
129
|
ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
|
|
129
130
|
return;
|
|
130
131
|
}
|
|
131
|
-
if (!dictionaryData.projectIds
|
|
132
|
+
if (!dictionaryData.projectIds?.includes(String(project._id))) {
|
|
132
133
|
ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
|
|
133
134
|
return;
|
|
134
135
|
}
|
|
@@ -220,7 +221,6 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
220
221
|
const updatedDictionariesResult = [];
|
|
221
222
|
const errorResult = [];
|
|
222
223
|
for (const dictionaryDataEl of newDictionaries) {
|
|
223
|
-
const publishedVersion = dictionaryDataEl.version ? dictionaryDataEl.version === "-1" ? null : dictionaryDataEl.version : null;
|
|
224
224
|
const dictionary = {
|
|
225
225
|
title: dictionaryDataEl.title,
|
|
226
226
|
description: dictionaryDataEl.description,
|
|
@@ -232,8 +232,7 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
232
232
|
filePath: {
|
|
233
233
|
[String(project._id)]: dictionaryDataEl.filePath ?? ""
|
|
234
234
|
},
|
|
235
|
-
key: dictionaryDataEl.key
|
|
236
|
-
publishedVersion
|
|
235
|
+
key: dictionaryDataEl.key
|
|
237
236
|
};
|
|
238
237
|
try {
|
|
239
238
|
const newDictionary = await dictionaryService.createDictionary(dictionary);
|
|
@@ -254,10 +253,9 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
254
253
|
const existingDictionaryDB = existingDictionariesDB.find(
|
|
255
254
|
(dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key
|
|
256
255
|
);
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
);
|
|
260
|
-
const lastContent = existingContentArray[existingContentArray.length - 1].content;
|
|
256
|
+
const versionList = [...existingDictionaryDB.content.keys() ?? []];
|
|
257
|
+
const lastVersion = versionList[versionList.length - 1];
|
|
258
|
+
const lastContent = existingDictionaryDB.content.get(lastVersion)?.content ?? null;
|
|
261
259
|
const isSameContent = JSON.stringify(lastContent) === JSON.stringify(dictionaryDataEl.content);
|
|
262
260
|
let newContent = existingDictionaryDB.content;
|
|
263
261
|
if (!isSameContent) {
|
|
@@ -269,9 +267,8 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
269
267
|
}
|
|
270
268
|
};
|
|
271
269
|
}
|
|
272
|
-
const publishedVersion = dictionaryDataEl.version ? dictionaryDataEl.version === "-1" ? null : dictionaryDataEl.version : null;
|
|
273
270
|
const dictionary = {
|
|
274
|
-
...existingDictionaryDB,
|
|
271
|
+
...ensureMongoDocumentToObject(existingDictionaryDB),
|
|
275
272
|
...dictionaryDataEl,
|
|
276
273
|
content: newContent,
|
|
277
274
|
projectIds: [String(project._id)],
|
|
@@ -279,7 +276,6 @@ const pushDictionaries = async (req, res, _next) => {
|
|
|
279
276
|
filePath: {
|
|
280
277
|
[String(project._id)]: dictionaryDataEl.filePath ?? ""
|
|
281
278
|
},
|
|
282
|
-
publishedVersion,
|
|
283
279
|
key: dictionaryDataEl.key
|
|
284
280
|
};
|
|
285
281
|
try {
|
|
@@ -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 { 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, el.publishedVersion ?? undefined)\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 publishedVersion = dictionaryDataEl.version\n ? dictionaryDataEl.version === '-1'\n ? null\n : dictionaryDataEl.version\n : null;\n\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 publishedVersion,\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 existingContentArray = Object.values(\n existingDictionaryDB.content\n );\n\n const lastContent =\n existingContentArray[existingContentArray.length - 1].content;\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 publishedVersion = dictionaryDataEl.version\n ? dictionaryDataEl.version === '-1'\n ? null\n : dictionaryDataEl.version\n : null;\n\n const dictionary: DictionaryData = {\n ...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 publishedVersion,\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":"AAIA,SAAS,cAAc;AAEvB,YAAY,uBAAuB;AACnC,SAAwB,oBAAoB;AAC5C;AAAA,EAEE;AAAA,OACK;AAEP,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EAGA;AAAA,OACK;AAEP,SAAS,SAAS;AAClB,YAAY,mBAAmB;AAgBxB,MAAM,kBAAkB,OAC7B,KACA,KACA,UACkB;AAClB,QAAM,EAAE,MAAM,SAAS,iBAAiB,IAAI,IAAI;AAChD,QAAM,EAAE,SAAS,UAAU,MAAM,MAAM,iBAAiB,IACtD,kCAAkC,GAAG;AAEvC,MAAI,CAAC,SAAS;AACZ,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,iBAAa,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,OACxC,mBAAmB,IAAI,QAAQ,KAAK,GAAG,oBAAoB,MAAS;AAAA,IACtE;AAEA,UAAM,eAAe,wBAAuC;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,iBAAa,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,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,iBAAa,2BAA2B,KAAK,4BAA4B;AACzE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,mBAAmB,MAAM,kBAAkB;AAAA,MAC/C,QAAQ;AAAA,IACV;AAEA,UAAM,eAAe,eAAyB;AAAA,MAC5C,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,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,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AACA,MAAI,CAAC,MAAM;AACT,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM;AAC3B,iBAAa,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,mBAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,YAAY,mBAAmB,YAAY,QAAQ,KAAK,OAAO;AAErE,UAAM,eAAe,eAA8B;AAAA,MACjD,MAAM;AAAA,IACR,CAAC;AAED,QAAI,KAAK,YAAY;AACrB;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,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,iBAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,WAAW,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC5D,iBAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,iBAAa,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,YAAY,mBAAmB,eAAe,QAAQ,GAAG;AAE/D,UAAM,eAAe,eAA8B;AAAA,MACjD,SAAS,EAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,aAAa,EAAE;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,mBAAmB,eAAe,QAAQ,GAAG;AAAA,QACzD,QAAQ;AAAA,MACV;AAAA,IACF,CAAC;AACD;AAAA,EACF,SAAS,OAAO;AACd,iBAAa,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,iBAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF,WAAW,CAAC,gBAAgB;AAC1B,iBAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,MAAM;AACT,iBAAa,2BAA2B,KAAK,kBAAkB;AAC/D;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,iBAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,iBAAa,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,mBAAmB,iBAAiB,UACtC,iBAAiB,YAAY,OAC3B,OACA,iBAAiB,UACnB;AAEJ,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,QACtB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,gBACJ,MAAM,kBAAkB,iBAAiB,UAAU;AACrD,8BAAsB;AAAA,UACpB,mBAAmB,eAAe,QAAQ,GAAG;AAAA,QAC/C;AAAA,MACF,SAAS,OAAO;AACd,qBAAa,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,uBAAuB,OAAO;AAAA,UAClC,qBAAqB;AAAA,QACvB;AAEA,cAAM,cACJ,qBAAqB,qBAAqB,SAAS,CAAC,EAAE;AAExD,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,uBAAa;AAAA,YACX,GAAG;AAAA,YACH,CAAC,iBAAiB,GAAG;AAAA,cACnB,SAAS,iBAAiB;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AAEA,cAAM,mBAAmB,iBAAiB,UACtC,iBAAiB,YAAY,OAC3B,OACA,iBAAiB,UACnB;AAEJ,cAAM,aAA6B;AAAA,UACjC,GAAG;AAAA,UACH,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;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,YACxB,mBAAmB,mBAAmB,QAAQ,GAAG;AAAA,UACnD;AAAA,QACF,SAAS,OAAO;AACd,uBAAa,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,eAAe,eAA2C;AAAA,MAC9D,SAAS,EAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,aAAa,EAAE;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,iBAAa,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,iBAAa,2BAA2B,KAAK,2BAA2B;AACxE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,eAAe,YAAY,SAAS,OAAO,QAAQ,GAAG,CAAC,GAAG;AAC7D,iBAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI,OAAO,iBAAiB,aAAa;AACvC,iBAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,iBAAa,2BAA2B,KAAK,6BAA6B;AAC1E;AAAA,EACF;AAEA,MAAI;AACF,UAAM,oBAAoB,MAAM,kBAAkB;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAY,mBAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,eAAe,eAA8B;AAAA,MACjD,SAAS,EAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,aAAa,EAAE;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,iBAAa,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,iBAAa,2BAA2B,KAAK,yBAAyB;AACtE;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,iBAAa,2BAA2B,KAAK,qBAAqB;AAClE;AAAA,EACF;AAEA,MAAI,CAAC,kBAAkB,OAAO;AAC5B,iBAAa,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,mBAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,oBACJ,MAAM,kBAAkB,qBAAqB,YAAY;AAE3D,QAAI,CAAC,mBAAmB;AACtB,mBAAa,2BAA2B,KAAK,wBAAwB;AAAA,QACnE;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,WAAO,KAAK,uBAAuB,OAAO,kBAAkB,GAAG,CAAC,EAAE;AAElE,UAAM,YAAY,mBAAmB,mBAAmB,QAAQ,GAAG;AAEnE,UAAM,eAAe,eAA8B;AAAA,MACjD,SAAS,EAAE;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN,CAAC;AAAA,MACD,aAAa,EAAE;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,iBAAa,uBAAuB,KAAK,KAAiB;AAC1D;AAAA,EACF;AACF;","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/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,6 +1,7 @@
|
|
|
1
1
|
import { logger } from "./../logger/index.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { getSessionAuthRoutes } from "./../routes/sessionAuth.routes.mjs";
|
|
3
3
|
import { sendEmail } from "./../services/email.service.mjs";
|
|
4
|
+
import * as projectService from "./../services/project.service.mjs";
|
|
4
5
|
import * as sessionAuthService from "./../services/sessionAuth.service.mjs";
|
|
5
6
|
import * as userService from "./../services/user.service.mjs";
|
|
6
7
|
import { ErrorHandler } from "./../utils/errors/index.mjs";
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
formatResponse
|
|
14
15
|
} from "./../utils/responseData.mjs";
|
|
15
16
|
import { t } from "express-intlayer";
|
|
17
|
+
import { Stripe } from "stripe";
|
|
16
18
|
import * as organizationService from "./../services/organization.service.mjs";
|
|
17
19
|
const getOrganizations = async (req, res, _next) => {
|
|
18
20
|
const { user, organizationRights } = res.locals;
|
|
@@ -219,7 +221,7 @@ const addOrganizationMember = async (req, res, _next) => {
|
|
|
219
221
|
invitedByUsername: user.name,
|
|
220
222
|
invitedByEmail: user.email,
|
|
221
223
|
organizationName: organization.name,
|
|
222
|
-
inviteLink:
|
|
224
|
+
inviteLink: getSessionAuthRoutes().loginEmailPassword.url,
|
|
223
225
|
inviteFromIp: req.ip ?? "",
|
|
224
226
|
inviteFromLocation: req.hostname
|
|
225
227
|
});
|
|
@@ -330,6 +332,7 @@ const updateOrganizationMembers = async (req, res, _next) => {
|
|
|
330
332
|
}
|
|
331
333
|
};
|
|
332
334
|
const deleteOrganization = async (_req, res, _next) => {
|
|
335
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
|
|
333
336
|
const { isOrganizationAdmin, organization, organizationRights } = res.locals;
|
|
334
337
|
if (!organization) {
|
|
335
338
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
|
|
@@ -349,7 +352,19 @@ const deleteOrganization = async (_req, res, _next) => {
|
|
|
349
352
|
);
|
|
350
353
|
return;
|
|
351
354
|
}
|
|
355
|
+
const projects = await projectService.findProjects({
|
|
356
|
+
organizationId: organization._id
|
|
357
|
+
});
|
|
358
|
+
if (projects.length > 0) {
|
|
359
|
+
ErrorHandler.handleGenericErrorResponse(res, "PROJECTS_EXIST", {
|
|
360
|
+
organizationId: organization._id
|
|
361
|
+
});
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
352
364
|
try {
|
|
365
|
+
if (organization.plan?.subscriptionId) {
|
|
366
|
+
await stripe.subscriptions.cancel(organization.plan.subscriptionId);
|
|
367
|
+
}
|
|
353
368
|
const deletedOrganization = await organizationService.deleteOrganizationById(organization._id);
|
|
354
369
|
if (!deletedOrganization) {
|
|
355
370
|
ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_FOUND", {
|
|
@@ -371,6 +386,7 @@ const deleteOrganization = async (_req, res, _next) => {
|
|
|
371
386
|
}),
|
|
372
387
|
data: deletedOrganization
|
|
373
388
|
});
|
|
389
|
+
sessionAuthService.clearOrganizationAuth(res);
|
|
374
390
|
res.json(responseData);
|
|
375
391
|
return;
|
|
376
392
|
} catch (error) {
|